{
  "id": "recommendation-engine",
  "title": "Redis recommendation engine",
  "url": "https://redis.io/docs/latest/develop/use-cases/recommendation-engine/",
  "summary": "Serve personalized recommendations under tight latency budgets by combining vector similarity with structured filters in a single Redis call.",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc"
  ],
  "last_updated": "2026-05-26T09:29:27-05:00",
  "children": [
    {
      "id": "redis-py",
      "summary": "Build a Redis-backed recommendation engine in Python with redis-py and sentence-transformers",
      "title": "Redis recommendation engine with redis-py",
      "url": "https://redis.io/docs/latest/develop/use-cases/recommendation-engine/redis-py/"
    },
    {
      "id": "nodejs",
      "summary": "Build a Redis-backed recommendation engine in Node.js with node-redis and @xenova/transformers",
      "title": "Redis recommendation engine with node-redis",
      "url": "https://redis.io/docs/latest/develop/use-cases/recommendation-engine/nodejs/"
    },
    {
      "id": "go",
      "summary": "Build a Redis-backed recommendation engine in Go with go-redis and Hugot",
      "title": "Redis recommendation engine with go-redis",
      "url": "https://redis.io/docs/latest/develop/use-cases/recommendation-engine/go/"
    },
    {
      "id": "rust",
      "summary": "Build a Redis-backed recommendation engine in Rust with redis-rs and fastembed",
      "title": "Redis recommendation engine with redis-rs",
      "url": "https://redis.io/docs/latest/develop/use-cases/recommendation-engine/rust/"
    },
    {
      "id": "dotnet",
      "summary": "Build a Redis-backed recommendation engine in C# with NRedisStack and SmartComponents.LocalEmbeddings",
      "title": "Redis recommendation engine with NRedisStack",
      "url": "https://redis.io/docs/latest/develop/use-cases/recommendation-engine/dotnet/"
    },
    {
      "id": "java-jedis",
      "summary": "Build a Redis-backed recommendation engine in Java with Jedis and DJL (HuggingFace tokenizers + ONNX Runtime)",
      "title": "Redis recommendation engine with Jedis",
      "url": "https://redis.io/docs/latest/develop/use-cases/recommendation-engine/java-jedis/"
    },
    {
      "id": "java-lettuce",
      "summary": "Build a Redis-backed recommendation engine in Java with Lettuce and DJL (HuggingFace tokenizers + ONNX Runtime)",
      "title": "Redis recommendation engine with Lettuce",
      "url": "https://redis.io/docs/latest/develop/use-cases/recommendation-engine/java-lettuce/"
    },
    {
      "id": "php",
      "summary": "Build a Redis-backed recommendation engine in PHP with Predis and TransformersPHP",
      "title": "Redis recommendation engine with Predis",
      "url": "https://redis.io/docs/latest/develop/use-cases/recommendation-engine/php/"
    },
    {
      "id": "ruby",
      "summary": "Build a Redis-backed recommendation engine in Ruby with redis-rb and informers",
      "title": "Redis recommendation engine with redis-rb",
      "url": "https://redis.io/docs/latest/develop/use-cases/recommendation-engine/ruby/"
    }
  ],
  "page_type": "content",
  "content_hash": "2a3f00d4bd648a4bfd394cba49c792bedfeb681d18c219a805b10beab5a8362a",
  "sections": [
    {
      "id": "when-to-use-redis-as-a-recommendation-engine",
      "title": "When to use Redis as a recommendation engine",
      "role": "overview",
      "text": "Use Redis as the serving layer for a recommendation engine when you need to combine embedding similarity with structured attribute filters under a tight latency budget — typically a multi-stage pipeline of candidate retrieval, scoring, and re-ranking that has to return in tens of milliseconds, while incorporating real-time session signals that can't wait for a batch cycle."
    },
    {
      "id": "why-the-problem-is-hard",
      "title": "Why the problem is hard",
      "role": "content",
      "text": "Recommendation pipelines have to produce a ranked list in roughly 200 ms end to end, and the serving phase needs simultaneous access to item embeddings, item metadata, user features, and recent interaction history. Some of the obvious workarounds have real drawbacks:\n\n-   **A relational database** can store the embeddings, metadata, and user features, but it cannot\n    perform sub-millisecond approximate nearest-neighbour search at serving-time concurrency. KNN\n    over millions of vectors is not what a row store is built for.\n-   **A dedicated vector database** handles KNN with metadata filtering, but adds a separate\n    scaling and monitoring surface, another network hop, and a synchronization layer between item\n    metadata in the primary store and embeddings in the vector store. Most are also optimized for\n    batch-loaded read-heavy workloads, not sub-millisecond writes interleaved with reads when\n    session signals need to update user features mid-request.\n-   **Pre-computing recommendations offline** removes the serving-time cost but cannot react to\n    in-session behavior — the user clicks something, and the next request still ranks against the\n    yesterday's offline batch.\n\nA workable serving layer needs vector KNN, structured pre-filters, and per-user feature updates that take effect within the request path — without standing up a separate vector store and synchronizing it with the primary."
    },
    {
      "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-   Return personalized recommendations with P99 latency under 10 ms for the retrieval stage at\n    peak concurrency.\n-   Combine embedding similarity with TAG, NUMERIC, and TEXT pre-filters in a single\n    [`FT.SEARCH`](https://redis.io/docs/latest/commands/ft.search) call, with no cross-store joins.\n-   Incorporate real-time session signals (clicks, dwell time, cart adds) into the *next*\n    recommendation without waiting for a batch pipeline — a session vector written with\n    [`HSET`](https://redis.io/docs/latest/commands/hset) is visible to the very next read of the user\n    features hash, which the application passes through to\n    [`FT.SEARCH`](https://redis.io/docs/latest/commands/ft.search) as the query vector.\n-   Refresh item embeddings from the offline training pipeline without serving downtime by\n    overwriting the vector field with [`HSET`](https://redis.io/docs/latest/commands/hset); the HNSW index\n    reflects the new vector on the next query. For schema changes (different dimensionality or\n    model), the same playbook scales out to a dual-field write followed by\n    [`FT.ALTER`](https://redis.io/docs/latest/commands/ft.alter) or a swap of the indexed key prefix.\n-   Co-locate item embeddings, item metadata, user features, and short-term interaction state in\n    one serving layer, eliminating cross-store hops on the request path.\n-   Run the recommendation index on the same Redis instance already in the stack handling cache,\n    sessions, or rate limiting — no additional infrastructure."
    },
    {
      "id": "how-redis-supports-the-solution",
      "title": "How Redis supports the solution",
      "role": "content",
      "text": "In practice, each item is a single [Hash](https://redis.io/docs/latest/develop/data-types/hashes) or\n[JSON](https://redis.io/docs/latest/develop/data-types/json) document holding both its embedding vector and\nits structured metadata — category, brand, price, in-stock flag, popularity score. A single\n[Redis Search](https://redis.io/docs/latest/develop/ai/search-and-query) index covers the vector field and\nevery filter field, so one [`FT.SEARCH`](https://redis.io/docs/latest/commands/ft.search) call can do KNN\nretrieval over millions of items with a TAG, NUMERIC, or TEXT pre-filter applied in the same\npass. Per-user features live in a separate hash that the application updates atomically with\n[`HSET`](https://redis.io/docs/latest/commands/hset) and\n[`HINCRBYFLOAT`](https://redis.io/docs/latest/commands/hincrbyfloat); the next time the application reads\nthat hash to build a query, it sees the click, so session signals feed scoring without any batch\ncycle.\n\nRedis provides the following features that make it a good fit for a recommendation serving layer:\n\n-   [Hashes](https://redis.io/docs/latest/develop/data-types/hashes) and\n    [JSON](https://redis.io/docs/latest/develop/data-types/json) store each item's embedding and structured\n    metadata in a single record, so retrieval reads everything the scorer needs in one round trip.\n-   [Redis Search](https://redis.io/docs/latest/develop/ai/search-and-query) with\n    [HNSW vector indexes](https://redis.io/docs/latest/develop/ai/search-and-query/vectors) performs\n    approximate KNN over the embedding field at HNSW speeds, and the same\n    [`FT.SEARCH`](https://redis.io/docs/latest/commands/ft.search) call applies TAG / NUMERIC / TEXT filters\n    to constrain the candidate set in one pass.\n-   [`FT.HYBRID`](https://redis.io/docs/latest/commands/ft.hybrid) (Redis 8.4+) combines text and vector\n    similarity into a single ranked result via Reciprocal Rank Fusion or linear combination, for\n    queries where lexical match should contribute to the score, not just gate the candidate set.\n-   [`HSET`](https://redis.io/docs/latest/commands/hset) and\n    [`HINCRBYFLOAT`](https://redis.io/docs/latest/commands/hincrbyfloat) updates to user feature hashes are\n    atomic, so the next time the application reads that hash to build a query it sees the click\n    — session signals feed scoring without any batch cycle or cache invalidation.\n-   Overwriting the vector field with [`HSET`](https://redis.io/docs/latest/commands/hset) re-trains the\n    HNSW entry in place; for embedding-model changes,\n    [`FT.ALTER`](https://redis.io/docs/latest/commands/ft.alter) and dual-field write patterns let you swap\n    in a new model without taking the serving index offline.\n-   Sub-millisecond reads and writes from memory let the recommendation index ride on the same\n    Redis instance already handling cache, sessions, or rate limiting at zero marginal cost."
    },
    {
      "id": "ecosystem",
      "title": "Ecosystem",
      "role": "content",
      "text": "The following libraries and frameworks build on Redis Search for recommendation workloads:\n\n-   **Python**: [RedisVL](https://github.com/redis/redis-vl-python) for a high-level vector-search\n    client, and the\n    [LangChain Redis integration](https://python.langchain.com/docs/integrations/vectorstores/redis/)\n    for embedding-driven retrieval chains.\n-   **Node.js**: [`redis-om-node`](https://github.com/redis/redis-om-node) for object-mapped\n    Hash/JSON documents and Redis Search queries.\n-   **Go**: [`go-redis`](https://github.com/redis/go-redis) with first-class Redis Search support\n    for FT.SEARCH KNN and structured filters.\n-   **ML platforms**: [NVIDIA Merlin](https://github.com/NVIDIA-Merlin) for an online feature store\n    and retrieval layer that uses Redis as the serving substrate."
    },
    {
      "id": "code-examples-to-build-your-own-redis-recommendation-engine",
      "title": "Code examples to build your own Redis recommendation engine",
      "role": "example",
      "text": "The following guides show how to build a small Redis-backed product recommendation service. Each guide includes a runnable interactive demo that lets you embed a query, retrieve candidates with KNN, filter by category and price, feed clicks back as a session signal, and watch the next recommendation incorporate them immediately.\n\n* [redis-py (Python)](https://redis.io/docs/latest/develop/use-cases/recommendation-engine/redis-py)\n* [node-redis (Node.js)](https://redis.io/docs/latest/develop/use-cases/recommendation-engine/nodejs)\n* [go-redis (Go)](https://redis.io/docs/latest/develop/use-cases/recommendation-engine/go)\n* [redis-rs (Rust)](https://redis.io/docs/latest/develop/use-cases/recommendation-engine/rust)\n* [NRedisStack (C#)](https://redis.io/docs/latest/develop/use-cases/recommendation-engine/dotnet)\n* [Jedis (Java)](https://redis.io/docs/latest/develop/use-cases/recommendation-engine/java-jedis)\n* [Lettuce (Java)](https://redis.io/docs/latest/develop/use-cases/recommendation-engine/java-lettuce)\n* [Predis (PHP)](https://redis.io/docs/latest/develop/use-cases/recommendation-engine/php)\n* [redis-rb (Ruby)](https://redis.io/docs/latest/develop/use-cases/recommendation-engine/ruby)"
    }
  ],
  "examples": []
}
