Config push vs poll: everyday use

PR #4320 (config_delivery_mode = "push") at 88f81d812 · one gateway, Docker driver, Postgres, 250 sandboxes, plus a 100-sandbox kind cluster with 2–3 gateway replicas · October 2026

99 ms vs 9.6 s
Policy edit to one sandbox (p99)
125 ms vs 9.8 s
Changes at 1/s across the fleet (p99)
1.5 s vs 10 s
Global policy reaches all 250 sandboxes (p99)
18% vs 22%
Idle gateway CPU, 250 sandboxes

Every change reached every targeted sandbox in both modes, and the in-sandbox checks matched the new configuration.

What changed since the last report

How we tested

Apply latency, p99

pushpolllog scale
10 ms 100 ms 1.0 s 10 s poll interval Policy edit push p99 99 ms 99 ms poll p99 9.6 s 9.6 s Sandbox setting push p99 117 ms 117 ms poll p99 9.0 s 9.0 s Draft rule approval push p99 135 ms 135 ms poll p99 9.9 s 9.9 s Provider attach push p99 114 ms 114 ms poll p99 9.6 s 9.6 s Provider detach push p99 98 ms 98 ms poll p99 9.7 s 9.7 s Mixed changes at 1/s push p99 125 ms 125 ms poll p99 9.8 s 9.8 s Global policy change push p99 1.5 s 1.5 s poll p99 10 s 10 s Global policy revert push p99 1.5 s 1.5 s poll p99 7.8 s 7.8 s Credential rotation push p99 1.6 s 1.6 s poll p99 7.7 s 7.7 s Edit after a graceful gateway restart push p99 95 ms 95 ms poll p99 9.9 s 9.9 s Global change after a graceful gateway restart push p99 1.6 s 1.6 s poll p99 9.9 s 9.9 s Catch-up after a 20 s supervisor stall push p99 862 ms 862 ms poll p99 10 s 10 s

All change scenarios

ChangeScopePush p50Push p99Poll p50Poll p99p99 speed-upConverged push · poll
One change at a time
Policy edit20 sandboxes, one edit each, 3 s apart60 ms99 ms5.6 s9.6 s96.7×20/20 · 20/20
Sandbox setting20 sandboxes49 ms117 ms5.0 s9.0 s76.8×20/20 · 20/20
Draft rule approval20 sandboxes74 ms135 ms6.4 s9.9 s73.7×20/20 · 20/20
Provider attach20 sandboxes71 ms114 ms5.3 s9.6 s84.5×20/20 · 20/20
Provider detach20 sandboxes58 ms98 ms5.7 s9.7 s99.8×20/20 · 20/20
Steady activity
Mixed changes at 1/s
70% policy edits, 30% settings
160 changes, each to a different sandbox54 ms125 ms5.6 s9.8 s78.2×160/160 · 160/160
Occasional fleet-wide change
Global policy changeevery sandbox674 ms1.5 s6.5 s10 s6.7×250/250 · 250/250
Global policy revertevery sandbox903 ms1.5 s4.2 s7.8 s5.1×250/250 · 250/250
Credential rotation
median of 3 rotations
provider every sandbox attaches747 ms1.6 s3.0 s7.7 s4.7×250/250 · 250/250
Sandbox lifecycle
Edit after a graceful gateway restart20 sandboxes53 ms95 ms4.9 s9.9 s104.1×20/20 · 20/20
Global change after a graceful gateway restartevery sandbox1.1 s1.6 s4.9 s9.9 s6.1×250/250 · 250/250
Fault
Catch-up after a 20 s supervisor stall
edited while stalled
10 sandboxes, measured from resume335 ms862 ms606 ms10 s12.0×10/10 · 10/10

Sandbox lifecycle

PushPush checkPollPoll check
Start a stopped sandbox, with a policy edit made while stopped
start to Ready, p50 / max
3.2 s / 4.7 s10/104.0 s / 5.4 s10/10
Replace a sandbox: delete one, create its replacement
create to Ready, p50 / max
3.1 s / 5.1 s10/103.3 s / 6.0 s10/10
Graceful gateway restart
every sandbox Ready / every session back, after the gateway started
316 s / 316 s250/250319 s / 319 s250/250

Starting, replacing and restarting take the same time in both modes, because supervisors start by polling in both. Push only changes what happens once the session is up. A graceful gateway restart on Docker stops every sandbox and resumes them one at a time, so the fleet is back after about five minutes in both modes. Changes made right after the restart arrive as fast as before it.

Gateway replicas coming and going (Kubernetes)

A kind cluster on the same host with 100 sandboxes and a gateway Deployment that starts with 2 replicas. Changes go through a NodePort, so most of them land on a replica that does not own the sandbox's session and reach the owner through peer notification. Scaling out does not move established sessions, so a new replica starts with none and forwards the changes it receives. Sessions on a replica that stops or is lost reconnect to the others.

ChangePush p50Push p99Poll p50Poll p99p99 speed-upConverged push · poll
Policy edit, one at a time
20 sandboxes, through a random replica
23 ms31 ms6.1 s8.9 s288.0×20/20 · 20/20
Steady activity at 1/s
40 changes
20 ms29 ms3.5 s9.9 s335.8×40/40 · 40/40
Global policy change
every sandbox
58 ms141 ms5.1 s9.8 s69.5×100/100 · 100/100
Credential rotation
median of 3
53 ms121 ms5.2 s9.4 s77.5×100/100 · 100/100
Edits while scaling 2 → 3 replicas
one edit per second, from the scale-up until 30 s after it (at least 60 s)
19 ms31 ms6.0 s9.8 s315.6×60/60 · 60/60
Edits during a rolling restart
one edit per second, from the restart until 30 s after it (at least 60 s) · CLI errors 2 / 1
21 ms30 ms4.7 s9.6 s319.0×58/58 · 59/59
Edits after losing one replica
20 sandboxes, right after the force-delete
27 ms40 ms6.6 s9.6 s241.0×20/20 · 20/20
Edits while scaling 3 → 2 replicas
one edit per second, from the scale-down until 30 s after it (at least 60 s)
20 ms28 ms4.8 s9.5 s335.7×60/60 · 60/60
Global change after scaling 2 → 3
every sandbox
58 ms146 ms5.5 s9.8 s67.3×100/100 · 100/100
Global change after a rolling restart
every sandbox
37 ms118 ms4.7 s10.0 s84.8×100/100 · 100/100
Global change after losing one replica
every sandbox
58 ms135 ms4.7 s10.0 s73.5×100/100 · 100/100
Global change after scaling 3 → 2
every sandbox
59 ms162 ms5.6 s9.9 s61.0×100/100 · 100/100
Replica changePush: tookPush: sessions per replica afterPoll: tookPoll: sessions per replica after
Scale 2 → 32.8 s58 / 42 / 02.7 s55 / 45 / 0
Rolling restart9.1 s44 / 31 / 259.1 s44 / 42 / 14
Scale 3 → 2115 ms52 / 4897 ms59 / 41
Force-delete one replica44 sessions moved in 611 ms44 sessions moved in 582 ms

Idle cost, 250 sandboxes

Gateway CPUGateway RSSgRPC requests/sConfig work
Push18.0%1262 MB508.3 reconcile builds/s
Poll21.7%1257 MB7525 config polls/s

Observations

Not covered here