What is shared
When Redis is enabled, ONR shares the following state across instances:- client access keys, their HMAC hashes, subjects, status, and expiry;
- subject blocked state received from Meterry webhooks;
- short-lived realtime balance decisions;
- asynchronous Meterry usage events in a Redis Stream;
- billing consumer-group pending entries, retry counters, and dead-letter events.
keys.yaml, a secret manager, or deployment secrets on every instance.
The request and billing flow is:
Prerequisites
Prepare:- A highly available Redis deployment reachable by every ONR instance. A managed primary/replica service or a Redis-compatible proxy is recommended.
- A Meterry project, published extractor rule set, project API key, and webhook signing secret.
- The same ONR configuration files and provider secrets on every instance.
- A load balancer that can route requests to any healthy instance.
go-redis/v9. Redis Cluster-specific commands are not required; use a managed endpoint or proxy that exposes the configured endpoint.
Configure Redis
Add the Redis block toonr.yaml:
ONR_ACCESS_KEY_HASH_SECRET must be the same on every ONR instance. Rotating it changes the hash of every Redis access key, so plan a coordinated migration before changing it.
Access-key lookup modes
redis_preferred is the recommended migration mode:
- look up a matching access key in Redis first;
- if Redis has no matching key, fall back to
keys.yaml; - if Redis is unavailable, fail closed and return an authentication-service error.
redis_only after all client keys have been migrated. file_only disables Redis access-key lookup while leaving the Redis control plane available for billing and shared balance state.
Configure Meterry and webhooks
Keep the Meterry project credentials in deployment secrets and configure the same project and extractor rule set on every instance:Migrate access keys
Redis stores only an HMAC-SHA256 hash. The plaintext secret is printed once during creation or rotation and is never written to Redis. Create a new key:keys.yaml with a dry run first:
access_key_mode: redis_preferred while validating the cluster. Switch to redis_only once all clients use the Redis-managed secrets.
Run multiple instances
Every instance should use the same:redis.addr,key_prefix, andaccess_key_hash_secret;- Meterry project, API key, and extractor rule set;
- provider DSL and model configuration;
- webhook path and signing secret.
billing_consumer_name empty makes ONR generate one from the hostname and process ID. All consumers use the same group:
XAUTOCLAIM. Meterry’s onr:<request_id> idempotency key prevents duplicate billing when an event is retried or reclaimed.
Health checks and rollout
Use/healthz for process liveness and /readyz for load-balancer readiness:
/readyz reports:
- Redis connectivity;
- whether Meterry is configured;
- billing pending-entry and dead-letter counts when the billing consumer is enabled.
Failure behavior
Redis is a control plane and cache, not the balance ledger. Do not implement local wallet debits or reservations in ONR.
Verify the cluster
Run these checks before production rollout:- Create an access key on instance A and authenticate through instance B.
- Revoke the key on instance A and confirm instance B rejects it immediately.
- Send requests through both instances and confirm the Meterry Usage Explorer shows one event per
onr:<request_id>. - Stop the billing worker on one instance, enqueue a request, and confirm another instance reclaims and delivers the pending event.
- Send a signed
wallet.insufficient_balancewebhook and confirm both instances return402 Payment Requiredfor the blocked subject. - Credit the Meterry wallet, send
wallet.balance_changed, and confirm requests succeed again. - Check
/readyzfor Redis availability, pending entries, and dead-letter count.