Expand description
Schema-validation limits: numeric bounds the config compiler enforces and runtime code must respect.
These constants are part of the CONFIG CONTRACT (a value validation
rejects can never reach the runtime), so they live beside the schema
rather than in the modules that also use them at runtime: validation
(snapshot::validate) and the runtime consumers (the balancer’s ring
construction, the slow-start clamp, the retry parameter resolution)
all read the same numbers from here.
Constants§
- DEFAULT_
LICENSE_ GRACE_ PERIOD_ DAYS - Default grace period (days) after a license expires before the gate
degrades to OSS (DW-032). Configurable via
gateway.license.grace_period_days; 0 means no grace (immediate degradation on expiry). Lives in config (the lowest domain) so both extensions::licensing (the gate) and snapshot::validate (the bounds check) can read it without an upward import. - KETAMA_
VNODES - Ketama vnode count per unit of endpoint weight (a weight-1 endpoint
gets 160 vnodes; a weight-w endpoint gets
160 * w— footprint is additive, so adding an endpoint never resizes existing segments). - MAGLEV_
TABLE_ SIZE - Maglev lookup table size (DP-07, #236). Must be a prime number for the Maglev permutation algorithm to work correctly. 65537 is the default used by Google’s Maglev paper and Envoy.
- MAX_
CONFIG_ CONVERGENCE_ DRIFT_ CHECK_ MS - Validation ceiling on
gateway.config_convergence.drift_check_interval_ms(DW-054): five minutes is the longest an operator should go without a drift report (beyond that a divergent instance serves stale config for too long before anyone notices). - MAX_
CONFIG_ CONVERGENCE_ POLL_ MS - Validation ceiling on
gateway.config_convergence.poll_interval_ms(DW-054): one minute is the longest convergence lag an operator should tolerate (the done-when targets sub-second convergence; a poll this slow is a misconfiguration). - MAX_
DNS_ DISCOVERY_ REFRESH_ S - Validation ceiling on
upstreams[].dns_discovery.refresh_interval_s(DW-042): one hour is the longest an operator should go without noticing a stale endpoint set (beyond that the TTL-driven refresh is the better mechanism). - MAX_
FAULT_ ABORT_ STATUS - MAX_
FAULT_ DELAY_ MS - Validation bound on
routes[].fault_injection.delay.fixed_ms(DW-062): the maximum injectable delay. Above 5 minutes the upstream is almost certainly dead and a timeout or breaker is the right tool, not a fault-injection delay. - MAX_
HAPPY_ EYEBALLS_ MS - Validation bound for
upstreams[].timeouts.happy_eyeballs_ms(DW-030, 10 minutes — the slow-start bound’s twin rationale: a racing delay past this no longer races anything, it serializes dials behind a sleeper).0is legal and disables racing instead. - MAX_
HEDGE_ AFTER_ MS - MAX_
HEDGE_ COPIES - Validation bound on
retries.hedge.hedge_max(DW-063): at most this many speculative copies per request. Each copy consumes an endpoint slot and a retry-budget charge, so the cap bounds the amplification factor. - MAX_
HTTP2_ KEEP_ ALIVE_ INTERVAL_ MS - Validation ceiling on
upstreams[].pool.http2_keep_alive_interval_ms(DP-03): ten minutes is the longest PING interval worth configuring (beyond that an intervening proxy’s idle timeout fires first, defeating the keep-alive). - MAX_
HTTP2_ KEEP_ ALIVE_ TIMEOUT_ MS - Validation ceiling on
upstreams[].pool.http2_keep_alive_timeout_ms(DP-03): ten minutes is the longest a client should wait for a PING ACK before closing (beyond that the connection is effectively dead and a reconnect is the right tool). - MAX_
LICENSE_ GRACE_ PERIOD_ DAYS - Maximum configurable grace period (days) after license expiry
(DW-032).
gateway.license.grace_period_daysis validated to 0..=this. - MAX_
NONCE_ CACHE_ ENTRIES_ PER_ SHARD - Runtime bound on the replay-nonce entries the HMAC request-signing
nonce cache (DW-036,
security::authn) holds PER SHARD. Not a schema bound — a process-lifetime memory guarantee under nonce flood, exactly the GCRA cap’s rationale: entries expire after twice the clock-skew window anyway, and the cap only binds when an attacker floods nonces faster than expiry retires them (a fixed constant rather than an ops knob). - MAX_
OIDC_ INTROSPECTION_ CACHE_ TTL_ S - Validation ceiling on
gateway.oidc_providers[].introspection_cache_ttl_s(DW-034): one hour is the longest a cachedactive: trueintrospection should be trusted without re-checking (a revoked token would otherwise keep authenticating for an hour after revocation). - MAX_
POOL_ IDLE_ TIMEOUT_ MS - Validation ceiling on
upstreams[].pool.pool_idle_timeout_ms(DP-03): ten minutes is the longest an idle connection should linger before the pool reaps it (beyond that the upstream or an intervening proxy has almost certainly reaped it already, and a stale pooled connection is a p99 regression source). - MAX_
POOL_ MAX_ CONCURRENT_ STREAMS - Validation ceiling on
upstreams[].pool.max_concurrent_streams(DP-03): one million concurrent streams per connection is well above any real h2 peer’s advertised limit, so this only catches a typo. The floor is 1 (a zero-concurrency client can never send). - MAX_
POOL_ MAX_ IDLE_ PER_ HOST - Validation ceiling on
upstreams[].pool.pool_max_idle_per_host(DP-03): the per-host idle fraction of the per-upstreamconnection_cap. 1024 is well above any reasonable cap, so this only catches a typo (a mistyped config that would allocate an unbounded “bounded” idle set). - MAX_
RATE_ LIMITER_ KEYS_ PER_ SHARD - Runtime bound on the per-key GCRA state a rate-limiter window holds
PER SHARD of its keyed store (see
extensions::rate_limiter). Not a schema bound — no config value is checked against it — but a process-lifetime memory guarantee: an[ip]-selector limiter under key spray can hold at mostshards * thiskeys per window per rule, after which idlest-first eviction takes over (a deliberately fixed constant rather than an ops knob; revisit if operators need to tune). - MAX_
REDIS_ CONNECTION_ TIMEOUT_ MS - Validation ceiling on
gateway.redis_rate_limiter.connection_timeout_ms(DW-031): 30 seconds is the longest a startup connection should stall the gateway (beyond that the operator should fix their Redis, not widen the timeout). - MAX_
REDIS_ KEY_ TTL_ S - Validation ceiling on
gateway.redis_rate_limiter.key_ttl_s(DW-031): 7 days is the longest a stale rate-limit key should linger in Redis (beyond that the operator should lower it to keep Redis memory bounded under key spray). - MAX_
RETRY_ ATTEMPTS - Validation bound on
retries.attempts(mirrored insnapshot::validate). - MAX_
RETRY_ TOTAL_ DEADLINE_ MS - Validation ceiling on
retries.total_deadline_ms(REL-01): the cross-attempt wall-clock cap including backoff delays. Ten minutes is the longest a single request’s retry storm should extend tail latency (beyond that the per-upstream circuit breaker and timeouts are the right tool, not a wider retry deadline). Absent means unbounded (the v1 default, kept for backwards compatibility); a present0is rejected at validation (omit the field for unbounded). - MAX_
RING_ VNODES - Validation bound on total ip_hash ring size (
sum(weight) * 160). Keeps ring construction cheap and the BTreeMap small even for skewed weight sets. - MAX_
SLOW_ START_ MS - Validation bound for
upstreams[].slow_start_ms(10 minutes): the ramp window is per-endpoint-entry, and unbounded windows would keep recycled addresses permanently underweighted. - MAX_
STREAM_ BATCH_ RECORDS - Validation bound on
gateway.analytics_stream.batch_max(DW-121): records per flushed batch ceiling (with the byte cap, whichever comes first — the batch is the delivery unit, so this is also the per-delivery record-count bound). - MAX_
STREAM_ BUFFER - Validation bound on
gateway.analytics_stream.buffer(DW-121): the ceiling on records queued between the dataplane and the flusher. Every queued record is an owned copy of the access record, so the buffer is the firehose’s whole memory story — this bound keeps a mistyped config from allocating an unbounded “bounded” queue. - MAX_
STREAM_ FLUSH_ MS - Validation bound on
gateway.analytics_stream.flush_ms(DW-121): the batch-latency ceiling (one minute — the same shape as the webhook timeout ceiling: a batch older than this is a backlogged pipeline, not a tuning knob). - MAX_
WEBHOOK_ ATTEMPTS - Validation bound on
gateway.webhooks[].max_attempts(DW-044): deliveries retry at most this many times in total, so a dead target cannot occupy its delivery task (or the retry budget) indefinitely. - MAX_
WEBHOOK_ TIMEOUT_ MS - Validation bound on
gateway.webhooks[].timeout_ms(DW-044): one minute is the largest per-delivery budget worth waiting on an ALERT (the gateway is not a durable queue; anything slower should be an event sink, not a webhook). - MAX_
WEBSOCKET_ FRAMES_ PER_ SEC - Validation bound on
routes[].websocket.max_frames_per_sec(DW-039): one hundred thousand frames per second sustained is the most an operator should need to allow (a chatty app ticks far below it; above it the policing itself becomes the load). - MIN_
CONFIG_ CONVERGENCE_ DRIFT_ CHECK_ MS - Validation floor on
gateway.config_convergence.drift_check_interval_ms(DW-054): below one second the drift check would race the poll and report transient mid-convergence divergence as drift (noise). - MIN_
CONFIG_ CONVERGENCE_ POLL_ MS - Validation floor on
gateway.config_convergence.poll_interval_ms(DW-054): below 100 ms the convergence poll would hammer the backend faster than another instance can publish a generation, and the round-trip itself dominates the interval. - MIN_
DNS_ DISCOVERY_ REFRESH_ S - Validation floor on
upstreams[].dns_discovery.refresh_interval_s(DW-042): below 1 second the discovery task would re-resolve faster than DNS can meaningfully change, hammering the name server. - MIN_
FAULT_ ABORT_ STATUS - Validation bound on
routes[].fault_injection.abort.status(DW-062): the HTTP status range for abort injection. - MIN_
HEDGE_ AFTER_ MS - Validation bounds on
retries.hedge.hedge_after_ms(DW-063): the tail-latency threshold before a speculative copy is sent. Below 1 ms is pointless (the copy would race immediately); above 5 minutes the upstream is almost certainly dead and a retry or breaker is the right tool, not a hedge. - MIN_
OIDC_ INTROSPECTION_ CACHE_ TTL_ S - Validation floor on
gateway.oidc_providers[].introspection_cache_ttl_s(DW-034): below 1 second the introspection cache would expire before the next request can benefit, degenerating into a per-request IdP call (the cache exists precisely to avoid that). - MIN_
REDIS_ CONNECTION_ TIMEOUT_ MS - Validation floor on
gateway.redis_rate_limiter.connection_timeout_ms(DW-031): below 100 ms a connection attempt is too aggressive for a network round-trip (the timeout would fire before DNS resolution completes on many setups). - MIN_
REDIS_ KEY_ TTL_ S - Validation floor on
gateway.redis_rate_limiter.key_ttl_s(DW-031): below 1 second keys would expire before the GCRA bucket can refill for any non-trivial rate, making the limiter ineffective. - MIN_
STREAM_ BUFFER - Validation bound on
gateway.analytics_stream.buffer(DW-121): the firehose channel’s capacity floor. Below this a single flush tick of bursty traffic would spill into emit-time drops that no buffer tuning could have absorbed. - MIN_
STREAM_ FLUSH_ MS - Validation floor on
gateway.analytics_stream.flush_ms(DW-121): below 100 ms the flusher degenerates into per-record delivery, which the batch knob exists to prevent.