redis-vl-dotnet
EmbeddingsCache
EmbeddingsCache is the simplest cache surface in the library. It stores one embedding per exact input string and retrieves it later without creating a RediSearch index.
When to use it
Use EmbeddingsCache when:
-
embedding generation is expensive and you want exact-input reuse
-
you do not need semantic lookup or metadata filtering
-
you want a lightweight cache that only depends on basic Redis hash operations
If you need nearest-neighbor lookup against previously stored prompts and responses, use SemanticCache instead.
Options and key layout
EmbeddingsCacheOptions controls three things:
-
Name, which becomes part of the Redis key prefix -
KeyNamespace, which lets multiple callers isolate entries inside one named cache -
TimeToLive, which applies a default Redis TTL to each stored entry
Stored values are Redis hashes keyed like embeddings:<name>:<namespace>:<sha256(input)> for legacy input-only entries and embeddings:<name>:<namespace>:<sha256(input + "\n" + model)> for model-aware entries. The library hashes the original identity before writing, but lookup is still an exact string match because the cache re-hashes the caller-provided input and optional model name.
Each hash stores the same core fields exposed by Python RedisVL parity work:
-
input -
model_name -
embedding -
metadata
Metadata is returned as the serialized JSON string stored in Redis so callers can inspect or deserialize it however they prefer.
Core operations
| API | Behavior |
|---|---|
|
Writes or overwrites the cached entry and returns an |
|
Returns the cached |
|
Supports direct Redis-key access plus semantic existence checks for exact input and model identity. |
|
Deletes a single entry by semantic identity or direct Redis key and returns |
|
Batch operations preserve the caller’s input order. Read batches return one result per requested lookup or key, using |
|
Batch existence checks return aligned |
|
Legacy-compatible aliases for callers that prefer the original method names. |
Single-entry and batch delete helpers are available for semantic lookups and direct Redis keys. Use short-lived namespaces or TTLs when you want automatic expiration instead of explicit cleanup.
TTL behavior
When TimeToLive is configured, each write resets the Redis expiration for that entry. SetAsync, StoreAsync, and EmbeddingsCacheWriteRequest can also accept a per-call timeToLive, which overrides the cache default for that write only. Once the key expires, GetAsync and LookupAsync return null, ExistsAsync returns false, and delete calls behave like a miss.
Python-parity workflow
The intended translation from Python RedisVL to .NET is:
-
Write entries with
SetAsyncwhen you want the returnedEmbeddingsCacheEntry, including the generated Redis key. -
Read exact matches with
GetAsync(input, modelName)orGetByKeyAsync(key)when a prior write returned the key. -
Use
Exists*andDelete*for cache lifecycle checks and cleanup. -
Use
SetManyAsync,GetManyAsync, and the other batch methods when callers already have multiple prompts to process. -
Keep
Store*andLookup*for legacy input-only usage or for callers migrating incrementally from older .NET examples.
Python to .NET method mapping
| Python RedisVL | .NET async | .NET sync |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Example
The runnable example for this API is /examples/EmbeddingsCacheExample.
It demonstrates:
-
creating a namespaced cache with TTL
-
storing an embedding and capturing the returned Redis key
-
reading the same entry by semantic identity and by direct Redis key
-
checking existence before and after deletion
-
reading mixed-hit batches while preserving request order
-
overwriting an existing embedding entry and applying a per-call TTL override
The exact behavior is also covered in tests/RedisVL.Tests/Caches/EmbeddingsCacheTests.cs and tests/RedisVL.Tests/Caches/EmbeddingsCacheIntegrationTests.cs.
Related sections
-
SemanticCache for semantic response reuse
-
Examples for the runnable sample map