Govern
Documentation

Version Latest

Routing and caching

Configure retries, timeouts and the circuit breaker, define routes over several models with fallback and load-balancing strategies and conditions, and turn on the sealed response cache in the Neural Inverse Govern model gateway.

Routing and caching make the gateway more reliable and cheaper. None of them widens access: every model a route or fallback reaches is decided again for the caller, and a cached answer is served only to someone who could have made the same request.

Retries, timeouts and the circuit breaker

Set per organisation on Models > Gateway endpoints, or with GET/PUT /api/v1/models/gateway-settings (models:view to read, models:admin to change). PUT replaces every field.

SettingDefaultRangeMeaning
retry_attempts20 to 5Retries of a transient failure on the same model
retry_base_ms25010 to 10000Base of the exponential backoff with full jitter
retry_max_ms4000base to 60000Cap of one backoff wait
upstream_timeout_ms600001000 to 600000Wait for the provider's response headers; a stream that started is never cut
breaker_failures50 to 100Consecutive failures that open a model's circuit; 0 disables the breaker
breaker_cooldown_seconds305 to 3600How long an open circuit skips the model
FailureSame model againNext candidate
429, 408, 5xx, timeout, unreachableYes, up to retry_attemptsAfter the retries
401, 403 (rejected key), 404 (unknown model), refused by the outbound guardNoYes
Any other 4xx (the caller's request)NoNo, returned to the caller
Budget or plan refusalNoNo

A provider's Retry-After replaces the backoff when it is not longer than retry_max_ms; a longer one moves to the next candidate at once. A client can lower retries for one request with X-Keystone-Retries, never raise them. Nothing is retried once a byte of the answer reached the caller. Every attempt is its own budget reservation and usage event.

The circuit breaker is per server process, organisation and model. After the threshold the model is skipped for the cooldown, then one probe request is let through. When every candidate is skipped this way the caller gets 503 circuit_open with Retry-After. Circuit state starts empty after a restart.

Fallback chains

Each catalog model can have a fallback chain of up to 20 models (PUT /api/v1/models/catalog/{id}/fallbacks). When the upstream fails before any byte reached the client, the next model is tried. Each fallback is decided again (assignment, classification, region, budget), so a fallback can never reach a model the caller may not use.

Routes

A route is a virtual model name over 1 to 20 catalog models. Clients name it wherever they name a model, and GET /v1/models lists the routes the caller can use. Route keys and model keys share one namespace.

Open Models > Routes and strategies, or POST /api/v1/models/routes (models:write):

{
  "route_key": "assistant",
  "display_name": "Assistant",
  "strategy": "consistent_hash",
  "hash_key": "user",
  "targets": [{"model_id": "<gpt>", "weight": 3}, {"model_id": "<claude>", "weight": 1}],
  "conditions": [
    {"match": {"classifications": ["restricted"]}, "targets": [{"model_id": "<on-prem llama>"}]},
    {"match": {"metadata": {"tier": "batch"}, "max_tokens_at_least": 4000}, "strategy": "least_cost",
     "targets": [{"model_id": "<haiku>"}, {"model_id": "<mini>"}]}
  ]
}
StrategyOrder of the targets
fallbackAs configured
weightedWeighted random first pick, the rest as fallbacks (load balancing, canaries, A/B)
least_latencyUnmeasured targets first, then by moving average time to response headers
least_costBy catalog input plus output price
round_robinIn turn, by weight
least_busyFewest requests in flight first
consistent_hashWeighted rendezvous hashing on hash_key: user (default), api_key or metadata:<name>; one key stays on one target while it is usable

Latency, in-flight counts and round-robin counters are per server process.

Conditions

A route can carry up to 20 ordered conditions, each with its own targets and strategy. The first condition whose match fits the request decides; a request no condition matches goes to the route's own targets. A match can test:

FieldFits when
usesThe request's use is listed
classificationsThe request's classification is listed
project_idsThe request names a listed project
team_idsThe caller belongs to a listed team
metadataEvery listed pair equals a value of X-Keystone-Metadata
max_tokens_at_least, max_tokens_at_mostThe requested output limit lies in the range

A condition never widens access. When the matching condition has no target the caller may use, the request is refused; it does not fall through to the route's own targets. A route ignores its targets' own fallback chains: the route is the chain. A disabled route refuses with model_not_allowed.

GET /api/v1/models/routes/{id}/effective shows how a route resolves. Route changes are audited (models.route.create, .update, .delete).

Response cache

The cache is off by default. It needs the deployment's key management service: without it, turning the cache on is refused (503 models.cache.unavailable).

Turn it on in Models > Response cache or with the gateway settings:

SettingDefaultMeaning
cache_modeoffoff, exact (identical requests) or semantic (identical requests, then a semantically equal last message)
cache_scopeuseruser: each person or key has their own entries, per project. project: members of a project share. org: the whole organisation shares.
cache_ttl_seconds360060 to 2592000
cache_max_classificationinternalRequests of a stricter classification never read or write the cache
cache_semantic_threshold0.950.8 to 0.999
cache_embedding_model_idRequired for semantic: an enabled catalog model with the embedding use

Rules that keep the cache safe:

  • semantic works with user scope only.
  • The request key is the request after DLP, so a cached answer was produced for exactly what policy let through.
  • A hit is served only while the model that produced it is still one the caller may use.
  • Answers paid with a person's own provider key are stored only under user scope.
  • Entries are sealed with AES-256-GCM under a data key wrapped by the organisation's key models-gateway-cache.
  • A hit still counts on rate limits and budgets, is audited with the cost it saved, and is recorded as a zero-cost usage event.
  • Changing any rule's output guardrails deletes the organisation's cached answers.
  • An organisation's cache holds at most 20,000 entries and 512 MiB; older entries are evicted first.

Clients can skip the cache for one request with X-Keystone-Cache-Control: no-cache (do not read) or no-store (do not write). GET /api/v1/models/cache/stats (models:view) reports entries, hits and savings; POST /api/v1/models/cache/flush (models:admin) deletes every entry, or those of one model or route with {"model": "<key>"}.

Advanced routing in the AI Gateway service

The AI Gateway service adds reliability settings (GET/PUT /api/v1/models/gateway-reliability), hedged requests, traffic mirroring and canaries on AI Gateway > Routing and reliability. These are recorded as working in the source; see the console page for the options your deployment offers.

Last reviewed 17 October 2026View as Markdown

Routing and caching · Docs · Neural Inverse