1Show the Level 1 solution
2**A.**
31. **URL shortener: read requests.** Links are clicked far more than created; storage per link is tiny.
42. **Video streaming: bandwidth.** Every viewer pulls megabits per second for minutes at a time.
53. **Log collection: write requests (and storage).** 1,000 × 100 = 100,000 lines a second, mostly written, rarely read. At about 200 bytes a line, that's about 1.7 TB a day.
64. **Online exam at 10:00: peak read and write requests.** The daily average is meaningless; everyone arrives in the same minute.
75. **Photo backup: storage.** Lots of large writes, few reads.
8
9**B.**
101. **Wrong time unit.** 86,400 is seconds in a **day**. A month has about 2.6 million seconds, so it's about **386 a second**, 30 times less.
112. **Bits vs bytes.** 5 MB a second = 40 Mbps per viewer. 1,000 viewers = 40,000 Mbps = **40 Gbps**, not 5.
123. **No peak, no headroom, no spare.** At 300 average and a peak factor of 3, that's 900 at peak. At 60% utilisation and 100 per server: 900 ÷ 60 = 15 servers, plus a spare = **16**.
Show the Level 2 solution
1. Bits a day = 5 million × 1,800 seconds × 5 million bits = 4.5 × 10¹⁶ bits. In bytes ÷ 8 = 5.6 × 10¹⁵ = **about 5.6 PB a day**.
2. Average = 4.5 × 10¹⁶ ÷ 86,400 ≈ 5.2 × 10¹¹ bits a second ≈ **520 Gbps**. At peak × 3 ≈ **1,560 Gbps (about 1.6 Tbps)**.
3. 50,000 × 500 MB = 25 TB a day. × 365 = **about 9.1 PB a year** (one copy).
4. **Egress.** Hundreds of gigabits a second on average can't come from a few servers. It decides that a CDN is required, and it's also the biggest cost. Storage is large but straightforward with object storage.
1Show the Level 3 solution
2Tested solution (Python 3):
3
4```python
5import math
6
7SECONDS_PER_DAY = 86_400
8
9
10def estimate(dau, reads_per_user, writes_per_user, write_size_bytes,
11 read_size_bytes, peak_factor=3, years=1, replicas=1, cache_fraction=0.2):
12 reads_per_day = dau * reads_per_user
13 writes_per_day = dau * writes_per_user
14 read_rps = reads_per_day / SECONDS_PER_DAY
15 write_rps = writes_per_day / SECONDS_PER_DAY
16 storage = writes_per_day * write_size_bytes * 365 * years * replicas
17 egress_bytes_per_s = reads_per_day * read_size_bytes / SECONDS_PER_DAY
18 return {
19 "read_rps": read_rps,
20 "write_rps": write_rps,
21 "peak_read_rps": read_rps * peak_factor,
22 "read_write_ratio": reads_per_day / writes_per_day if writes_per_day else float("inf"),
23 "storage_bytes": storage,
24 "egress_gbps": egress_bytes_per_s * 8 / 1e9, # bytes -> bits, then giga
25 "cache_bytes": reads_per_day * read_size_bytes * cache_fraction,
26 }
27
28
29def servers_needed(peak_rps, rps_per_server, target_utilisation=0.6, spare=1):
30 return math.ceil(peak_rps / (rps_per_server * target_utilisation)) + spare
31```
32
33All four checks pass. The full file with the checks is in `code/ch02_estimator.py`.
1Show the Level 4 solution
2**The bug:** the script divides bytes a second by a billion and calls it **gigabits**. It's really **gigabytes** a second. Network links are sold in gigabits.
3
41. 500 million views × 200 KB = 100 TB a day.
52. ÷ 86,400 = about 1.16 **billion bytes** a second.
63. The script prints 1.16 and labels it Gbps.
74. In bits, it's 1.16 × 8 = **9.26 Gbps**. The links were **8 times too small**.
8
9**The fix:**
10
11```python
12def egress_gbps(reads_per_day, read_size_bytes):
13 bytes_per_s = reads_per_day * read_size_bytes / SECONDS_PER_DAY
14 return bytes_per_s * 8 / 1e9
15```
16
173. **It also ignores the peak.** 9.26 Gbps is the daily **average**. At a peak factor of 3, the evening needs about 28 Gbps. (Better still: serve images from a CDN so most of this never touches your own links.)
1Show the Level 5 solution
21. Messages a day = 50 million × 40 = 2 billion. Average = 2 billion ÷ 86,400 ≈ **23,000 a second**. Peak × 3 ≈ **69,000 a second**.
32. Text = 2 billion × 100 bytes = 200 GB a day × 365 = **73 TB a year**.
43. Media = 5% of 2 billion = 100 million photos a day × 200 KB = 20 TB a day × 365 = **7.3 PB a year**.
54. Media ingress = 20 TB a day × 8 ÷ 86,400 ≈ **1.85 Gbps** on average.
65. Servers = 69,444 ÷ (5,000 × 0.6) = 23.1 → 24, plus 1 spare = **25**.
76. **The write rate (about 69,000 messages a second at peak) and media storage** drive the design. The write rate points to spreading the load: partition messages by chat or user (Chapter 15) and use queues for delivery (Chapter 22). The media points to object storage plus a CDN, keeping only references in the message store (Chapter 11).