Redis Keys¶
Redis is the gateway's fast mutable state store. PostgreSQL remains the durable source of truth for keys, policy, service registration, usage records, and operator state. Redis stores only short-lived rate-limit and budget control state plus readiness checks.
Scope¶
REDIS_URLpoints Gateway at the Redis instance used for readiness, rate limits, and budget counters./readyzchecks Redis withPING; readiness does not create a persistent application key.- Redis keys are generated by
gateway-corehelpers and written bygateway-store::RedisControlState. - All current keys are scoped by the PostgreSQL
api_keys.idUUID, not by raw virtual key material or key prefixes.
Required Operational State¶
| Area | Redis key family | Required when |
|---|---|---|
| Request rate limit | rl:req:<key_id>:<yyyymmddhhmm> |
A virtual key policy has rpm_limit set. |
| Daily budget | budget:daily:<key_id>:<yyyymmdd> |
A virtual key policy has a daily budget or a request records/reserves positive cost. |
| Monthly budget | budget:monthly:<key_id>:<yyyymm> |
A virtual key policy has a monthly budget or a request records/reserves positive cost. |
| Budget reservation | budget:reservation:<key_id>:<request_id> |
A request reserves estimated cost before final usage reconciliation. |
Redis can be treated as volatile for normal operations. Restarting or flushing Redis clears rate-limit windows, budget counters, and in-flight budget reservations, but does not delete virtual keys, policies, usage events, or operator state from PostgreSQL.
Key Reference¶
rl:req:<key_id>:<yyyymmddhhmm>¶
Request-per-minute counter for one virtual key and one UTC minute.
| Field | Details |
|---|---|
| Example | rl:req:018f8d31-86a7-7c48-8f36-4d1fa4d99101:202605091403 |
| Owner | RateLimitStore::check_request_rate_limit. |
| Value | Integer counter incremented with INCR. |
| Time bucket | UTC minute formatted as YYYYMMDDHHMM. |
| TTL | 70 seconds. |
| Created when | key_policies.rpm_limit is not NULL and the key makes a request. |
| Used for | Comparing the incremented count with rpm_limit; exceeded requests return retry timing based on Redis TTL when available. |
The 70-second TTL intentionally outlives the exact minute boundary so late requests and clock skew do not immediately erase the active bucket.
budget:daily:<key_id>:<yyyymmdd>¶
Daily spend counter for one virtual key and one UTC day.
| Field | Details |
|---|---|
| Example | budget:daily:018f8d31-86a7-7c48-8f36-4d1fa4d99101:20260509 |
| Owner | BudgetStore::check_budget, add_budget_spend, reserve_budget, reconcile_budget_reservation, and release_budget_reservation. |
| Value | Floating-point USD amount stored through INCRBYFLOAT. Missing or unparsable values are treated as 0.0 by Gateway. |
| Time bucket | UTC day formatted as YYYYMMDD. |
| TTL | 172,800 seconds, or 2 days, after writes that add or reserve positive spend. |
| Created when | A positive estimated or actual cost is recorded or reserved for the key. |
| Used for | Enforcing key_policies.daily_budget_usd and reporting the current daily budget state during checks. |
When a request reserves budget, this counter is incremented immediately. Later reconciliation adjusts it by the difference between actual cost and reserved cost. Releasing a reservation subtracts the reserved amount.
budget:monthly:<key_id>:<yyyymm>¶
Monthly spend counter for one virtual key and one UTC month.
| Field | Details |
|---|---|
| Example | budget:monthly:018f8d31-86a7-7c48-8f36-4d1fa4d99101:202605 |
| Owner | BudgetStore::check_budget, add_budget_spend, reserve_budget, reconcile_budget_reservation, and release_budget_reservation. |
| Value | Floating-point USD amount stored through INCRBYFLOAT. Missing or unparsable values are treated as 0.0 by Gateway. |
| Time bucket | UTC month formatted as YYYYMM. |
| TTL | 5,356,800 seconds, or 62 days, after writes that add or reserve positive spend. |
| Created when | A positive estimated or actual cost is recorded or reserved for the key. |
| Used for | Enforcing key_policies.monthly_budget_usd and reporting the current monthly budget state during checks. |
The 62-day TTL keeps the current and recently closed monthly bucket available long enough for late reconciliation.
budget:reservation:<key_id>:<request_id>¶
In-flight budget reservation for a single request.
| Field | Details |
|---|---|
| Example | budget:reservation:018f8d31-86a7-7c48-8f36-4d1fa4d99101:req-1 |
| Owner | BudgetStore::reserve_budget, reconcile_budget_reservation, and release_budget_reservation. |
| Value | Pipe-delimited string: <amount_usd>|<daily_key>|<monthly_key>. |
| TTL | 3,600 seconds, or 1 hour. |
| Created when | Gateway reserves a positive estimated cost for a request. |
| Deleted when | Reconciliation applies actual cost, or release subtracts the reservation after failure/cancellation. |
| Fallback behavior | If the reservation key is missing or malformed, Gateway treats the reserved amount as 0.0 and derives the daily/monthly keys from the current request context. |
Reservation values include the original daily and monthly budget keys so reconciliation can adjust the same time buckets that were charged during reservation, even if the request crosses a UTC day or month boundary.
Operating Notes¶
- Do not store raw Relayna virtual keys, operator tokens, provider credentials, prompts, or request bodies in Redis.
- Use PostgreSQL usage events for durable billing and audit history. Redis budget counters are control-plane state, not the billing ledger.
- Avoid manual edits unless recovering from a known operational incident. If a
counter must be corrected, update both the daily and monthly counter for the
same
key_idconsistently. - Redis persistence is optional for basic gateway operation. Enable Redis persistence only when your deployment requires rate-limit and budget state to survive Redis restarts.