Understanding the Caching Mechanisms in OmniRoute: A Complete Technical Guide
OmniRoute implements a multi-layered caching architecture combining an in-memory Prompt LRU Cache for LLM responses, a general-purpose Memory Cache for async operations, HTTP cache-control directives, and comprehensive health metrics to minimize latency and reduce provider API costs.
OmniRoute, an open-source AI provider routing layer maintained by diegosouzapw, employs sophisticated caching mechanisms to optimize performance and eliminate redundant API calls. By examining the source code in the diegosouzapw/OmniRoute repository, we can analyze how these distinct caching layers collaborate to deliver sub-millisecond response times for repeated prompts while enforcing strict memory boundaries and observability.
Layered Caching Architecture Overview
The caching mechanisms in OmniRoute are distributed across multiple specialized subsystems, each optimized for specific data types and access patterns. Rather than relying on a single cache store, the codebase separates prompt caching, general memory caching, HTTP semantic caching, and compression-aware caching into discrete modules.
Prompt LRU Cache
The Prompt LRU Cache serves as the primary caching layer for LLM interactions, storing prompt-response pairs to avoid redundant calls to expensive AI providers. Implemented in src/lib/cacheLayer.ts, this cache uses a 16-character hash key generated from request parameters including the model identifier and prompt content.
Key characteristics include:
- Default limits: 50 maximum entries and 2 MiB memory ceiling
- TTL: 5-minute default expiration configurable via the
PROMPT_CACHE_TTL_MSenvironment variable - Eviction policy: LRU (Least Recently Used) eviction when size or byte limits are exceeded
- Observability: Built-in hit, miss, and eviction statistics accessible via the
getStats()method
Memory Cache for Async Operations
For general-purpose caching of embeddings, credential health checks, and other async operations, OmniRoute utilizes the Memory Cache found in src/lib/memory/cache.ts. This implementation uses a native JavaScript Map structure with FIFO (First In, First Out) eviction when the configured maximum size is reached.
Distinct features include:
- Pattern-based invalidation for bulk cache clearing
- Async-compatible
get()andset()methods - Statistical counters via the
stats()method for monitoring hit rates
HTTP and SSE Cache Control
Beyond application-level caching, OmniRoute manages HTTP cache semantics through src/lib/cacheControlSettings.ts, which constructs appropriate Cache-Control headers for outgoing responses. For Server-Sent Events (SSE) streams, the system applies per-request cache policies via open-sse/utils/cacheControlPolicy.ts, determining whether a response can be served from cache or must be fetched upstream. The open-sse/services/compression/cacheAwareConfig.ts module further integrates caching decisions with payload compression logic.
Implementing the Prompt LRU Cache
To leverage the prompt caching mechanism in your OmniRoute deployment, interact with the singleton cache instance exported from src/lib/cacheLayer.ts. The following pattern demonstrates key generation, cache retrieval, and storage:
import { getPromptCache } from "@/src/lib/cacheLayer";
// Initialize cache with custom limits (optional)
const promptCache = getPromptCache({ maxSize: 100 });
// Generate deterministic 16-character key from request parameters
const key = LRUCache.generateKey({ model: "gpt-4", prompt: myPrompt });
// Attempt to serve from cache
const cached = promptCache.get(key);
if (cached) {
// Return cached LLM output immediately
return cached;
}
// ... after obtaining fresh response from provider:
promptCache.set(key, llmResponse);
The generateKey method hashes the provided request parameters to create a consistent cache identifier, while getPromptCache() returns a singleton instance that persists across requests.
Working with the Memory Cache
For caching embeddings, tool results, or other serializable data, use the generic Memory Cache from src/lib/memory/cache.ts. This cache supports asynchronous operations and custom TTL values per entry:
import { memoryCache } from "@/src/lib/memory/cache";
async function getEmbedding(text: string) {
const cacheKey = `embed:${text}`;
// Check cache first
const fromCache = await memoryCache.get(cacheKey);
if (fromCache) return fromCache as Uint8Array;
// Fetch from provider if miss
const fresh = await fetchEmbeddingFromProvider(text);
// Store with 10-minute TTL (specified in milliseconds)
await memoryCache.set(cacheKey, fresh, 10 * 60_000);
return fresh;
}
Unlike the Prompt LRU Cache, which manages TTL globally via environment variables, the Memory Cache allows per-entry TTL specification in the set() method's third parameter.
Monitoring Cache Health and Metrics
OmniRoute exposes detailed cache statistics through src/lib/usage/cacheHealth.ts, which aggregates metrics from both caching layers for consumption by monitoring endpoints. You can programmatically inspect cache performance using the following pattern:
import { getPromptCache } from "@/src/lib/cacheLayer";
const stats = getPromptCache().getStats();
console.log(
`Prompt cache – ${stats.hits} hits, ${stats.misses} misses, ${stats.evictions} evictions, hit-rate ${stats.hitRate.toFixed(1)}%`
);
These metrics feed into the /api/monitoring health endpoints, enabling auto-scaling decisions and cache warming strategies based on real-time hit rates.
Summary
- Prompt LRU Cache: Located in
src/lib/cacheLayer.ts, provides hashed key storage for LLM responses with configurable TTL (PROMPT_CACHE_TTL_MS) and memory limits (default 50 entries, 2 MiB). - Memory Cache: Found in
src/lib/memory/cache.ts, offers async-compatible, general-purpose caching with FIFO eviction and pattern-based invalidation. - Health Metrics: The
src/lib/usage/cacheHealth.tsmodule aggregates statistics from all caches for monitoring integration. - HTTP Cache Control:
src/lib/cacheControlSettings.tsmanages response headers, while SSE streams utilizeopen-sse/utils/cacheControlPolicy.tsfor streaming-specific cache logic. - Compression Integration:
open-sse/services/compression/cacheAwareConfig.tscoordinates caching with payload compression decisions.
Frequently Asked Questions
How does OmniRoute generate cache keys for the Prompt LRU Cache?
The LRUCache class in src/lib/cacheLayer.ts generates a deterministic 16-character hash key by hashing the request parameters object containing the model identifier and prompt content. This ensures identical prompts produce identical cache keys, while varying parameters create distinct entries.
What are the default configuration limits for OmniRoute's caching mechanisms?
The Prompt LRU Cache defaults to 50 maximum entries and 2 MiB of memory, with a 5-minute TTL. These values are configurable via constructor options when calling getPromptCache(). The Memory Cache defaults depend on instantiation parameters but utilize FIFO eviction when the configured maximum size is reached.
How can I monitor cache hit rates in production?
Invoke the getStats() method on the Prompt LRU Cache instance or the stats() method on the Memory Cache to retrieve hit counts, miss counts, eviction tallies, and calculated hit rates. These statistics are automatically aggregated by src/lib/usage/cacheHealth.ts and exposed through the /api/monitoring endpoints for dashboard integration.
Does OmniRoute support cache invalidation patterns?
Yes, the Memory Cache implementation in src/lib/memory/cache.ts supports pattern-based invalidation, allowing developers to clear multiple entries matching a specific key prefix or pattern. This is particularly useful for invalidating embedding caches when model versions change or clearing credential health check results during security rotations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →