Skip to main content
Version: Next (Private Preview)

MongoDB Cache

:::danger Cache authorization boundary

  • Do not use shared or multi-tenant caching unless the selected runtime explicitly guarantees that every cache key includes authenticated tenant/principal identity and authorization-policy/role identity in addition to the request namespace, command, and body.
  • If those authorization boundaries cannot be guaranteed, use a dedicated Proxy and cache per tenant/principal security boundary or disable caching.

Anti-pattern to avoid: The legacy key formula hashes only database + collection + command + request body. It omits authenticated tenant/principal identity and authorization-policy/role identity, so two callers with different permissions can collide and receive the same cached response.

:::

Serve repeated eligible reads from an in-memory LRU or Redis backend.

Always confirm availability in the release bundle selected for deployment.

At a glance

PropertyValue
Pipeline phaseRequest + response
CategoryCache
Canonical minimum tierPro
Canonical entitlementYes
Supported deployment contractYes
Release statusCatalog component. The dashboard currently displays an incorrect Business badge; canonical entitlement is Pro.

Release accuracy

  • Current documentation: Catalog component. The dashboard currently displays an incorrect Business badge; canonical entitlement is Pro.

Where any detail below conflicts with the release status above, the release status is authoritative. Field names and examples describe the current dashboard and CRD surface; always confirm behavior against the selected release bundle before relying on it operationally.

MongoDB Cache current release feature flow. Catalog component. The dashboard currently displays an incorrect Business badge; canonical entitlement is Pro.

Release-aware feature flow. The diagram is explanatory; the release status on this page is authoritative.

Diagram resources: Open the SVG full screen · Download the editable Excalidraw source

Performance impact

:::warning Unverified performance figures

These figures are illustrative only. They are not current benchmarks or service guarantees and have not been verified by the current test suite.

:::

PercentileReported figure
P500.30ms
P950.80ms
P991.50ms

Note: Cache miss path. Cache hits return in ~0.05ms (SHA256 + map lookup). Net effect is latency REDUCTION for cached reads.

Overview

The Cache Layer step provides an in-memory read-through cache for MongoDB queries. Frequently accessed documents are served directly from the proxy's memory, reducing load on the database and providing sub-millisecond response times for hot data.

The cache uses an LRU (Least Recently Used) eviction policy with per-namespace TTL configuration. Write operations automatically invalidate relevant cache entries to maintain consistency.

When to use

  • Read-heavy workloads with frequently accessed "hot" documents
  • Reducing MongoDB cluster load without application-level caching
  • Latency-sensitive applications where even 1-2ms matters
  • Cost reduction by serving reads from proxy memory instead of database IOPS

How it works

  1. Admission requirement: Cache only when the runtime key includes the database, collection, command, full request body, authenticated tenant/principal identity, and authorization-policy/role identity.
  2. Isolation fallback: If the selected runtime cannot guarantee every authorization boundary in the key, shared caching is prohibited; use a dedicated Proxy and cache per security boundary or disable caching.
  3. Request phase (writes): Detects configured write operations and invalidates the affected namespace.
  4. Response phase: For an eligible miss inside an isolated authorization boundary, stores the response with the configured TTL and capacity limits.

Configuration

“Not specified” means required semantics were not declared for that field.

FieldTypeDefaultRequiredDescription
max_entriesnumber10000NoMaximum number of cached entries before LRU eviction starts.
max_memory_mbnumber256NoIndependent memory ceiling in MB; whichever capacity limit (entries or memory) is reached first triggers eviction.
default_ttlduration60sNoDefault time-to-live for cached entries when a namespace rule does not set its own TTL.
backendselectmemoryYesWhere cache entries are stored: "memory" (per-proxy LRU, fastest) or "redis" (shared across replicas, adds a network hop).
redis_addrstringlocalhost:6379NoRedis endpoint used when backend="redis". Accepts host:port (e.g. redis-master:6379) or a redis:// URL. Ignored for the memory backend.
max_value_sizenumber1048576NoMaximum size in bytes of a response eligible for caching; larger responses bypass the cache.
cacheable_commandsmultiselect["find","aggregate","count","distinct"]NoRead commands eligible for caching (find, aggregate, count, distinct, getMore, listCollections, listIndexes). Commands outside the list always hit MongoDB.
invalidate_onmultiselect["insert","update","delete","drop"]NoWrite commands that evict matching cached entries (insert, update, delete, drop, findAndModify, replace).
rulesjsonNoNamespace allowlist: [{ database, collection, ttl }]. database "" matches all databases; collection supports glob (e.g. "logs_", "*"); empty collection = all collections. With no rules, nothing is cached.
stats_headersobjectdisabledNoAdds cache diagnostic response headers. Shape: { enabled, include_key }. include_key exposes the resolved cache key for debugging — avoid if keys can contain sensitive identifiers. Requires Pro.
negative_cacheobjectdisabledNoCaches empty/not-found results to shield the backend from repeated misses. Shape: { enabled, ttl_sec, max_entries }. Keep ttl_sec short so newly-created documents are not hidden behind stale misses. Requires Pro.
write_behindobjectdisabledNoCoalesces invalidations during bursty writes. Shape: { enabled, window_ms, max_pending }. Larger window_ms reduces churn but can serve stale data longer; max_pending forces an early flush. Requires Business.
pattern_invalidationobjectdisabledNoMaps writes on one namespace to evictions on another (e.g. invalidate order_summary when orders change). Shape: { enabled, rules: [{ trigger_database, trigger_collection, invalidate_database, invalidate_collection }] } with glob support. Requires Business.

Settings reference

Capacity limits

Max Entries caps the number of cached responses before least-recently-used eviction starts. Max Memory sets an independent memory ceiling in MB, so whichever capacity limit is reached first can evict older entries. Tune both for the amount of hot data you expect the proxy to hold.

Default TTL

Default TTL controls how long cached responses remain fresh when a namespace rule does not provide its own TTL. It uses duration strings such as 60s, 5m, or 1h. Rule-level TTL values override this default for matching namespaces.

Backend

The backend selects where cache entries are stored. Memory (LRU) is per-proxy and fastest, matching the current modal default — its max_entries and max_memory_mb caps are enforced in-process. Redis stores entries in a shared server so a hit warmed by one replica serves all replicas, at the cost of a network hop; set redis_addr to the endpoint (host:port or a redis:// URL). With Redis, eviction is governed by the Redis server maxmemory policy (the entry/memory caps are advisory) and TTL uses native key expiry. Redis operations are fail-open: any error or timeout degrades to a cache miss so a Redis outage never blocks requests.

Value size limit

Max Value Size prevents responses larger than the configured byte limit from being cached. This protects the cache from a few large documents evicting many smaller hot entries. Increase it only when large responses are repeatedly read and safe to cache.

Commands and invalidation

Cacheable Commands lists the read commands eligible for caching; commands outside the list always hit MongoDB. Invalidate On lists write commands that evict matching cached entries. The defaults cache common read commands and invalidate on insert, update, delete, and drop.

Cache rules

Rules are the namespace allowlist for caching. Each rule names a database and collection glob, with an optional TTL that overrides the default. With no rules configured, nothing is cached.

Stats headers

Stats headers add response headers such as cache status, age, and hit ratio so clients and dashboards can inspect cache behavior. Including the resolved cache key is useful for debugging key composition. Avoid exposing keys if they can contain sensitive identifiers.

Negative caching

Negative caching stores empty or not-found responses for a short period to shield the backend from repeated misses. Keep the TTL short so newly-created documents are not hidden behind stale empty results. The max entries setting bounds memory used by cached misses separately from normal cache entries.

Write-behind coalescing

Write-behind coalescing batches invalidations during bursty writes. The coalesce window controls how long invalidations wait before being applied, trading less churn for slightly longer potential staleness. Max Pending forces an early flush when too many invalidations are queued.

Pattern invalidation

Pattern invalidation maps writes on one namespace to evictions on another namespace. Use it for derived views or summaries, such as invalidating an order_summary cache when orders change. Each rule defines a trigger database/collection and an invalidated database/collection, with glob support.

Examples

General-purpose cache with per-namespace rules

steps:
- name: builtin:cache
config:
max_entries: 50000
default_ttl: "5m"
max_value_size: 131072
rules:
- database: "config"
collection: "settings"
ttl: "1h"
- database: "users"
collection: "profiles"
ttl: "30s"
invalidate_on: ["insert", "update", "delete"]

Best practices

  • Start with short TTLs (30s-5m) and increase based on data staleness tolerance
  • Use rules to allowlist which namespaces to cache — set database:"*" to cache everything, or list specific database/collection pairs with per-rule TTLs
  • Monitor cache hit rate via the nexo_cache_hits_total / nexo_cache_misses_total metrics
  • Set max_value_size to exclude large documents that would waste cache space
  • Use invalidate_namespace (default) unless you understand the consistency trade-offs

Limitations

  • In-memory only — cache is lost on proxy restart
  • Conservative invalidation (invalidate_namespace) may over-invalidate
  • Cannot cache queries with $currentDate or server-generated values
  • Multi-proxy deployments have independent caches — no cross-instance coherence

Security and operational guidance

  • Require authenticated tenant/principal identity and authorization-policy/role identity in every cache key
  • Do not enable shared or multi-tenant caching unless the selected runtime explicitly guarantees those key boundaries
  • Otherwise use separate Proxy and cache instances per security boundary or disable caching
  • Define invalidation and acceptable staleness
  • Protect Redis with authentication, encryption in transit, and network policy

Release availability

  • Current documentation: Catalog component. The dashboard currently displays an incorrect Business badge; canonical entitlement is Pro.

See the component catalog for the complete comparison matrix.

Search Nexo documentation

Type to search titles, headings, and page content.