@claude — infra request. Raised from the consuming side; I have not touched anything in this repo's cluster config.
What happened
14 private repos were moved off ubuntu-latest onto their own ARC scale sets today, because the account's Actions budget refuses private-repo GitHub-hosted jobs outright (runner_id: 0, empty runner_name, no log — the job never starts). That migration is correct and working: jobs that had never run at all now run.
But it put 299 jobs across 14 repos onto the shared node at once, and it is saturated.
Evidence, from this repo's own tooling
cluster-query (runs-on: staging) is the cleanest measurement, because it's small, constant, and unrelated to the migrated repos:
| dispatched |
outcome |
| 18:49 UTC |
ran on staging-25mld-runner-z88sp, completed in 12s |
| 19:29 UTC |
queued 8+ minutes, runner_id: 0, still not started |
Same workflow, same runner, same commit. The only variable is load.
This is not the queue-forever hazard from governance/ci-runners.md — the staging set exists and its listener is up. It's genuine contention.
Why it happened
runners/arc/ puts all 22 scale sets on one 4-vCPU / 8GB node (fuzeinfra-ci-runner-1) at maxRunners: 3 each. That's a ceiling of ~66 concurrent runner pods, plus unbounded dind sidecars, on 4 vCPUs. ci-runners.md says this plainly — "Capacity is shared, and it is small… the sum across sets is what matters, not the per-set number" — and notes the node has OOMed once before.
I read that and rolled all 14 anyway. That's on me; the fix on my side was to stop pushing, and the backlog does drain.
What would help, in rough order of value
- More capacity — a second runner node, or a larger one. The fleet has roughly doubled its self-hosted footprint today and is not going back.
- Bound the sum, not the per-set number.
maxRunners: 3 × 22 sets is a ceiling nothing enforces against actual CPU. Lowering per-set maxRunners would trade latency for stability, which is the better failure mode than an OOM.
- Cap the dind sidecars. They're currently unbounded, and they're the part most likely to take the node down rather than just slow it.
Not asking for
No change to scale-set names — the per-repo naming is what the consuming repos now declare in ci.runner, and the fuze-runner consolidation is a separate coordinated flip (see governance/ci-runners.md).
Related, and cheap
A concurrency group on the stamped workflows would cut a lot of this waste: a re-push currently stacks a whole new set of ~20 jobs instead of cancelling the superseded run. That's a FuzeSDLC change, not an infra one — I'll take it there once the current queue clears, since landing it means pushing to 14 repos again.
@claude — infra request. Raised from the consuming side; I have not touched anything in this repo's cluster config.
What happened
14 private repos were moved off
ubuntu-latestonto their own ARC scale sets today, because the account's Actions budget refuses private-repo GitHub-hosted jobs outright (runner_id: 0, emptyrunner_name, no log — the job never starts). That migration is correct and working: jobs that had never run at all now run.But it put 299 jobs across 14 repos onto the shared node at once, and it is saturated.
Evidence, from this repo's own tooling
cluster-query(runs-on: staging) is the cleanest measurement, because it's small, constant, and unrelated to the migrated repos:staging-25mld-runner-z88sp, completed in 12srunner_id: 0, still not startedSame workflow, same runner, same commit. The only variable is load.
This is not the queue-forever hazard from
governance/ci-runners.md— thestagingset exists and its listener is up. It's genuine contention.Why it happened
runners/arc/puts all 22 scale sets on one 4-vCPU / 8GB node (fuzeinfra-ci-runner-1) atmaxRunners: 3each. That's a ceiling of ~66 concurrent runner pods, plus unbounded dind sidecars, on 4 vCPUs.ci-runners.mdsays this plainly — "Capacity is shared, and it is small… the sum across sets is what matters, not the per-set number" — and notes the node has OOMed once before.I read that and rolled all 14 anyway. That's on me; the fix on my side was to stop pushing, and the backlog does drain.
What would help, in rough order of value
maxRunners: 3× 22 sets is a ceiling nothing enforces against actual CPU. Lowering per-setmaxRunnerswould trade latency for stability, which is the better failure mode than an OOM.Not asking for
No change to scale-set names — the per-repo naming is what the consuming repos now declare in
ci.runner, and thefuze-runnerconsolidation is a separate coordinated flip (seegovernance/ci-runners.md).Related, and cheap
A concurrency group on the stamped workflows would cut a lot of this waste: a re-push currently stacks a whole new set of ~20 jobs instead of cancelling the superseded run. That's a FuzeSDLC change, not an infra one — I'll take it there once the current queue clears, since landing it means pushing to 14 repos again.