</> MAANG.io
system design · 301

Advanced

Master system design interviews with scalable architecture patterns, distributed systems, and real-world design challenges.

0/480 solved 0% complete

Section 6: Fewer Boxes Than You Expected - High-Level Architecture

Executive Summary: With the API and the split data model settled, the interviewer asks for the boxes. The college system needs about ten: a CDN, a static origin, two stateless API instances, the college SSO, one managed relational database with a synchronous standby, a batch flusher, a close-check job, a tally job, a results publisher and an admin console. The design splits into two paths that never touch: a write path that must be exact and carries at most 1 vote/s, and a results path that carries 400 requests/s and is a static file. Then we name what is missing on purpose (queue, cache, microservices, second region), why, and what would change each answer.

The interviewer slides the marker across. "You've got the contracts and the tables. Draw me the system."

You: "Before I draw, here are the three numbers the drawing has to respect: a voting peak of 1 vote/s, 4.8 MB of ballots for the whole election, and a results spike of 400 requests/s after close. The first two say this is a small database problem. The third says the busiest part of the system should not touch the database at all."

The Whole System on One Board

High-level architecture: Alex's browser gets pages, ballot definitions and results from the CDN (cache miss to the static origin), signs in with College SSO, and calls the API service (2 stateless instances in 2 AZs) to get the ballot and cast with a token; the API verifies the token signature with SSO and runs one transaction on the managed relational DB (primary plus synchronous standby); the batch flusher, close-check job (count-only view: ballots = participation = codes) and read-only tally job reach the DB; the tally job sends counts to the results publisher, which writes static JSON and the sorted board to the origin; the registrar roll file is imported into the dual-control admin console, which defines, imports and schedules open and close via the API

Component Its one job Why this and not something bigger
CDN + static origin Serves the web app, the public ballot definitions, the results JSON and the bulletin board snapshot The 400 requests/s spike becomes cache hits at the edge
API service Reads identity from the SSO token, looks up the roll, runs the cast transaction, returns the random-looking tracking code Stateless, so two instances behind a load balancer survive losing a zone. Either could carry 1 vote/s alone
College SSO Proves who Alex is We never store passwords. The college already runs this
Managed relational DB Holds the roll, participation, the ballot buffer, ballots, the bulletin board codes and the audit log 4.8 MB fits in memory many times over. One database gives us a real transaction for exactly-once
Batch flusher Every 15 minutes, if the buffer holds at least 25 ballots, shuffles them into ballots. At close it moves the remainder Breaks the link between write order and participation (Section 7 owns the details)
Close-check job After close: confirms ballots = participation = board codes A count-only view, so it learns totals and never reads a selection or a voter id
Tally job After close and after the close checks: count Read-only role on ballots; nothing in participation
Results publisher Writes the results JSON and the bulletin board file (codes sorted, never in cast order) to the origin One write, then the CDN does the rest
Admin console Election setup, roll import, scheduled open and close Any change needs two committee members, and every action lands in the audit log

Each component also has a database role that matches its job. The API can insert into participation, ballot_buffer and bulletin_board but cannot read ballots. The flusher can move rows from the buffer to ballots and sees no voter ids. The close-check job sees only counts. The tally job reads ballots only. Section 5 covered what each table must not contain; the roles make sure each process can only reach the tables it needs.

Quick check before moving on:


Sign in to continue reading

The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.

Sign in to read the full lesson

Sign in to MAANG.io

Use your Google or Microsoft account — no password to remember.

Continue with Google Continue with Microsoft

Please accept the terms above to continue.