{
  "id": "langcache_semantic_cache",
  "title": "Use LangCache as the LLM Cache Backend",
  "url": "https://redis.io/docs/latest/develop/ai/redisvl/user_guide/how_to_guides/langcache_semantic_cache/",
  "summary": "",
  "tags": [],
  "last_updated": "2026-05-06T11:49:45+02:00",
  "page_type": "content",
  "content_hash": "016290cbff918d970e86efa9cc9c18bbe9011dc199da1ededfabe3a32523dc07",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "This guide shows how to use RedisVL's `LangCacheSemanticCache`, a thin wrapper around the [LangCache](https://redis.io/langcache/) managed semantic cache service. You get the same high-level `check` / `store` workflow as `SemanticCache`, backed by LangCache's HTTP API instead of a Redis index you manage yourself.\n\nFor more on semantic caching, see [Extensions](https://redis.io/docs/latest/../../concepts/extensions), and to use RedisVL's semantic caching class see our [llm cache notebook](https://redis.io/docs/latest/llmcache). API entries for both classes live in the [LLM cache API](https://redis.io/docs/latest/../../api/cache)."
    },
    {
      "id": "prerequisites",
      "title": "Prerequisites",
      "role": "content",
      "text": "Before you begin, ensure you have:\n- Installed RedisVL with the LangCache extra: `pip install redisvl[langcache]`\n- Python 3.10+ (same as RedisVL)\n- A LangCache service with a **cache ID** and **API key**. You can set up a LangCache service in Redis Cloud [here](https://cloud.redis.io/#/)\n- Optionally: **attributes** configured on your LangCache cache if you plan to pass `metadata` / `attributes` from RedisVL"
    },
    {
      "id": "what-you-ll-learn",
      "title": "What You'll Learn",
      "role": "content",
      "text": "By the end of this guide, you will be able to:\n- Choose between `SemanticCache` and `LangCacheSemanticCache` for your deployment\n- Initialize `LangCacheSemanticCache` with credentials and TTL defaults\n- Implement read-through caching (`check` → LLM → `store`)\n- Use LangCache attributes for scoping and deletion\n- Override TTL per store, use async APIs, and run delete operations\n- Understand current limitations compared to `SemanticCache`"
    },
    {
      "id": "choose-semanticcache-or-langcachesemanticcache",
      "title": "Choose `SemanticCache` or `LangCacheSemanticCache`",
      "role": "content",
      "text": "| | `SemanticCache` | `LangCacheSemanticCache` |\n|---|------------------|--------------------------|\n| **Where data lives** | Your Redis deployment; RedisVL creates and queries a search index | LangCache managed service (hosted API) |\n| **Best when** | You control Redis, need full RedisVL query/filter features, or co-locate cache with app data | You want a managed semantic cache without operating Redis or the index |\n| **Vector search by raw embedding** | Supported (`vector=` on `check`) | **Not supported** — search is prompt-based via the LangCache API |\n| **Filter expressions** | `FilterExpression` on `check` | **Not supported** — use LangCache **attributes** (pre-configured on the cache) |\n| **Partial entry updates** | Supported where the backend allows | **`update` / `aupdate` raise** — delete and re-store instead |\n\n**Note:** `SemanticCache` is covered in depth in the [llmcache notebook](https://redis.io/docs/latest/llmcache) guide."
    },
    {
      "id": "install-the-langcache-extra",
      "title": "Install the LangCache extra",
      "role": "setup",
      "text": "The `redisvl[langcache]` extra installs compatible `langcache` dependencies:\n\n[code example]\n\n\n\n[code example]"
    },
    {
      "id": "initialize-langcachesemanticcache",
      "title": "Initialize `LangCacheSemanticCache`",
      "role": "content",
      "text": "Create `LangCacheSemanticCache` with your LangCache credentials. The default `server_url` points at the managed LangCache API; override it if your provider gives a different endpoint.\n\nThe following example reads credentials from environment variables (recommended for applications). Replace placeholder values when experimenting locally.\n\n\n\n[code example]\n\n| Parameter | Purpose |\n|-----------|---------|\n| `cache_id`, `api_key` | Required. Identify your LangCache cache and authenticate. |\n| `server_url` | LangCache API base URL (default matches typical managed deployments). |\n| `ttl` | Default time-to-live for stored entries, in seconds; can be overridden per `store` call. |\n| `use_exact_search` / `use_semantic_search` | Enable exact and/or semantic matching (at least one must be `True`). |\n| `distance_threshold` (on `check`) | Works with `distance_scale`: `\"normalized\"` (0–1 distance) or `\"redis\"` (cosine-style 0–2). |"
    },
    {
      "id": "attributes-and-metadata",
      "title": "Attributes and metadata",
      "role": "content",
      "text": "LangCache **attributes** are key/value metadata attached to entries. They can be used when **searching** (`check` / `acheck` via the `attributes` argument) and when **deleting** (`delete_by_attributes` / `adelete_by_attributes`).\n\n**You must define the same attribute names (and types) in the LangCache console or API for your cache before RedisVL can use them.** If you pass `metadata` to `store` or `attributes` to `check` but the cache has no attributes configured, the LangCache API returns an error; RedisVL surfaces a clear `RuntimeError` explaining that attributes need to be configured or removed from the call.\n\nString values are encoded for the API and decoded when reading hits so special characters remain usable."
    },
    {
      "id": "read-through-caching-pattern",
      "title": "Read-through caching pattern",
      "role": "content",
      "text": "Typical flow: try `check`, call the LLM on a miss, then `store` the result.\n\n\n\n[code example]\n\nOptional scoping with attributes (only if those attributes are configured on LangCache):\n\n\n\n[code example]"
    },
    {
      "id": "ttl",
      "title": "TTL",
      "role": "content",
      "text": "- **Constructor** `ttl=` sets the default lifetime for new entries (seconds).\n- **Per call**, pass `ttl=` to `store` / `astore` to override the default for that entry.\n\n\n\n[code example]"
    },
    {
      "id": "async-usage",
      "title": "Async usage",
      "role": "content",
      "text": "Use the `a`-prefixed methods with `asyncio` — for example `acheck`, `astore`, `adelete`, `adelete_by_id`, `adelete_by_attributes`, `aclear`.\n\n\n\n[code example]"
    },
    {
      "id": "delete-operations",
      "title": "Delete operations",
      "role": "content",
      "text": "| Method | What it does |\n|--------|----------------|\n| `delete()` / `adelete()` | **Flush** the entire cache (all entries). Aliases: `clear()` / `aclear()`. |\n| `delete_by_id(entry_id)` / `adelete_by_id` | Remove one entry by LangCache entry ID (returned from `store`). |\n| `delete_by_attributes` / `adelete_by_attributes` | Remove entries matching the given attribute map (non-empty dict required). |"
    },
    {
      "id": "current-limitations",
      "title": "Current limitations",
      "role": "content",
      "text": "The wrapper follows the LangCache API. The following RedisVL features either do not apply or are explicitly unsupported:\n\n- **No direct vector search** — Passing `vector=` to `check` / `acheck` logs a warning and does not search by embedding.\n- **No `filter_expression`** — RedisVL filter expressions are not translated; use LangCache attributes only.\n- **No `update()` / `aupdate()`** — The LangCache API does not update individual entries; these methods raise `NotImplementedError`. Delete the entry (or store a new pair) instead.\n- **`filters` on `store`** — Not supported by LangCache; a warning is logged if provided.\n\n**Tip:** See the **LangCacheSemanticCache** section in the [LLM cache API](https://redis.io/docs/latest/../../api/cache) for parameter and method listings."
    }
  ],
  "examples": [
    {
      "id": "install-the-langcache-extra-ex0",
      "language": "bash",
      "code": "pip install redisvl[langcache]",
      "section_id": "install-the-langcache-extra"
    },
    {
      "id": "install-the-langcache-extra-ex1",
      "language": "python",
      "code": "# NBVAL_SKIP\n%pip install redisvl[langcache]",
      "section_id": "install-the-langcache-extra"
    },
    {
      "id": "initialize-langcachesemanticcache-ex0",
      "language": "python",
      "code": "# NBVAL_SKIP\nimport os\n\nfrom redisvl.extensions.cache.llm import LangCacheSemanticCache\n\nCACHE_ID = os.environ.get(\"LANGCACHE_CACHE_ID\", \"YOUR_CACHE_ID\")\nAPI_KEY = os.environ.get(\"LANGCACHE_API_KEY\", \"YOUR_API_KEY\")\n\ncache = LangCacheSemanticCache(\n    name=\"my_app_cache\",\n    server_url=\"https://aws-us-east-1.langcache.redis.io\",\n    cache_id=CACHE_ID,\n    api_key=API_KEY,\n    ttl=3600,  # default TTL for entries, in seconds (optional)\n)",
      "section_id": "initialize-langcachesemanticcache"
    },
    {
      "id": "read-through-caching-pattern-ex0",
      "language": "python",
      "code": "# NBVAL_SKIP\ndef call_your_llm(prompt: str) -> str:\n    \"\"\"Replace with your LLM client (OpenAI, Anthropic, etc.).\"\"\"\n    return f\"Answer for: {prompt}\"\n\n\ndef answer(user_prompt: str) -> str:\n    hits = cache.check(prompt=user_prompt, num_results=1)\n    if hits:\n        return hits[0][\"response\"]\n\n    response = call_your_llm(user_prompt)\n    cache.store(prompt=user_prompt, response=response)\n    return response",
      "section_id": "read-through-caching-pattern"
    },
    {
      "id": "read-through-caching-pattern-ex1",
      "language": "python",
      "code": "# NBVAL_SKIP\nuser_prompt = \"Example prompt\"\n\nhits = cache.check(\n    prompt=user_prompt,\n    attributes={\"tenant_id\": \"acme\", \"model\": \"gpt-4o\"},\n    num_results=1,\n)",
      "section_id": "read-through-caching-pattern"
    },
    {
      "id": "ttl-ex0",
      "language": "python",
      "code": "# NBVAL_SKIP\nprompt = \"What is Redis?\"\nresponse = \"Redis is an in memory data store.\"\n\ncache.store(prompt=prompt, response=response, ttl=300)  # this entry expires in 5 minutes",
      "section_id": "ttl"
    },
    {
      "id": "async-usage-ex0",
      "language": "python",
      "code": "# NBVAL_SKIP\nasync def call_your_llm_async(prompt: str) -> str:\n    return f\"Async answer for: {prompt}\"\n\n\nasync def answer_async(user_prompt: str) -> str:\n    hits = await cache.acheck(prompt=user_prompt, num_results=1)\n    if hits:\n        return hits[0][\"response\"]\n\n    response = await call_your_llm_async(user_prompt)\n    await cache.astore(prompt=user_prompt, response=response)\n    return response",
      "section_id": "async-usage"
    }
  ]
}
