ASG MaxSize is 4, but the app cannot run on more than one instance
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- Half a day
- Newbie friendliness
- 25/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- aws, node.js, typescript
Research direction
The mismatch is in the autoscaling configuration (aws:autoscaling:asg MaxSize, set alongside the CPU trigger from #376) and in the app's per-process state in EnvironmentService, which holds arenas in a Map. Check the ladder loop started from index.ts when LADDER_ENABLED=true. Done means MaxSize is set to 1 with the rationale recorded, but the longer-term architecture work is out of scope for a first contribution.
Written by the indexing model from the issue text.
Description
Noticed on 2026-10-10 during the RDS memory investigation.
The setup contradicts itself
aws:autoscaling:asg → MaxSize: 4, with the scale-up trigger at CPUUtilization > 75% sustained 10 minutes (aws:autoscaling:trigger, set by #376).
But the app is not horizontally scalable:
- Arena state is per-process and in memory.
EnvironmentServiceholds aMap<arenaId, Environment>in the Node process. A second instance cannot see the first's arenas, so a request routed there finds a different world. - SSE connections are pinned. An established
/arena/eventsor/arena/logsstream stays on the instance that accepted it and cannot be relieved by adding more. - The ladder loop runs on every instance.
index.tsstarts it wheneverLADDER_ENABLED=true, so N instances means N independent matchmakers writing ratings to the sameapprows — concurrent, unsynchronised Elo updates.
A scale-out therefore does not add capacity; it forks the live state and multiplies the background load on the shared database.
How close it is
Measured over 24 h on 2026-10-10: CPU averaged 38–42% with 5-minute maxima of 64–66%, against a 75% trigger. That is one busy afternoon away.
#406's saturation cap should drop steady-state CPU to the ~20% ladder-idle baseline, which makes a breach much less likely — but it does not make a breach safe, and the ceiling is still 4.
Suggested fix
Short term: set MaxSize: 1. The trigger can stay; there is simply nowhere to scale to. This is the honest configuration for the current architecture and removes the failure mode outright.
Longer term, if scaling out is ever wanted, it needs at least:
- a single-leader election (or a dedicated worker) for the ladder loop, so only one instance matchmakes
- shared or sticky arena ownership, so an arena lives in one known place
- the simulation state moved out of process, or arenas sharded by instance with routing
That is a real project, not a config change — hence the short-term fix.
Related
- #376 replaced the (wrong)
NetworkOuttrigger with CPU, which fixed spurious scale-outs but left the ceiling at 4. - #143 (de-duplicate the simulation math) and #144 (multi-arena tooling) are adjacent but do not address this.
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 0
- Avg merge
- 8m
- Merged PRs (30d)
- 8
Getting set up
Starts the project's dev container in your browser, under your own GitHub account.
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from LeeAdcock/robocodeJs.com
-
priority: medium tech-debt
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
LeeAdcock/robocodeJs.com#411 ·
Maintainers usually reply within 1 day
-
enhancement priority: medium
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
LeeAdcock/robocodeJs.com#254 ·
Maintainers usually reply within 1 day
-
good first issue priority: low tech-debt
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
LeeAdcock/robocodeJs.com#146 ·
Maintainers usually reply within 1 day
-
dependencies priority: low tech-debt
Difficulty 1/5 Under an hour Newbie friendliness 15/100
LeeAdcock/robocodeJs.com#413 ·
Maintainers usually reply within 1 day
-
priority: low tech-debt
Difficulty 3/5 Half a day Newbie friendliness 32/100
LeeAdcock/robocodeJs.com#412 ·
Maintainers usually reply within 1 day
All issues in LeeAdcock/robocodeJs.com
Similar issues
-
useFragment does not require `variables` when the fragment's variables type has required fieldsOpen
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
apollographql/apollo-client#13493 ·
Maintainers usually reply within 1 day
-
Custom hosts written as trailing-dot FQDNs (`host.local.`) aren't detected as local backendsPossibly taken @roboomp claimed this today. Openbug prio:p2 providers triaged
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
can1357/oh-my-pi#15798 · 3 comments ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
code-yeongyu/oh-my-openagent#10172 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
PDFCraftTool/pdfcraft#189 ·
-
Add the Yahoo chart API duplicate last-day row (yfinance#573) to incidents.md (about 1 hour)Possibly taken A pull request linked to this issue is open or already merged. Opendata docs good first issue
Difficulty 1/5 Under an hour Newbie friendliness 80/100
pacocartones/market-data-sanity-checker#160 ·
Maintainers usually reply within 1 day