What you are looking at
The sliders hold the numbers you would agree with the interviewer first: how many people use the product each day, how often each one writes something, how many reads each write gets, how big a write is, how long it is kept, how many copies are stored and how much busier the peak is than the average. The working turns them into requests a second, storage and bandwidth. Every row shows its sum, and the result rounded to one significant figure, the way you would say it aloud.
The four products are presets made of our own guesses, not figures from any real app. Each guess is one you could argue with, and that is how estimates work in an interview: state a number, check it is roughly sane, and move on. The box under the working divides the totals by what one server can do, which is a guess too, and says which side sets the size of the design.
Why estimate
An estimate is there to make decisions with, not to be exact. Two questions shape most designs, and the numbers answer both.
- Read-heavy or write-heavy? The URL shortener reads each link 200 times for every one created: of its 140,000 or so requests a second at the peak, fewer than 700 are writes. That design is about serving reads fast, and a cache in front of the database does most of the work. Delivery tracking reads each location ping once, so it writes as often as it reads, nearly 90,000 times a second at the peak. There the write path is the hard part.
- Storage or traffic? Photo sharing gets about an eighth of the URL shortener's requests but keeps a thousand times the data, about 50 PB against 50 TB, because a photo is 500 KB and a link is 500 bytes. Its design is about where the bytes live and how they reach people: object storage, and a content delivery network for the 23 Gbit/s it sends out on an average second.
Try it: pick the chat app, then move reads per write from 2 to 100. The writes don't change, and the reads at the peak go from 69,400 a second to 3.47 million.
The shortcuts
- A day is about 100,000 seconds. It is 86,400, but dividing by 10⁵ is something you can do aloud. It makes every figure about 14% low, far less than the doubt in the guesses that went in. A million a day is about 12 a second (10 with the shortcut); a billion a day is about 12,000.
- The peak is a few times the average. Traffic follows the day: most people use most apps while they are awake, and some peaks are sharper, such as meal times for food delivery or the first minutes of a ticket sale. Without data, two or three times the average is a common guess. Say which one you chose.
- Round to one significant figure. 579 a second is 600, and 17,361 is 20,000. The inputs are good to a factor of two at best, so the other digits are noise, and round numbers multiply in your head.
- Storage follows the average, machines the peak. What is written in a day doesn't depend on when it was written, so storage uses the average. Servers and network links have to survive the busiest minute, so they are sized for the peak.
Sizes go up in powers of ten, so multiplying a count by a size means adding the powers: a billion writes (10⁹) of 1 KB (10³) is 10¹² bytes, a terabyte. The steps worth knowing:
- KB, 10³ bytes: a paragraph or two of plain English text.
- MB, 10⁶: a photo from a phone camera is a few of them.
- GB, 10⁹: a million records of 1 KB.
- TB, 10¹²: a billion records of 1 KB.
- PB, 10¹⁵: a thousand terabytes.
The lab counts in thousands, the way disks and network links are sold. Operating systems and memory often count in 1,024s instead (KiB, MiB, GiB), which is why a 1 TB disk shows up as about 931 GiB. The gap is 2.4% at KB and grows to about 10% at TB: too small to matter when you are rounding to one figure.
Against one machine
Totals become a design when you divide them by what one machine can do. That number is the one most worth flagging as an assumption: it depends on the hardware, the data and how much work each request does, and in a real system you would measure it with a load test rather than quote it. The lab starts from one server handling 1,000 requests a second and holding 10 TB. Change both in the box under the working.
With the chat app at those numbers, traffic and data each need about 110 servers (105 and 110). Raise a server to 10,000 requests a second and traffic needs 11 while the data still needs 110: storage sets the size.
Rough latencies help you judge a number like that. These are approximate orders of magnitude, the kind worth carrying in your head; real figures vary with the hardware:
- reading main memory: about 100 nanoseconds;
- a random read from an SSD: about 100 microseconds;
- a round trip inside one data centre: well under a millisecond;
- a seek on a spinning disk: about 10 milliseconds;
- a round trip between continents: about 100 milliseconds, often more.
They turn into capacities. One spinning disk doing one random read at a time manages about 100 a second (a second ÷ 10 ms). An SSD does about 10,000 a second one at a time, and far more with many reads in flight. With the data in memory, the limit moves to the processor and the network.
In an interview
Estimation comes once the requirements are agreed and before any boxes are drawn: the requirements set the numbers, and the numbers shape the design. Four habits help:
- Say every assumption aloud and write it down: “say 100 million daily users, and one in five makes a link each day”. The interviewer may change a guess, and that is fine: the method stays the same.
- Keep it to a few minutes. Round as you go. The interviewer is checking orders of magnitude and reasoning, not long division.
- End each number with what it means for the design: “about 140,000 reads a second at the peak, so the reads need a cache”, “50 TB over five years, more than one machine should hold, so plan to shard”, “50 PB of photos, so object storage and a CDN”.
- Check the units: per day against per second, and bytes against bits. Network links are rated in bits a second, eight to a byte.
Questions this lab prepares you for:
- How many requests a second will this get at the peak?
- How much storage do we need for five years?
- Is the system read-heavy or write-heavy, and what changes because of it?
- Will it fit on one machine, and if not, on how many?
The code
The estimator's core, as the lab runs it. Each row of the working is one of these results at three significant figures, and the figure to say aloud is the same result at one. SECONDS_PER_DAY is the exact 86,400: the shortcut is for your head, not for code.
type Inputs = { users: number; // daily active users writesPerUser: number; // writes per user a day readsPerWrite: number; writeBytes: number; // size of one write years: number; // how long the data is kept replicas: number; // copies of each write peakRatio: number; // peak traffic ÷ average traffic}; const SECONDS_PER_DAY = 86_400; function estimate(i: Inputs) { const writesPerDay = i.users * i.writesPerUser; const writeQps = writesPerDay / SECONDS_PER_DAY; const readQps = writeQps * i.readsPerWrite; const bytesPerDay = writesPerDay * i.writeBytes; const bytesPerYear = bytesPerDay * 365; return { writeQps, peakWriteQps: writeQps * i.peakRatio, readQps, peakReadQps: readQps * i.peakRatio, bytesPerDay, bytesPerYear, bytesTotal: bytesPerYear * i.years * i.replicas, bytesIn: writeQps * i.writeBytes, // Each read returns one write's worth of data. bytesOut: readQps * i.writeBytes, };}