2,700
busy judge cores at the contest peak
80,000 people start a weekly contest in the same minute. Assume 6 Submits and 10 Runs each. That’s roughly 4× a normal evening, arriving in three minutes.
Where does the code run?
Bad: In the API process
One while (fork()); takes the API down.
Good: Store, queue, 202
Store it, queue the ID, return 202. Separate judge hosts pull jobs when a core is free.
Any submission can be a fork bomb. Build two walls.
A fresh microVM gives each submission its own kernel. Inside it, isolate cuts the network and caps memory, processes and output.
Same code, same tests: Accepted, then TLE.
On shared vCPUs, busy neighbours add noise. In one illustrative test, 8 of 20 runs crossed a 1 s limit; on a pinned core, none did.
Make every run repeatable
- Limit CPU time; wall time is only a guard
- One run per pinned physical core, SMT and turbo off
- Re-run near-misses and keep the minimum
- Publish language multipliers: Java 2×, Python 5×
At 8:00, 80,000 contestants start at once. Load jumps fourfold in three minutes; new hosts need minutes to boot.
The trick
Contests are scheduled. Thirty minutes early, boot the contest pool, warm images and prefetch tests.
One number ranks 80,000 contestants.
Solved, penalty and last accepted time pack into one Redis score. The scorer rebuilds a contestant’s row from stored verdicts and overwrites it, so replays and rejudges stay correct.
Remember
The web tier never runs code. Every run gets two sandbox walls and its own quiet core; contests get capacity before the crowd.