{
  "id": "feature-store",
  "title": "Redis feature store",
  "url": "https://redis.io/docs/latest/develop/use-cases/feature-store/",
  "summary": "Serve pre-computed ML features on the request path under tight latency budgets, with batch and streaming features kept fresh in the same store.",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc"
  ],
  "last_updated": "2026-06-04T14:49:57+01:00",
  "children": [
    {
      "id": "redis-py",
      "summary": "Build a Redis-backed online feature store in Python with redis-py",
      "title": "Redis feature store with redis-py",
      "url": "https://redis.io/docs/latest/develop/use-cases/feature-store/redis-py/"
    },
    {
      "id": "nodejs",
      "summary": "Build a Redis-backed online feature store in Node.js with node-redis",
      "title": "Redis feature store with node-redis",
      "url": "https://redis.io/docs/latest/develop/use-cases/feature-store/nodejs/"
    },
    {
      "id": "go",
      "summary": "Build a Redis-backed online feature store in Go with go-redis",
      "title": "Redis feature store with go-redis",
      "url": "https://redis.io/docs/latest/develop/use-cases/feature-store/go/"
    },
    {
      "id": "java-jedis",
      "summary": "Build a Redis-backed online feature store in Java with Jedis",
      "title": "Redis feature store with Jedis",
      "url": "https://redis.io/docs/latest/develop/use-cases/feature-store/java-jedis/"
    },
    {
      "id": "java-lettuce",
      "summary": "Build a Redis-backed online feature store in Java with Lettuce",
      "title": "Redis feature store with Lettuce",
      "url": "https://redis.io/docs/latest/develop/use-cases/feature-store/java-lettuce/"
    },
    {
      "id": "rust",
      "summary": "Build a Redis-backed online feature store in Rust with redis-rs",
      "title": "Redis feature store with redis-rs",
      "url": "https://redis.io/docs/latest/develop/use-cases/feature-store/rust/"
    },
    {
      "id": "dotnet",
      "summary": "Build a Redis-backed online feature store in .NET with StackExchange.Redis",
      "title": "Redis feature store with StackExchange.Redis",
      "url": "https://redis.io/docs/latest/develop/use-cases/feature-store/dotnet/"
    },
    {
      "id": "ruby",
      "summary": "Build a Redis-backed online feature store in Ruby with redis-rb",
      "title": "Redis feature store with redis-rb",
      "url": "https://redis.io/docs/latest/develop/use-cases/feature-store/ruby/"
    },
    {
      "id": "php",
      "summary": "Build a Redis-backed online feature store in PHP with Predis",
      "title": "Redis feature store with Predis",
      "url": "https://redis.io/docs/latest/develop/use-cases/feature-store/php/"
    }
  ],
  "page_type": "content",
  "content_hash": "86d7841ad973133d511d0b29ea4fc8212891c1975ffa80fa23ee4f8d20f2ac88",
  "sections": [
    {
      "id": "when-to-use-redis-as-a-feature-store",
      "title": "When to use Redis as a feature store",
      "role": "overview",
      "text": "Use Redis as the online layer of a feature store when production models — fraud\nscoring, recommendations, dynamic pricing — need dozens of pre-computed features\nper prediction on every request, with sub-millisecond reads, mixed batch-and-streaming\nfreshness, and high write throughput from concurrent ingestion pipelines."
    },
    {
      "id": "why-the-problem-is-hard",
      "title": "Why the problem is hard",
      "role": "content",
      "text": "An online feature store has to serve dozens of features per inference call inside\na request budget measured in milliseconds, while batch jobs and streaming\npipelines update those same features at very different cadences. Some of the\nobvious workarounds have real drawbacks:\n\n-   **Querying the offline warehouse directly** adds hundreds of milliseconds per\n    inference call, which makes real-time serving impossible.\n-   **A bespoke cache in front of the warehouse** solves latency but introduces\n    *training-serving skew*: the features served at inference drift from what the\n    model trained on, silently degrading accuracy whenever a transform changes\n    on one side and not the other.\n-   **Disk-backed online stores** hit a throughput wall when every user action\n    has to update a dozen features simultaneously across millions of entities —\n    the I/O mix of small concurrent writes is exactly what they are slowest at.\n-   **Single-TTL stores** can't handle mixed staleness: batch features refreshed\n    nightly coexist with streaming features updated every few seconds, and a\n    single per-key expiry can't express both. Worse, a failed ingestion\n    pipeline must *expire* its features rather than serve stale values silently.\n\nA workable online feature store needs sub-millisecond reads at request rate,\nhigh concurrent write throughput from mixed batch and streaming ingestion,\nindependent freshness controls per feature, and self-cleaning behavior when an\nupstream pipeline fails — without standing up a dedicated piece of\ninfrastructure beside the rest of the model-serving stack."
    },
    {
      "id": "what-you-can-expect-from-a-redis-solution",
      "title": "What you can expect from a Redis solution",
      "role": "content",
      "text": "You can:\n\n-   Serve feature vectors to inference endpoints under 1 ms P99\n    (99% of requests have a latency of 1 ms or less) at millions of\n    reads per second from a single shard, and scale horizontally beyond that\n    with Redis Cluster.\n-   Run batch and streaming ingestion concurrently against the same entities\n    without locking or version columns — Redis is single-threaded per shard, so\n    individual field writes are atomic by construction.\n-   Apply *different* freshness guarantees to individual features within the same\n    entity hash: seconds for real-time signals, hours for batch aggregates, with\n    per-field TTL via [`HEXPIRE`](https://redis.io/docs/latest/commands/hexpire).\n-   Let stale streaming features self-expire when their ingestion pipeline\n    fails, so models receive missing features rather than silently outdated ones.\n-   Retrieve features for hundreds of entities in a single round trip for batch\n    scoring, using pipelined [`HMGET`](https://redis.io/docs/latest/commands/hmget).\n-   Plug into [Redis Feature Form](https://redis.io/docs/latest/develop/ai/featureform) —\n    Redis's own materialize / serve layer — or\n    [Feast](https://docs.feast.dev/) with a connection-string change, so no\n    bespoke serving code is required.\n-   Co-locate the online feature store on the same Redis instance already\n    handling cache, sessions, or rate limiting in the stack — no additional\n    infrastructure."
    },
    {
      "id": "how-redis-supports-the-solution",
      "title": "How Redis supports the solution",
      "role": "content",
      "text": "In practice, each entity (a user, an account, an item) is a single\n[Hash](https://redis.io/docs/latest/develop/data-types/hashes) at a deterministic key like\n`fs:user:{id}`. The hash holds every feature for that entity as one field per\nfeature — batch-materialized aggregates alongside streaming-updated signals —\nso one [`HMGET`](https://redis.io/docs/latest/commands/hmget) call returns whatever subset\nthe model needs in one round trip. A key-level\n[`EXPIRE`](https://redis.io/docs/latest/commands/expire) aligns with the batch\nmaterialization cycle so a whole entity self-cleans when its pipeline stops\nrefreshing it, and per-field [`HEXPIRE`](https://redis.io/docs/latest/commands/hexpire)\nlets each streaming feature carry its own shorter expiry independent of the\nrest of the hash.\n\nRedis provides the following features that make it a good fit for an online\nfeature store:\n\n-   [Hashes](https://redis.io/docs/latest/develop/data-types/hashes) group every feature\n    for an entity under one key, so retrieval reads everything the model needs\n    in a single network round trip with [`HMGET`](https://redis.io/docs/latest/commands/hmget),\n    and small hashes use *listpack* encoding for compact in-memory representation.\n-   [`HSET`](https://redis.io/docs/latest/commands/hset) writes any subset of fields\n    atomically, so batch and streaming pipelines can update overlapping or\n    disjoint features on the same entity concurrently without locks or version\n    columns.\n-   [`HEXPIRE`](https://redis.io/docs/latest/commands/hexpire) and\n    [`HTTL`](https://redis.io/docs/latest/commands/httl) (Redis 7.4+) give per-field TTLs,\n    so streaming features (5-minute freshness) and batch features (24-hour\n    freshness) can live in the same hash with independent expiry — the\n    *mixed-staleness* problem becomes a one-line server-side guarantee.\n-   [`EXPIRE`](https://redis.io/docs/latest/commands/expire) at the key level lets an\n    entity disappear entirely if its batch refresher fails, so inference sees\n    a missing entity (which the model handler can detect and fall back on)\n    rather than silently outdated values.\n-   [Pipelining](https://redis.io/docs/latest/develop/using-commands/pipelining) bundles\n    [`HMGET`](https://redis.io/docs/latest/commands/hmget) calls for many entities into\n    one round trip, which is the right primitive for batch scoring where the\n    model needs features for hundreds of entities at once.\n-   Sub-millisecond reads and writes from memory keep the feature store off the\n    critical path of inference, so the model-server's request budget is spent\n    on the model rather than on feature retrieval."
    },
    {
      "id": "ecosystem",
      "title": "Ecosystem",
      "role": "content",
      "text": "The following libraries and platforms use Redis as their online feature store:\n\n-   **[Redis Feature Form](https://redis.io/docs/latest/develop/ai/featureform)** is\n    Redis's own feature-engineering platform. It defines features, labels, and\n    feature views in a Python definitions file, materializes them through a\n    [registered provider](https://redis.io/docs/latest/develop/ai/featureform/providers),\n    and [serves](https://redis.io/docs/latest/develop/ai/featureform/features-and-labels)\n    them from Redis as the low-latency online store. See the\n    [quickstart](https://redis.io/docs/latest/develop/ai/featureform/quickstart) for an\n    end-to-end walkthrough.\n-   **Python**: [Feast](https://docs.feast.dev/reference/online-stores/redis)\n    ships Redis as a first-class online store provider — point a Feast\n    `online_store` block at a Redis connection string and the\n    `RedisOnlineStore` backend handles materialization and serving.\n-   **Compute**: [Apache Spark](https://spark.apache.org/) batch jobs run the\n    nightly materialization, writing into Redis via the Redis Feature Form /\n    Feast materialize commands or directly with the\n    [`spark-redis`](https://github.com/RedisLabs/spark-redis) connector.\n-   **Streaming**: [Apache Flink](https://flink.apache.org/) or\n    [Kafka Streams](https://kafka.apache.org/documentation/streams/) compute the\n    real-time features and `HSET` them into Redis with per-field\n    [`HEXPIRE`](https://redis.io/docs/latest/commands/hexpire) so each streaming signal\n    carries its own freshness window.\n-   **Infrastructure**: [Kubernetes](https://kubernetes.io/) co-locates Redis\n    pods alongside the model-serving containers, with horizontal-pod autoscaling\n    on the read replicas to track inference load;\n    [Active-Active geo-distribution](https://redis.io/docs/latest/operate/rs/databases/active-active)\n    on Redis Enterprise / Redis Cloud replicates the online store across\n    regions for low-latency reads close to each inference cluster."
    },
    {
      "id": "code-examples-to-build-your-own-redis-feature-store",
      "title": "Code examples to build your own Redis feature store",
      "role": "example",
      "text": "The following guides show how to build a small Redis-backed online feature\nstore for a fraud-scoring model. Each guide includes a runnable interactive\ndemo that lets you bulk-load batch features, run a streaming worker that\nupdates real-time features with per-field TTL, retrieve any subset of features\nfor a single user under 1 ms, and pipeline batch reads across a hundred users.\n\n* [redis-py (Python)](https://redis.io/docs/latest/develop/use-cases/feature-store/redis-py)\n* [node-redis (Node.js)](https://redis.io/docs/latest/develop/use-cases/feature-store/nodejs)\n* [go-redis (Go)](https://redis.io/docs/latest/develop/use-cases/feature-store/go)\n* [Jedis (Java)](https://redis.io/docs/latest/develop/use-cases/feature-store/java-jedis)\n* [Lettuce (Java)](https://redis.io/docs/latest/develop/use-cases/feature-store/java-lettuce)\n* [redis-rs (Rust)](https://redis.io/docs/latest/develop/use-cases/feature-store/rust)\n* [StackExchange.Redis (C#)](https://redis.io/docs/latest/develop/use-cases/feature-store/dotnet)\n* [Predis (PHP)](https://redis.io/docs/latest/develop/use-cases/feature-store/php)\n* [redis-rb (Ruby)](https://redis.io/docs/latest/develop/use-cases/feature-store/ruby)"
    }
  ],
  "examples": []
}
