Skip to main content
Version: 0.2.0 (Private Preview)

MongoDB Cache

:::danger Cache authorization boundary

  • Do not use shared multi-tenant caching in 0.2.0. Its cache key does not include authenticated tenant/principal or authorization-policy/role identity, and Tenant Isolation is not executed.
  • Use a dedicated Proxy and cache instance per tenant/principal security boundary, or disable caching entirely.

Unsafe legacy anti-pattern: 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.

This page belongs to the immutable 0.2.0 Private Preview documentation.

At a glance

PropertyValue
Pipeline phaseRequest + response
CategoryCache
Canonical minimum tierPro
Legacy dashboard tier labelEnterprise
Legacy rendered nameCache Layer
Legacy rendered summaryRead-through LRU cache for MongoDB — sub-millisecond reads for hot data.
Canonical entitlementYes
Supported deployment contractYes
Release statusReconciled and executable.

Release accuracy

  • 0.2.0 Private Preview: Reconciled and executable.

The detailed material below preserves every section rendered by the legacy dashboard. Where it conflicts with the release status above, the release status is authoritative. Legacy field names and examples are not a substitute for the selected bundle's CRD and runtime contract. Unsafe legacy wording is retained in metadata for traceability but is corrected in the rendered guidance.

MongoDB Cache 0.2.0 Private Preview feature flow. Reconciled and executable.

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 Legacy, unverified performance claims

These numbers are preserved for documentation parity with the legacy dashboard. They are not current benchmarks or service guarantees and have not been verified by the current test suite.

:::

PercentileLegacy claim
P500.30ms
P950.80ms
P991.50ms

Legacy 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. Security boundary: 0.2.0 caching is permitted only in a dedicated single-tenant/single-principal Proxy and cache instance. Shared multi-tenant caching is prohibited.
  2. Request phase (reads): Within that isolated deployment, eligible reads can return a cached response without reaching MongoDB.
  3. Request phase (writes): Configured write operations invalidate the namespace.
  4. Response phase: Eligible misses are stored with the configured TTL and capacity limits.

Configuration

The table preserves the legacy dashboard field reference. “Not specified” means the legacy source did not declare required semantics.

FieldLegacy UI typeLegacy defaultRequiredDescription
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

  • Do not use a shared 0.2.0 cache for multi-tenant or differently authorized principals: the key is authorization-blind and Tenant Isolation is not executed
  • Use separate Proxy and cache instances per tenant/principal security boundary or disable caching
  • Do not treat namespace and request-body matching as an authorization boundary
  • Define invalidation and acceptable staleness
  • Protect Redis with authentication, encryption in transit, and network policy

Release availability

  • 0.2.0 Private Preview: Reconciled and executable.

See the component catalog for the complete comparison matrix.

Search Nexo documentation

Type to search titles, headings, and page content.