Gessa Docs
Product · Reference

Reference

Reference: Backpressure and Degradation

The runtime overload surfaces, invariants, and pinned numbers - the backpressure summary, the per-room and per-shard degradation ladders, the state-stream governor, the slow-consumer machine, and the capacity floor - each bound to a symbol and a proving test.
engine v1.0.234since v1Copy for LLM
engine v1.0.232

Last verified 2026-09-05 against engine v1.0.232.

Overload is the runtime's answer to being asked for more than a process can afford: a burst of author state, a client that will not drain its socket, more rooms than one instance should host. The response is server-owned graceful degradation, a fixed order in which cheap-to-lose work is shed first and a room is refused or stopped last. This page enumerates the overload surfaces, the invariants and the conformance test that holds each, the constants with the receipt that pins them, the typed error codes, the proof surfaces, and the limits (which rungs are wired into a live actuator and which are declared but inert). For the model behind these values, read the Overload and Degradation Model; this page states the values, that page states the why. For the wider runtime this sits inside, read the Netcode Contract reference.

Source of truth

This subsystem has no single generated file. Its source of truth is the runtime code in server/src/modules/runtime plus the fixture-hash test server/tests/runtimeNetcodeContractFixtureHash.test.ts, which pins the overload constants by value. The typed error codes a shed effect surfaces under are the exception: they are generated into the runtime error registry and this page links down to it.

The mechanisms live in backpressure.ts (the summary and both ladders), streamBudget.ts (the ingress governor), shard/shardCapacityPolicy.ts (the capacity floor), runtimePolicies.ts (the slow-consumer, load-test, and state-stream policy constants), replicationTransport.ts (the slow-consumer machine), and roomActor.ts (the live ingress admission path), all under server/src/modules/runtime.

Surfaces

KindSurfaceSymbol and file
functionBackpressure summarysummarizeRuntimeBackpressure in backpressure.ts
enumWire classificationbackpressureState (none, watch, throttling, shedding) in packages/protocol/src/index.ts
constantPer-room ladderRUNTIME_LOAD_DEGRADATION_ORDER in backpressure.ts
constantPer-shard ladderRUNTIME_SHARD_LOAD_DEGRADATION_ORDER in backpressure.ts
functionPer-shard verdictevaluateShardDegradation in backpressure.ts
classState-stream governorRuntimeStateStreamBudget in streamBudget.ts
functionSlow-consumer stageslowConsumerStage in replicationTransport.ts
functionPlacement verdictevaluateRoomPlacement in shard/shardCapacityPolicy.ts
functionPlacement enforcementassertRoomPlacementWithinBudget in shard/shardCapacityPolicy.ts
constantCapacity capsRUNTIME_SHARD_CAPACITY_POLICY in shard/shardCapacityPolicy.ts
constantDurability kneeRUNTIME_LOAD_TEST_POLICY in runtimePolicies.ts
constantSlow-consumer bytesRUNTIME_SLOW_CONSUMER_POLICY in runtimePolicies.ts

Backpressure summary

summarizeRuntimeBackpressure classifies a room's replication health from two independent signals and reduces them to one backpressureState. The first signal is acknowledgement lag: for each connected-or-degraded connection, how far the server's latest sequence has run ahead of what the client last acknowledged.

ackLag(c)=max(0,latestServerSeq-c.lastAckedServerSeq)

The summary reads the maximum and the p95 of that lag and trips the highest of the three thresholds ACK_LAG_WATCH, ACK_LAG_THROTTLING, and ACK_LAG_SHEDDING, or escalates from the count of connections already flagged degraded (greater than zero is throttling; greater than max(4, active / 2) is shedding). The second signal is gateway pressure, reconstructed from each connection's metadata.gatewayPressure, which the routes layer writes on an envelope-too-large or command-over-budget rejection. The two are combined by rank, worst wins:

state=maxrank(ackLagState,degradedCountState,gatewayPressureState),none<watch<throttling<shedding

The classification is observational: it labels a room so operators and clients can read the strain, and it drives no shed on its own path. The shedding is performed by the mechanisms below.

The per-room ladder

RUNTIME_LOAD_DEGRADATION_ORDER is the fixed per-room shed order. Its rungs, by increasing severity, are downsample_or_drop_state_streams, drop_low_priority_replication, reject_room_commands, evict_slow_consumers, and mark_room_unhealthy. The array is a declaration, not a dispatcher: it performs no action itself, and each rung is realized by a separate module.

Rung actionRealized by
downsample_or_drop_state_streamsRuntimeStateStreamBudget in streamBudget.ts
drop_low_priority_replicationslowConsumerStage throttle in replicationTransport.ts
reject_room_commandsthe room-scope command shed in routes.ts (runtime_room_pressure_shedding)
evict_slow_consumersslowConsumerStage evict in replicationTransport.ts
mark_room_unhealthythe tick fuse failureLimitForRoom in tickScheduler.ts

The per-shard ladder

RUNTIME_SHARD_LOAD_DEGRADATION_ORDER is meant to compose above the per-room ladder when rooms run on worker-thread shards. Its rungs, by increasing severity, are thin_snapshots, reduce_snapshot_rate, pause_non_essential_lanes, refuse_joins, and migrate_or_close; each carries a stable action, a typed error code, and an operator-facing trigger. The selector evaluateShardDegradation is a pure function of a shard's signals { tickP99Ms, frameBudgetMs, ringOccupancyRatio, roomCount, roomCapacity } that returns the single highest active rung, walked from calm upward. The thresholds are budget-relative, so the ladder holds at any tick rate:

tickRatio=tickP99Msmax(1,frameBudgetMs)
rung={5tickRatio≥2∨ring≥14tickRatio≥1.5∨ring≥0.95∨roomCount≥roomCapacity3tickRatio≥1.25∨ring≥0.852tickRatio≥1∨ring≥0.71tickRatio≥0.8∨ring≥0.50otherwise

The two top rungs set refusesJoins (the verdict's order at or above four), and reaching the room cap alone (roomCount at or above roomCapacity) refuses joins even with a calm tick loop. The literals in that piecewise definition are the source of truth in evaluateShardDegradation itself; the ladder's conformance test proves the rung order and the typed code each rung emits, not that any interior threshold is drift-protected (see Proof surfaces).

The state-stream governor

Author-driven state streams pass RuntimeStateStreamBudget before admission. A sample runs a chain of sliding one-second windows over four scopes in order: per-stream rate, per-stream bytes, per-player aggregate bytes, and per-room aggregate bytes. The first scope it would exceed rejects it with a typed reason (rate_exceeded, byte_budget_exceeded, player_byte_budget_exceeded, or room_byte_budget_exceeded), a retryAfterMs, and a specific hint: a rate rejection hints drop_next, a byte or aggregate rejection hints downsample. An accepted sample whose utilization has reached DEGRADE_RATIO still carries a downsample hint, so a well-behaved client backs off before it starts losing samples. Ahead of the budget, on the same ingest path (admitStreamSampleInMemory in roomActor.ts), a per-player distinct-stream cap, enforcePlayerStreamStateLimit, bounds how many streams one player may open so the rate and byte windows never police an unbounded fan-out.

The window length WINDOW_MS and the DEGRADE_RATIO are the two governor constants exercised by netcode-state-stream-phase9.test.ts. The four scope budgets themselves are carried by RUNTIME_STATE_STREAM_POLICY in runtimePolicies.ts and surfaced in the Netcode Contract reference; no test value-pins them, so they are recorded in the dossier's Unverified list rather than stated here.

The slow-consumer machine

Replication is unreliable by design, but a client that stops draining its socket still costs the server memory. Per outbound socket, slowConsumerStage in replicationTransport.ts maps the socket's bufferedAmount through the byte ladder in RUNTIME_SLOW_CONSUMER_POLICY to a watch, throttle, or evict stage, and the stage is latched (via slowConsumerStageRank) so it can only rise. Under throttle, only a low-priority (replication) frame is dropped, with reason backpressure_throttle; higher-priority frames still go out. Under evict, the subscriber is detached with WebSocket close code 1008. These two stages are the live realizations of the per-room ladder's drop_low_priority_replication and evict_slow_consumers rungs.

The capacity floor

Before a room joins the tick loop, evaluateRoomPlacement checks the placement against RUNTIME_SHARD_CAPACITY_POLICY and returns admit or a typed refusal naming the first breached scope; assertRoomPlacementWithinBudget throws that refusal (runtime_shard_over_budget, category capacity) so an over-budget room never starts ticking. Instance scopes are always checked; shard scopes are checked only when the placement is sharded. The live enforcement site is assertRoomPlacementWithinInstanceBudget in service.ts, reached from ensureLocalRoomTickAuthority before tickScheduler.ensureRoom, and it places with the unsharded flag, so in production only the per-instance scopes are consulted. The sharded site placeRoom in shard/shardHost.ts places with the sharded flag but runs only under the test harness, since ShardHost is instantiated only in tests.

The durability knee RUNTIME_LOAD_TEST_POLICY records the room and player counts a single loop was validated to sustain. It is a load-test guardrail, consumed only by loadTestRunner.ts (which throws when a plan exceeds it), not a production admission gate, and its room knee sits below the enforced per-instance room cap.

Typed error codes

The client-visible codes a shed effect surfaces under are generated into the runtime error registry.

CodeWhere it firesLive
runtime_room_pressure_sheddingroom-scope command shed in routes.ts (realizes per-room rung three)yes
backpressure_throttleslow-consumer throttle drop reason in replicationTransport.tsyes
runtime_shard_over_budgetover-budget placement refusal in shard/shardCapacityPolicy.ts; also shard rung fourplacement path yes; shard rung inert
runtime_shard_sheddingshard rungs one to three in backpressure.tsinert (no actuator)
game_server_restartingroom-lifecycle not-ready path in runtimeGatewayErrors.ts; also shard rung fivelifecycle path yes; shard rung inert
ReferenceRuntime error registryResolved signature, schema and example

Numbers

Each value names its constant or function (the source of truth) and the test or check that pins it. Provisional values carry the code's own provisional qualifier and must never be quoted as a tuned service level.

ValueConstant or functionReceipt
ack-lag thresholds 8 / 32 / 128 (sequence)ACK_LAG_WATCH, ACK_LAG_THROTTLING, ACK_LAG_SHEDDING in backpressure.tsruntimeNetcodeContractFixtureHash.test.ts
slow-consumer bytes 1 / 4 / 16 MiBRUNTIME_SLOW_CONSUMER_POLICY in runtimePolicies.tsruntimeNetcodeContractFixtureHash.test.ts
capacity caps 200 / 2000 per instance; 32 / 320 per shard (provisional)RUNTIME_SHARD_CAPACITY_POLICY in shard/shardCapacityPolicy.tsruntimeNetcodeContractFixtureHash.test.ts
durability knee 128 rooms / 1024 playersRUNTIME_LOAD_TEST_POLICY in runtimePolicies.tsruntimeNetcodeContractFixtureHash.test.ts (constant pinned; gates only load-test plans)
state-stream degrade ratio 0.8DEGRADE_RATIO in streamBudget.tsnetcode-state-stream-phase9.test.ts (behavioral)
state-stream window 1000 msWINDOW_MS in streamBudget.tsnetcode-state-stream-phase9.test.ts (behavioral)
shard tick ratios 0.8 / 1.0 / 1.25 / 1.5 / 2.0 (rungs one to five)evaluateShardDegradation in backpressure.tsshardPlacementCapacityLadder.test.ts (order and typed code; interior literals not drift-gated)
shard ring ratios 0.5 / 0.7 / 0.85 / 0.95 / 1.0 (rungs one to five)evaluateShardDegradation in backpressure.tsshardPlacementCapacityLadder.test.ts (order and typed code; exact equality asserted only at ring at or above 1.0)
tick fuse default 3RUNTIME_DEFAULT_RUNTIME_BUDGET.tickFailureMaxConsecutive in runtimePolicies.tsruntimeRuntimePolicies.test.ts
Free-tier capacity 10 players / 20 Hz / 1 room (provisional; higher tiers pending)docs/spec/RUNTIME_CAPACITY_TIER_MATRIX.mdrun 2026-06-02T21-49-rssfix-final12h

Invariants

InvariantProved by
The per-room shed order equals the pinned sequence downsample-streams, drop-low-priority-replication, reject-commands, evict-slow-consumers, mark-unhealthy.netcode-load-hardening.test.ts
The per-shard ladder is ordered, typed, and severity-dominant: rising tick-p99 walks it emitting the correct action and code, ring occupancy drives it independently, the room cap alone refuses joins, the highest active rung wins, and identical signals give an identical verdict.shardPlacementCapacityLadder.test.ts
The state-stream scopes are isolated and deterministically hinted: each rejection surfaces its own reason, a rate rejection hints drop_next and byte and aggregate rejections hint downsample, an accept at or above the degrade ratio still hints downsample, and command and stream budgets stay isolated under floods.netcode-state-stream-phase9.test.ts
Placement refuses before joining the tick loop: an over-budget placement throws runtime_shard_over_budget (category capacity) and the room never joins, while an idempotent re-ensure excludes the room itself from the census.runtimeLocalTickAuthorityCapacity.test.ts
The overload constants are drift-gated by value (ack thresholds, slow-consumer bytes, shard caps with the provisional flag, and the durability knee) and the netcode contract emits a stable fixture hash.runtimeNetcodeContractFixtureHash.test.ts
The tick fuse consecutive-failure limit defaults to three, takes a per-room override, and a run that reaches it is stopped.runtimeRuntimePolicies.test.ts and runtimeTickScheduler.test.ts

Limits and non-features

  • The per-shard degradation ladder is not wired into a production actuator. evaluateShardDegradation has no server/src caller, and the shard host collects load signals through requestGovernor in shard/shardHost.ts but nothing evaluates them into a live shed action.
  • The live tick-authority path is unsharded. assertRoomPlacementWithinInstanceBudget in service.ts places with the unsharded flag, so the per-shard scopes are never consulted in production, and ShardHost (the only sharded placeRoom caller) is instantiated only in tests.
  • The capacity caps are provisional placeholders, not measured service levels. provisional: true on RUNTIME_SHARD_CAPACITY_POLICY is load-bearing; at the generous defaults admission does not refuse in normal production.
  • The per-room ladder is a declaration, not a dispatcher. RUNTIME_LOAD_DEGRADATION_ORDER performs no action; its rungs are realized by separate modules.
  • The backpressure summary is observational. summarizeRuntimeBackpressure classifies a room and drives no shed on its own path.
  • The durability knee gates only load-test plans. RUNTIME_LOAD_TEST_POLICY is consumed by loadTestRunner.ts, not by live admission, and its room knee sits below the enforced per-instance cap, so production admission can exceed the durability-validated knee.
  • Only the Free capacity tier is benchmark-validated. The Pro, Premium, and Enterprise rows of RUNTIME_CAPACITY_TIER_MATRIX.md remain evidence-gated.

Proof surfaces

The guarantees are held by tests and static gates, not by prose.

  • Per-room order: server/tests/netcode-load-hardening.test.ts pins the RUNTIME_LOAD_DEGRADATION_ORDER action sequence.
  • Per-shard ladder: server/tests/shard/shardPlacementCapacityLadder.test.ts drives evaluateShardDegradation up a bracketing ramp and asserts the rung order and the typed code each rung emits. It brackets the interior tick and ring thresholds rather than pinning them exactly (it asserts exact equality only at ring at or above 1.0 and at roomCount at or above roomCapacity), so a downward drift of an interior literal would still pass. The function is the source of truth for those literals; the test proves order and code, not exact-value protection.
  • State-stream scopes: server/tests/netcode-state-stream-phase9.test.ts proves each scope's isolated reason and hint, the accept-with-downsample behavior at the degrade ratio, and command-versus-stream budget isolation under floods.
  • Placement refusal: server/tests/runtimeLocalTickAuthorityCapacity.test.ts proves an over-budget room never joins the tick loop and the refusal carries category capacity.
  • Constant drift gate: server/tests/runtimeNetcodeContractFixtureHash.test.ts asserts by value the ack thresholds, the slow-consumer bytes, the shard caps with provisional, and the durability knee, and pins the resolved netcode-contract hash.

Where the model lives

This page states the values. For the model behind them, read the Overload and Degradation Model. For the room clock, authority, replication lanes, durability, and rejoin that this overload response sits inside, read the Netcode Contract reference and the Netcode Model. The player-safe copy for each overload code is in the generated runtime error registry.

Was this helpful?Report an issueContact support

On this page