Caching

GroundRoute caches results so repeated and similar queries return without re-hitting an engine. A cache hit costs nothing from the engine — and under gain-share pricing you pay only 50% of what the hit saved you. Every response reports the cache outcome in cache_meta.

Tiers

GroundRoute looks up the cache in this order; the first hit wins.

Tier (cache_tier)What it is
exact_privateAn exact, per-tenant match — same normalized query and parameters, for your tenant only.
exact_pooledAn exact match served from the cross-customer pooled cache, when the query is safe to share (generic, no PII, not personalized, not BYOK-private).
semanticA near-match found by embedding similarity above the per-class threshold. Skipped for fresh queries.
missNo cache hit — the query was routed to an engine.

The pooled cache is the durable edge: a generic query another customer already ran can serve yours for free. Private and BYOK queries are never pooled.

What goes into the cache key

The exact-cache key is derived from the normalized query plus the parameters that change the results: max_results, domains, lang, country, and the freshness bucket. Two requests that differ on any of these are cached separately. The key stored in cache_meta is a SHA-256 hex digest — the raw query is never stored in the key.

TTLs

Exact private TTLs are set per query class:

ClassPrivate TTL
news5 minutes
answer3 hours
web24 hours
page5 days
academic14 days

fresh intent caps the exact TTL at 5 minutes regardless of class, and bypasses the semantic tier entirely.

Pooled TTLs are always the private TTL for the same cell (a tighter staleness budget for cross-tenant reuse), and depend on both the class and the freshness bucket (static / semi). Cells not in the pooled allowlist are not poolable.

cache_meta fields

FieldTypeMeaning
cache_tierenummiss, exact_private, exact_pooled, or semantic.
poolableboolWhether this entry is eligible for the pooled cache.
poolability_reasonstringWhy it is/isn't poolable — e.g. poolable:web/static, byok_private, fresh_intent, news_class, pii_in_query, personalized, tenant_consume_opt_out, tenant_contribute_opt_out, cell_not_allowlisted, eval_error.
screens_post_nfkcboolSafety screens ran on the NFKC-normalized query (required for any pooled entry).
freshness_bucketstringhourly, daily, or none.
cache_key_privatestring | nullSHA-256 hex of the private key (no raw query).
cache_key_pooledstring | nullPooled key — set only when poolable.
cached_atdatetime | nullWhen the cached entry was written (hits only).
ttl_secondsint | nullRemaining/assigned TTL.
cost_avoided_usdfloatProvider cost saved by this hit. Drives the gain-share charge.
similarityfloat | nullSemantic tier only — similarity vs the per-class threshold.

Opting out of pooling

A tenant can opt out of consuming from the pool, contributing to it, or both. The reasons are distinct in the audit trail (tenant_consume_opt_out vs tenant_contribute_opt_out). When evaluation fails for any reason, the entry is forced private (eval_error) — the pooled cache fails closed.