System design sample solution

System design: build a coding contest platform

A step-by-step system design answer you could actually give in 60 minutes.

System design interview · Sample 60-minute answer · Not Meta's actual design · Independent, not affiliated with Meta

The system design question

Design a coding contest platform like LeetCode's weekly contest. Thousands of people join a timed contest, submit code that's run against tests, and see a live leaderboard.

Agree on the scope (5 minutes)

Say up front what you're covering.

We'll designWe'll skip
Starting a contestWriting problems
Submitting and judging codeCheating detection
The live leaderboardRatings after the contest
Handling the rushPayments

Then agree on what "good" means:

  • Fair: everyone starts at the same time, and judging order doesn't change anyone's score.
  • Safe: people's code can't break our servers or see other people's code.
  • Quick results: most submissions should be judged within seconds.
  • Live leaderboard: the leaderboard should update within a few seconds.

Rough numbers (5 minutes)

Made up, but reasonable: 50,000 people, 4 problems, a 90-minute contest, and about 3 submissions each per problem.

600K
submissions per contest
~500
submissions per second in the final rush
~1,000
CPU cores busy judging at the peak
~5K
leaderboard requests per second
QuestionRough mathWhat it means
How much judging?500 a second × about 2 seconds of running eachAbout 1,000 cores at once, so judging is the expensive part
How busy is the leaderboard?50,000 people refreshing every 10 secondsAbout 5,000 reads a second
What happens at the start?50,000 people loading problems at onceA huge spike, but it's the same 4 pages for everyone

The overall design (10 minutes)

Participantsubmits codeSubmission servicesaves itJudge queuewaiting runsSandboxed runnersrun the testsResults, leaderboardscores
Submissions are saved and queued. Isolated runners judge them, and results update the leaderboard.
  1. Problems are hidden until the start, then served from a cache close to users.
  2. When someone submits, we save the code and put a 'judge this' message on a queue.
  3. Runners take submissions off the queue and run them against the tests, each in its own locked-down container.
  4. The result is saved and the participant is told.
  5. If it passed, the participant's score and leaderboard position are updated.

What the apps need to do

ActionWho does itWhat's sent
Register for a contestParticipantContest ID
Get problemsParticipantContest ID, once it's started
Submit codeParticipantProblem, language, code and a submission ID
Check a submissionParticipantSubmission ID, and we return its result
View the leaderboardAnyoneContest ID and a page, or 'around me'

What we store and where

DataWhere it goesWhy
Submissions and resultsRelational databaseThe permanent record of what happened
Waiting submissionsQueueLets judging catch up with bursts
LeaderboardSorted set in memoryFast to update and to read ranks
Problems and testsStorage, cached near usersSame for everyone, read constantly at the start

Step 1: Judging submissions (15 minutes)

Never run code in the web request. Save it, put a message on a queue, and return 'pending'. Runners pull from the queue, so when the end-of-contest rush hits, submissions just wait a bit longer and nothing falls over.

Every submission runs in its own container with no network access and strict limits on time, memory and CPU. Someone will try something nasty, and it shouldn't matter.

Score by submission time, not by when judging finishes, so a backed-up queue never costs anyone points.

Judging twice

If a runner crashes, its message goes back on the queue and another runner judges it again. Saving the result by submission ID means a repeat overwrites the same result instead of counting twice. That's idempotency.

Step 2: The live leaderboard (10 minutes)

Keep a sorted set in memory, like Redis, with each participant's score. Most contests rank by problems solved, then by total time with penalties, which you can combine into one number. Updating a score and finding someone's rank are both quick.

Most people look at the top of the board or their own spot. Cache the top pages for a few seconds, so thousands of refreshes are one read.

If the in-memory leaderboard is lost, rebuild it from the saved results.

Step 3: The rush at the start (5 minutes)

Have people register beforehand, so the start is just loading problems. Problems are the same for everyone, so serve them from a cache close to users the moment the clock starts.

Add judging capacity before the contest starts, not after the queue backs up. Rate limit submissions per person, say one every 10 seconds, so nobody floods the queue.

Choices you should be able to defend

We choseInstead ofBecauseWe'd reconsider if
A queue and runnersRunning code in the requestBursts wait instead of crashing thingsResults needed to be instant and traffic was steady
Scoring by submission timeScoring by when judging finishedA slow queue never costs anyone pointsWe had no reliable submission timestamps
An in-memory sorted setRanking with a database queryUpdates and rank look-ups are instantThe contest was small enough not to matter
ContainersFull virtual machinesThey start faster and use lessWe needed stronger isolation for some languages

What could go wrong (5 minutes)

What happensWhat we do about it
A runner dies mid-judgeThe message goes back on the queue and another runner judges it
The queue backs upShow 'pending' and add runners. Scores use submission time, so it's still fair
The leaderboard store is lostRebuild it from the saved results
Someone submits malicious codeIt's stuck in a locked-down container with no network and strict limits
A test case is wrongFix it and rejudge that problem's submissions from the queue

Follow-up questions (5 minutes)

How would you catch cheating?

After the contest, compare submissions for suspicious similarity and flag them for review.

How would you update ratings?

Once the final standings are locked, run a batch job that updates everyone's rating.

What about contests across the world?

Run runners in several regions, but keep one leaderboard as the source of truth.

How the 60 minutes add up

MinutesWhat you're doing
0–5Agree on what you're building
5–10Rough numbers
10–20Draw the overall design
20–35Judging submissions
35–45The live leaderboard
45–50The rush at the start
50–55What could go wrong
55–60Follow-up questions

Key concepts used here

Further reading

We wrote this sample answer ourselves.

Practice Loop is independent and isn't affiliated with or endorsed by Meta.