← All tracks

Concurrency

Concurrency is not a syntax you learn, it is a set of failures you have personally caused. Rather than ten unrelated toys, this track builds two systems properly. The first three exercises are a bank: money vanishes, then the fix deadlocks, then a rate limiter shows that the clock is harder than the lock. The remaining seven are one load balancer, built up from a registry you can add backends to into something with health checks, a connection pool, a circuit breaker, graceful draining and consistent hashing — each exercise adding a capability and, with it, a new class of bug that the previous design could not have had. Every exercise is solved three times, in Java, Go and Python, because the same bug is silent in one language, loud in another, and disguised by the GIL in the third.

Java · Go · Python · 4 of 10 written · free, no signup

Foundations
  1. 01
    The bank that loses money

    Start with a transfer function that works perfectly in tests and destroys money under load. Solved in Go, Java and Python — where the same bug is loud, invisible, and disguised by the GIL respectively.

    45 minutes · data races · critical sections · check-then-act · memory models

  2. 02
    The bank that freezes itself

    Per-account locks are the obvious optimisation and they introduce deadlock. Build it, freeze it on purpose, then fix it in Go, Java and Python — where only one of the three runtimes will tell you what went wrong.

    1 hour · deadlock · lock ordering · lock granularity · reentrancy

  3. 03
    A rate limiter for a payment gateway

    A token bucket is ten lines and almost everybody writes it wrong the first time. Built in Go, Java and Python — where every real difference turns out to be about the clock, not the lock.

    1 hour · time and concurrency · monotonic clocks · lock scope · async vs threads

Applied
  1. 04
    A load balancer you can register backends with

    Registration is the interesting part, not the routing. Crash it with an index out of bounds, then find the boundary that makes the bug unconstructible rather than merely fixed — and the two bugs that survive even after you draw it.

    1 hour 15 minutes · read-mostly state · consistent snapshots · copy-on-write · compound reads · API boundaries

  2. 05
    Least-busy routing, and the race in picking the minimum

    Planned

  3. 06
    Health checks, and the threads that outlive what they were checking

    Planned

  4. 07
    A connection pool per backend, and backpressure when it is full

    Planned

Advanced
  1. 08
    A circuit breaker that lets exactly one request through

    Planned

  2. 09
    Removing a backend without dropping what it is already doing

    Planned

  3. 10
    Routing that barely moves when the ring changes

    Planned