System Design Story (Chapter 1)
Chapter 1 — Day 1: The Launch
Every billion-dollar system started as something embarrassingly simple. Don’t let anyone tell you otherwise.
The Idea
It’s a Saturday afternoon. You and your friend Maya have been complaining about Twitter for months. Too much noise, too many ads, too much drama. You want something simpler. Just a clean feed of short posts from people you actually know.
You decide to build it. You call it Chirp.
The scope is deliberately tiny:
A user can sign up and log in
A user can post a short message (a “Chirp”)
A user can see a feed of all recent Chirps, newest first
That’s it. No likes. No reposts. No algorithm. Just posts, in order.
The Architecture (Day 1)
User's Browser
│
▼
┌─────────────┐
│ Web Server │ ← Your Next.js app, deployed on Vercel
│ + API │
└──────┬──────┘
│
▼
┌─────────────┐
│ PostgreSQL │ ← A single managed database (e.g. Supabase or Railway)
└─────────────┘
One server. One database. It fits on a napkin.
The Database Schema
You only need two tables to launch.
Table: users
---------------------------------------------------------
id UUID Primary key
username VARCHAR(50) Unique
email VARCHAR(255) Unique
password_hash VARCHAR(255) Never store plain text
created_at TIMESTAMP Default: now()
Table: chirps
---------------------------------------------------------
id UUID Primary key
user_id UUID Foreign key -> users.id
content VARCHAR(280) The post body
created_at TIMESTAMP Default: now()The feed query is just:
SELECT chirps.content, users.username, chirps.created_at
FROM chirps
JOIN users ON chirps.user_id = users.id
ORDER BY chirps.created_at DESC
LIMIT 50;
Simple, readable, and for now totally fine.
Why This Works (For Now)
You push the code. You share the link in a group chat. Twelve people sign up. The app is snappy. The database query runs in 2ms. Vercel’s free tier handles it without blinking.
This setup works because:
The traffic is tiny. 12 users making a few requests a day is nothing.
The data is tiny. A few hundred rows across two tables.
The queries are simple. A single JOIN on a small table is trivially fast.
The simplest architecture that works is the right architecture for now. You don’t need Kubernetes for a weekend project with 12 users. Over-engineering too early is just as dangerous as under-engineering too late.
The Back-of-the-Envelope Check
Let’s run the numbers anyway, just to build the habit.
12 users, each making maybe 10 requests/day = 120 requests/day
Using the 100,000 rule: 1 QPS ≈ 86,400 requests/day, which we round to 100,000 for easy mental math. So divide any daily request count by 100,000 to get approximate QPS. 120 requests/day is essentially 0 QPS
Storage: 12 rows in
users× 1KB = 12KB. Your database is smaller than this document. Chirps are 280 characters max, so with 1000 users and 1000 chirps each that would be under 1GB, still tiny for any modern database.
No load balancer needed. No caching needed. No read replicas needed. The math tells you so.
What You Don’t Know Yet
You’re happy. Maya is happy. The app works.
What you don’t know is that Maya is about to post a link to Chirp in a Discord server with 200,000 members. She does it on a Tuesday evening.
By Wednesday morning, everything is on fire.

