Audit of the Fifteen
You specified the project list. I designed to it and never asked whether it was the right list — which is a question upstream of every other decision in the track.
This page is that audit: what the fifteen cover, what they redundantly cover, what they do not cover, and which of the gaps actually matter for the stated goal.
Conclusion first: the list is good, with one real redundancy and three real gaps, of which only one is worth acting on now.
Table of Contents
- The Coverage Map
- What Is Covered Twice
- What Is Not Covered At All
- The Three Gaps That Matter
- Against the Stated Goal
- What I Would Change
- What I Would Not Change
- References
The Coverage Map
Thirteen fundamental mechanisms in systems work, against the projects that build them. ● = built by hand. ○ = touched but not built.
| Mechanism | P01 | P02 | P03 | P04 | P05 | P06 | P07 | P08 | P09 | P10 | P11 | P12 | P13 | P14 | P15 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Cache / memory hierarchy | ○ | ● | ○ | ● | ● | ○ | ● | ○ | |||||||
| Durability & crash recovery | ● | ● | ● | ○ | ● | ○ | ○ | ||||||||
| Concurrency & synchronisation | ● | ○ | ● | ● | ● | ● | ○ | ○ | |||||||
| Partial failure / consensus | ● | ● | ● | ○ | |||||||||||
| Scheduling | ○ | ○ | ● | ● | ● | ||||||||||
| Approximation with a bound | ● | ● | ● | ● | ● | ○ | ● | ● | ○ | ||||||
| Dispatch & interpretation | ○ | ● | ○ | ● | |||||||||||
| Memory management / GC | ○ | ● | ● | ● | ● | ||||||||||
| Compilation / IR | ● | ● | ○ | ||||||||||||
| Data movement & locality | ○ | ● | ● | ● | ○ | ● | ○ | ● | ● | ● | ○ | ||||
| Statistical inference | ○ | ○ | ● | ● | ● | ● | |||||||||
| Measurement & experiment design | ● | ● | ● | ● | ● | ● | ● | ● | ● | ● | ● | ● | ● | ● | ● |
| Protocol / wire format | ○ | ○ | ● | ○ | ○ | ○ |
Every row has at least one ●. Measurement is universal, which is the design intent — it is the one skill the whole track exists to build, and it is trained fifteen times.
Best-covered: data movement (7 projects), durability (4), approximation (6). Those are the right three to over-cover for someone building retrieval and storage systems.
Thinnest: protocol/wire format (1 solid), scheduling (2), compilation (2).
What Is Covered Twice
Redundancy is not automatically waste — repetition in different contexts is how a lesson generalises. But two cases are worth naming.
P06 and P07 share more than they should
Both build: a coordinator, a worker pool, task/operator scheduling, a partitioned shuffle or network partitioner, failure detection and retry, and checkpoint/recovery. P07's page even says the scheduler "generalises" from P06.
| P06 | P07 | Genuinely distinct? | |
|---|---|---|---|
| Coordinator + workers | ● | ● | No |
| Partitioning / shuffle | ● | ● | Mostly no |
| Fault tolerance via re-execution | ● | ○ | — |
| Fault tolerance via checkpointing | ○ | ● | Yes |
| Bounded vs unbounded input | ● | ● | Yes — the real difference |
| Event time, watermarks, windowing | ● | Yes, and it is P07's whole point | |
| Stragglers / speculative execution | ● | Yes, and it is P06's |
The honest reading: ~40% of the two projects overlaps, and the distinct 60% is where each project's value lives. 176 hours for 60% novelty is the weakest hours-per-lesson ratio in the portfolio.
The existing scope cut — build P07 as an extension of P06's runtime, saving 2 weeks — addresses this partially. The stronger version is to make it the default rather than a fallback: build one distributed execution runtime, then run it in two modes. You would save ~4 weeks and lose nothing but the experience of building a second coordinator, which you will have just built.
P03 and P04 both build persistence
P03 builds a naive append-only store; P04 builds a proper LSM. This is deliberate redundancy and it is correct — it is the roadmap's most explicit application of "naive design first", and it costs about six hours of rework on purpose. P03's measured recovery time is what makes P04 feel necessary rather than academic.
Not a defect. Leave it.
What Is Not Covered At All
Nine mechanisms a systems engineer might reasonably be expected to have built, absent from the list.
| Absent | What it would teach | Verdict |
|---|---|---|
| Networking below RPC — TCP state machine, congestion control, a userspace stack | Flow control, retransmission, the actual behaviour under loss that P05 only simulates | Real gap. See below |
| Code generation — SSA, register allocation, native emission | The other half of compilation. P11 stops at a bytecode VM by design | Real gap, deliberately deferred |
| Concurrency primitives from scratch — lock-free queue, MCS lock, epoch reclamation | Memory ordering as something you implement rather than use | Real gap. Smallest and cheapest to close |
| Query processing — parsing, planning, optimisation, execution | The layer above P03/P04's storage | Correctly excluded. A whole second journey |
| Transactions / MVCC — isolation levels, conflict detection | Why serializable is expensive | Partly covered (P03 snapshots, P05 linearizability). Acceptable |
| Compression — entropy coding, dictionary methods | A real column in the RUM trade-off | Mentioned in P04, not built. Minor |
| Security & isolation — capabilities, sandboxing, side channels | A different threat model to P12's basic isolation | Out of scope for the stated goal |
| Observability — tracing, sampling, cardinality | Only appears as P15 instrumentation | You do this professionally. Low marginal value |
| Distributed training — data/tensor/pipeline parallelism | Where ML meets distributed systems | Needs P13 and P05. A strong post-journey project |
The Three Gaps That Matter
Ranked by how much they weaken the stated goal.
1. Concurrency primitives from scratch — the cheapest to close
What is missing. You use atomics and mutexes across P05–P07 and P12, and measure them in numbers §4. You never build one. Memory ordering, ABA, and safe reclamation stay theoretical.
Why it matters here. P12 is single-core by design, so the one project that would naturally force this is scoped to avoid it. That is a defensible scoping decision that leaves a hole.
Cost to close: 2–3 weeks. A Small project: a lock-free MPSC queue, a ticket lock and an MCS lock, benchmarked under contention from 1 to N threads, with the crossover found.
Where it fits. As P12's extension, which already names "synchronisation shoot-out" — promote it from optional to standard. Or as a standalone Small project between P12 and P14.
My recommendation: take P12's extension as standard. It is the highest ratio of lesson to weeks on this page.
2. Networking below RPC
What is missing. P05 assumes a network that drops, delays, duplicates and reorders — correctly, and that is the right abstraction for consensus. But you never build the layer that produces those behaviours: no congestion control, no retransmission, no flow control, no head-of-line blocking.
Why it matters. A large fraction of real distributed-systems debugging is network-layer behaviour leaking through the abstraction — Nagle interacting with delayed ACK, TCP incast collapse, a connection pool exhausting under retry storms. Simulating faults at the message level teaches you what to handle; it does not teach you why they occur.
Cost to close: 4–6 weeks for a minimal reliable protocol over UDP with sliding window, retransmission and one congestion-control algorithm.
Verdict: a real gap, and I would not add it. Six weeks against 130 for a mechanism that is one layer below where your stated goals live. Note it as a limitation and consider it post-journey. If you want a cheap partial: in P05, add a fault-injection mode that models bandwidth and queueing rather than only drop and delay — that surfaces congestion-shaped failures for about two days of work.
3. Code generation
What is missing. P11 goes lexer → parser → AST → bytecode → VM → GC, and stops. SSA, register allocation, instruction selection and native emission are absent, so "how does a compiler produce fast machine code" remains a black box — which is a notable hole next to a journey that measures machine code constantly.
Why it is deliberate. A JIT is a project in itself, P11 is already Large at 132 hours, and the dispatch lesson (bytecode's advantage is cheaper operations, not fewer) is fully delivered without codegen.
Cost to close: 6–10 weeks.
Verdict: correctly deferred. It is the single best post-journey project on this page, and it composes: P11 gives the front end, P14 gives the machine model, and a tracing JIT for your own language is a genuinely impressive artifact.
Against the Stated Goal
You named MapReduce, Spanner, TensorFlow, TPUs, programming languages, OS kernels, databases, distributed systems, vector search, recommenders, and Transformers.
| Named system | Covered by | Fidelity |
|---|---|---|
| MapReduce | P06 | High — same architecture, same failure model |
| Spanner | P05 | Partial — consensus and replication yes; TrueTime and distributed transactions read-only |
| TensorFlow | P13 | High for the autodiff and graph-execution core; no distribution |
| TPUs | P14 | Good for the reasoning — you derive the TOPS figure and simulate the array; no silicon |
| Programming languages | P11 | High to bytecode+GC; no codegen |
| OS kernels | P12 | Good — boot, VM, scheduling, syscalls; single-core, no drivers |
| Databases | P03+P04 | Storage engine only. No query layer, no transactions |
| Distributed systems | P05–P07 | High |
| Vector search | P02+P03 | High — arguably the deepest coverage in the list |
| Recommenders | P08–P10 | High, including the evaluation problem most treatments skip |
| Transformers | P01+P13 | High for the mechanism; no scale |
Ten of eleven are covered at high or good fidelity. The weakest is Spanner, and the missing pieces there (bounded clocks, distributed transactions) are precisely the parts that need infrastructure you cannot have.
The list is well matched to the goal. That is worth saying plainly, because the rest of this page is criticism and the headline finding is that the portfolio is sound.
What I Would Change
Three changes, in order of confidence.
1. Merge P06 and P07 into one runtime, two modes. Saves ~4 weeks, loses ~nothing. Build one coordinator, worker pool and partitioner; run it in batch mode (with speculative execution and the straggler study) and in streaming mode (with watermarks, windowing and checkpointing). The distinct 60% of each project is fully preserved and you stop building the same scheduler twice. Confidence: high.
2. Promote P12's synchronisation shoot-out from extension to standard. Costs ~2 weeks, closes the cheapest real gap, and produces directly transferable knowledge — every concurrent system you tune afterwards benefits. Confidence: high.
3. Add bandwidth and queueing to P05's fault injector. Two days. Surfaces congestion-shaped failures without a six-week networking project. Confidence: medium.
Net: −2 weeks and one gap closed. Both of the first two are consistent with the existing scope-cut machinery rather than requiring a replan.
What I Would Not Change
- The fifteen-project scope. It is ambitious and it is coherent. Cutting further would produce breadth without the depth you asked for.
- P03's deliberate redundancy with P04. The rework is the lesson.
- P12's single-core scoping. SMP multiplies the difficulty of every subsequent bug; the extension in change 2 gets the concurrency lesson without it.
- The absence of a query layer. Storage engines and query processing are two journeys. Yours is the storage one.
- P09 and P10 as separate projects, despite the existing cut that merges them. The A/B platform's statistical content is genuinely distinct from the simulator's modelling content, and it is the part most directly useful in your job next month.
References
- Brooks, F. P. No Silver Bullet — Essence and Accident in Software Engineering. IEEE Computer 20(4), 1987. The essence/accident distinction underlying the coverage map: the mechanisms are the essence; the fifteen projects are one accidental arrangement of them.
- Lampson, B. W. Hints for Computer System Design. SOSP 1983. "Do one thing well" — the argument for merging P06 and P07 rather than building two partial runtimes.
- Ousterhout, J. A Philosophy of Software Design, 2nd ed. Yaknyam Press, 2018. On deep modules, and on the cost of building the same abstraction twice.
- Mellor-Crummey, J. M., Scott, M. L. Algorithms for Scalable Synchronization on Shared-Memory Multiprocessors. ACM TOCS 9(1), 1991. MCS locks — the reference for gap 1.
- Herlihy, M., Shavit, N. The Art of Multiprocessor Programming, 2nd ed. Morgan Kaufmann, 2020. The text for the synchronisation shoot-out.
- Alizadeh, M. et al. Data Center TCP (DCTCP). SIGCOMM 2010. What gap 2 would teach, and why incast is the canonical example.
- Aycock, J. A Brief History of Just-In-Time. ACM Computing Surveys 35(2), 2003. The entry point for gap 3 as a post-journey project.