System design — Engineering Manager loop
You still have to draw. You also have to say who owns which box, what you ship first, and what you measure.
Draw. Then talk. If you cannot defend a box, leave it off the board.
Practice problems live in Problems. Company and market language lives in Domain.
Source for the IC template: System Design School primer, study guide, NFRs. Do not recite Twitter. Map every idea to where truth lives, who may see it, and what you measure.
How an EM interview differs from a tech-lead interview
| Tech lead (old loop) | Engineering manager (this loop) |
|---|---|
| You are the designer of one vertical | You are accountable for teams delivering the design |
| Deep on one service’s APIs | Deep on the hard constraint, then staffing and sequencing |
| “I would implement…” | “The team would implement… I would make this the default in review.” |
| Mentorship as unblocking PRs | Capacity, on-call, career, not being the bottleneck |
| Quality as your code review | Quality as KPI + automation + definition of done |
| Stakeholder how | Stakeholder how + exec-ready risk |
Level they are probing: treat this as senior / L5–L6 hybrid. SDS: L5 = scale a feature, name bottlenecks, 1–2 deep dives. L6 = ambiguity, production failure modes, why this vs that when requirements change. Lead the room. Skip textbook load balancers in one sentence. Spend time on the hard constraint (often correctness, not QPS).
Memorization trap (primer): cookie-cutter Kafka+Redis diagrams die under “what if the feed is late?” Know why each box exists.
Primer you actually need (compressed)
What system design is
Making trade-offs so a vague problem becomes a system that meets requirements. Not connecting boxes — justifying the connections from constraints.
The four challenges (every design)
- Too many concurrent users → replicate compute (load balancing) and/or data (replicas).
- Too much data → partition / shard with a key that matches access.
- Must feel fast → reads from memory/cache; writes go async when the user can wait. Exception: money and positions often cannot lie with a spinner.
- Inconsistent / stale state → the bill for (1)+(2)+(3). Consumer apps use eventual consistency. Correctness-heavy apps wait or show an explicit break.
Non-functional requirements (the “big four”)
Availability, scalability, latency, consistency. They conflict. You prioritize from the business.
| NFR | Typical consumer app | Correctness-heavy default |
|---|---|---|
| Availability | Stale feed > error | Unavailable write > wrong write on money/permission paths |
| Scalability | 100M users | Pain may be burst, hot key, multi-tenant blast radius, not millions of users |
| Latency | <500ms reads | Reads feel instant on entitled data; ingest can lag if the UI is honest |
| Consistency | Eventual OK | Strong where money / positions / entitlements move; eventual OK for “processing” if labeled |
Loan-market defaults: Domain NFRs.
CAP in one sentence they can hear: once the network splits, you pick correct and maybe down (CP) or up and maybe stale (AP). Writes that move money or permissions = CP. A “live progress dashboard” can be AP if it says it is approximate.
Consistency spectrum: strong → read-your-writes → eventual. Pick the weakest the feature can tolerate. Primer: stronger = latency and availability cost.
Core building blocks (know these cold)
- Stateless services + load balancer
- Replication + cache for reads
- Partitioning (prefer consistent hashing if shards resize)
- Message queues for write/ingest buffering
- Plus when lying is expensive: idempotency, outbox, sagas/compensations, row-level authz, audit log, dead-letter, observability
Master template (primer): write to a queue; workers update DB and cache; read from cache.
Amendment when lying is expensive: the read path used to act (pay, vote, reconcile) cannot be “whatever is in Redis.” Cache is a performance layer behind source of truth. Show as_of / sync state in the API.
How to scale (only add a technique when a number forces it)
Back-of-envelope: daily actions / 86,400 → avg QPS; × peak factor. Storage = writes × bytes × retention. Round to orders of magnitude. Ask: is the pain reads, writes, storage, or burst?
Then: decompose by business capability → vertical scale only if it’s a DB with strong consistency needs → horizontal for stateless → partition data → cache (hit rate is the game: 90%→99% is another 10× off origin) → queue writes → read/write split or CQRS if models truly differ.
Business-level load shaping (primer, useful for EM): don’t run every sale on one day; stagger. Don’t onboard three full-history migrations the same weekend as a hard deadline.
Contention
Naive read-modify-write loses updates. Optimistic lock (UPDATE … WHERE version = N). Pessimistic lock if conflicts are common (inventory or tally under a deadline — [discuss]).
Sagas
No distributed ACID across you, an external provider, and a customer’s book. Steps + compensating actions, all idempotent. Primer checkout: reserve → charge → ship. If a required snapshot or reservation fails, do not accept the write.
Decomposition framework (open every interview with this)
Vague prompt → keywords.
- Verbs → use cases. post, view, vote, reconcile, notify. Define correct for each (dedupe? immediate? durable forever?).
- Nouns → entities + ownership. Who is allowed to write.
- Adjectives → constraints. realtime, reliable, auditable, multi-tenant, consistent. Each adjective earns a component. Do not sprinkle Kafka for sport.
Interview clock (45–60 min)
- Requirements / decomposition (8–10 min) — you lead; write NFRs on the board.
- APIs (3–5 min) — readable resources, authz in the contract.
- High-level design (15 min) — one box at a time, each forced by a problem.
- Deep dives (15 min) — 2–3 hard constraints, not a catalog of boxes.
- EM close (3–5 min) — rollout, SLOs, team shape, v1 cut, exec summary.
If they starve you of time, skip CDN and object storage. Keep golden source and authz.
How to open (same for any prompt)
“I would not start with the framework. I would start with where truth lives, who is allowed to see it, and what the UI does when we or an upstream system are behind. Then I’d say what a team can ship in v1 versus what becomes a platform bet with architecture. Here’s how I’d approach [problem].”
Then run verbs → nouns → adjectives. Ask:
- Who are the actors?
- What’s the write rate vs read rate? Peak?
- What’s worse: stale, wrong, down, or leaked?
- Retention / audit?
- Single region or more? (Don’t invent multi-region unless they care.)
EM overlay — say this on every board
After the boxes:
- Team topology. Platform vs product vertical vs shared concerns (authz). Conway: if one squad owns both “pretty grid” and “the hose,” the hose loses.
- v1 vs platform. One-way sync before two-way. One use case before all. Architecture owns the long-term model; your teams own the vertical contract.
- Definition of done. Tests on must not see another tenant’s row; idempotent submit; replayable ingest.
- SLIs/SLOs (KPIs). Lag, escaped defects, false-allow = 0 on authz — not story points.
- Operability. Queue depth, poison messages, Datadog on workers, not only the SPA. On-call is a people issue.
- Exec one-liner. “We can have a live-looking grid this week that can be wrong, or a smaller honest slice in two. I recommend two. If the date is political, we cut scope, not golden source.”
If they ask you to pick one and go deep
Use proof stories when you need a personal board. Map Temelio to two-ledger problems and Phia to ingest. Offer a second board in a sentence; do not draw two full systems.
One sentence if they only give you thirty seconds
Temelio: “We designed an accounting integration as a mapping layer between two ledgers, with idempotent writes, explicit conflict behavior, a UI that showed sync state, and we taught the company how to sell that honestly.”
Phia: “We took listing ingest off the request path, queued and coalesced work per item, and scaled workers behind rate limits so the app could read from our store when traffic jumped.”
EM: “I would have the team ship the same skeleton: golden source at the boundary, async where we can, strong consistency where we can’t lie, entitlements on every read, and SLOs on lag and wrong-row.”
Primer self-check (from SDS)
- Reveal components one at a time so each is forced.
- Consistent hashing remaps ~1/N keys on resize; hash-mod-N remaps almost all.
- On partition, AP still answers (stale); CP refuses on the cut-off side.
- Optimistic lock: version column; loser retries.
- Queues are at-least-once → workers must be idempotent.
Night-before drill (30 min)
- Say the open paragraph out loud.
- Sketch one correctness board from a blank page (no interviewer notes).
- Sketch one SDS board (webhook or rate limiter).
- EM close: two hows + KPI + who owns ingest vs UI.
- Recite CAP in English once.