Module limits

Module limits 

Source
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). 0 is 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_days is 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 cached active: true introspection 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-upstream connection_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 most shards * this keys 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 in snapshot::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 present 0 is 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.