Config push vs poll: load test

PR #4320 (config_delivery_mode = "push") · one gateway, Docker driver, Postgres · 250 sandboxes · October 2026 · tested at d74015e8c (45fc53a10 after the rebase onto main)

83 ms vs 4.1 s
Policy update to one sandbox, worst of 10
930 ms vs 9.9 s
Global setting reaches all 250 sandboxes (p99)
1.5 s vs 10.0 s
Global policy reaches all 250 sandboxes (p99)
18% vs 22%
Idle gateway CPU with 250 sandboxes (push vs poll)

Every scenario converged on 100% of the targeted sandboxes in both modes, and in-sandbox checks (allow/deny flips, injected credentials, environment placeholders) matched the new configuration every time.

How we tested

p99 propagation latency

pushpolllog scale
100 ms 1.0 s 10 s poll interval Policy update (incremental rule) push p99 83 ms 83 ms poll p99 4.1 s 4.1 s Draft rule approval push p99 285 ms 285 ms poll p99 10 s 10 s Full policy replace push p99 1.6 s 1.6 s poll p99 12 s 12 s Sandbox setting set push p99 368 ms 368 ms poll p99 10 s 10 s Provider attach push p99 1.3 s 1.3 s poll p99 12 s 12 s Provider detach push p99 972 ms 972 ms poll p99 12 s 12 s Global policy set push p99 1.5 s 1.5 s poll p99 10.0 s 10.0 s Global policy delete push p99 3.6 s 3.6 s poll p99 10 s 10 s Global setting set push p99 930 ms 930 ms poll p99 9.9 s 9.9 s Global setting delete push p99 892 ms 892 ms poll p99 10.0 s 10.0 s Provider credential rotation push p99 3.8 s 3.8 s poll p99 10 s 10 s Provider profile update push p99 1.7 s 1.7 s poll p99 10 s 10 s Change while 10% of supervisors are stopped push p99 940 ms 940 ms poll p99 9.9 s 9.9 s Catch-up after stopped supervisors resume push p99 3.1 s 3.1 s poll p99 12 s 12 s

All scenarios

ChangeScopePush p50Push p99Poll p50Poll p99p99 speed-up
One sandbox
Policy update (incremental rule)
p50 and max of the 10 updates
1 sandbox, 10 sequential updates54 ms83 ms3.5 s4.1 s49.6×
Draft rule approval20 sandboxes, one approval each229 ms285 ms8.3 s10 s35.2×
Every sandbox, one command each
Full policy replace250 commands, 16 in parallel1.1 s1.6 s5.8 s12 s7.7×
Sandbox setting set250 commands260 ms368 ms4.6 s10 s27.5×
Provider attach250 commands1.0 s1.3 s6.5 s12 s8.9×
Provider detach250 commands749 ms972 ms5.7 s12 s12.3×
Fleet-wide, one command
Global policy set250 sandboxes1.1 s1.5 s5.0 s10.0 s6.5×
Global policy delete250 sandboxes3.1 s3.6 s5.1 s10 s2.9×
Global setting set250 sandboxes357 ms930 ms6.1 s9.9 s10.7×
Global setting delete250 sandboxes479 ms892 ms4.9 s10.0 s11.2×
Provider credential rotation
median of 3 rotations
250 attached sandboxes3.2 s3.8 s5.1 s10 s2.7×
Provider profile update250 sandboxes (workspace)1.3 s1.7 s4.8 s10 s6.0×
Faults
Change while 10% of supervisors are stopped225 running sandboxes559 ms940 ms5.9 s9.9 s10.6×
Catch-up after stopped supervisors resume
measured from resume
stopped supervisors that survived1.7 s3.1 s11 s12 s3.9×

For the "one command each" rows, latency is measured from each sandbox's own command, so it excludes the time to issue all 250 commands.

Idle cost, 250 sandboxes

Gateway CPUGateway RSSgRPC requests/sConfig work
Push18.0%1190 MB508.3 reconcile builds/s
Poll21.9%1213 MB7525 polls/s

Push replaces 25 config polls per second with a 30-second per-session reconcile (about 8 builds/s at 250 sandboxes, a few milliseconds each). The remaining 50 requests/s in both modes are provider readiness reports, one every 5 seconds per sandbox. Moving them onto the supervisor session is a follow-up.

Tuning and follow-ups

Push latency at this scale is set by how fast the gateway builds snapshots, not by the network. A change that rebuilds only the sandbox configuration reaches all 250 sandboxes in 930 ms; a change that also rebuilds every provider environment takes 1.5 s–1.7 s; a credential rotation, which also resolves credentials for every sandbox, takes 3.9 s. These can be improved in follow-ups or by tuning:

Not covered here