tejas.k

Case study

System Design Playground

Sketch a system, send traffic, watch it break, then fix it. A deterministic simulator in Go with a hand-drawn React canvas.

Status
Open source, MIT
Engine
Go, deterministic discrete-event
Components
23 component types
Challenges
108 guided scenarios

Source on GitHub ↗

  • 108Guided challengesEach one starts broken and teaches one kind of failure.
  • 6-8%Gap to queueing theorySimulated waits match textbook formulas, so the lessons can be trusted.
  • ~330xFaster than real time30 simulated seconds of a busy system run in about 90 ms.

The problem

System design is usually taught with static boxes and arrows. You never see a queue fill, a connection pool run dry or a retry storm build, which is exactly what interviews and production incidents are about.

I wanted a place to build a design and then stress it: send traffic, crash a node, and learn from the failure instead of memorising a diagram.

Architecture

System Design Playground architectureThe browser edits the diagram and streams it to a Go simulation over a WebSocket; frames of stats and request particles stream back. REST handles validation, headless runs, scenarios and shared designs. edits 25 Hz headless run React canvas UI zustand · roughjs · inspector WebSocket session live edits · play · chaos Discrete-event engine event heap · stations · 100 ms ticks REST API validate · run · scenarios · share Sanitiser untrusted diagrams Scenarios as data start must fail, solution must pass Designs store rate-limited
The browser edits the diagram and streams it to a Go simulation over a WebSocket; frames of stats and request particles stream back. REST handles validation, headless runs, scenarios and shared designs.
  1. React canvas UI: zustand · roughjs · inspector
  2. WebSocket session: live edits · play · chaos
  3. Discrete-event engine: event heap · stations · 100 ms ticks
  4. REST API: validate · run · scenarios · share
  5. Sanitiser: untrusted diagrams
  6. Scenarios as data: start must fail, solution must pass
  7. Designs store: rate-limited

Explore the stages

Decisions that mattered

Make the simulator trustworthy

Situation
A toy simulator that is wrong teaches the wrong thing.
What I decided
Check queue waits against known queueing formulas, and make every run repeatable: same design and seed, same result.
Result
Waits land within 6-8% of theory, and any odd result can be reproduced and debugged.

Show why retries can kill a system

Situation
Many outages are not the first fault, but the retries that follow.
What I decided
Model it faithfully: one node slows down briefly while clients retry straight away into a deep queue.
Result
That system never recovers. With backoff, no retries, a short queue or newest-first service, it recovers fully. This became a challenge.

Live, fast and safe to share

Situation
Edits must show up instantly, and anyone can send a design.
What I decided
The server owns the simulation. Every shared design is cleaned and size-limited, and sharing is rate-limited.
Result
It feels live, and untrusted input never reaches the engine.

What I optimise for

  • Same design and seed give the same result.
  • The server decides, the browser only shows.
  • Treat every incoming design as hostile.
  • Teach by breaking things, then fixing them.

Known gaps and what is next

  • It models traffic and capacity, not product data flows like feeds, chat or video.

    Next Add fan-out, publish-subscribe and blob-storage blocks.

  • Service times are smoother than real services.

    Next Make realistic, spiky times the default.

  • Screen-reader use has not been tested by a person yet.

    Next Run the scripted pass and fix what it finds.

What I would change today

  • From the project's own gap analysis: it models request flow and capacity well, but not data-flow questions such as feeds, chat or video pipelines. Those need new building blocks (fan-out, pub/sub, blob storage).

← All work Let's talk →

↑↓ navigate · ↵ run · esc close

tejas@portfolio ~

The 30-second version

Tejas Kothari

Message on LinkedInSee the workLinkedIn