SDSystem design
Start learning free

LESSON 106 OF 140 · PRACTICE PROBLEMS

SYSTEM DESIGN · INTERVIEW WALKTHROUGH

Design an E-Book Platform: System Design Interview Practice

The problem

"Design an e-book platform" (a store and reader like Kindle). People buy books, read them on an e-reader, a phone or a tablet, and open any device on the page where they stopped.

This practice problem reuses the pattern of Design Spotify: files in object storage behind a CDN, and downloads kept encrypted on the device. Four things are new: your place, highlights and notes synced across devices; buying each book, charged once; at most 6 devices per account; and search inside a book. Park lending and audiobooks.

The numbers

From the interviewer: 20 million people read each day, about 30 minutes each, and the app saves their place about once a minute while they read. Round a day to 100,000 seconds (86,400 really); busy hours run about 5× the average.

  • Place saves: 20 million × 30 = 600 million a day, 6,000 a second on average (about 6,900 with 86,400), so about 30,000 a second at busy hours. Say one database server takes about 5,000 such writes a second: that's 6 servers' worth, so the sync data is split by reader.
  • Downloads: say 2 million books a day of about 1 MB each: 2 TB a day, about 20 MB a second, 100 MB at busy hours. In the Spotify lesson, audio went out at 8 Tbps at the busiest hour.
  • Catalog: say 10 million books of about 1 MB: 10 TB, 30 TB in 3 copies.

So the busy path is the tiny writes, not the books.

Syncing your place: the newest reading time wins

Ana reads book b7 on her phone in the subway, with no signal, to page 80 at 8:30 am. At lunch she finds her chapter on her e-reader and reads on to page 120, saved at 12:30 pm. The phone's update reaches the server at 6:00 pm:

arrives    update
12:31 pm   page 120, read 12:30 pm   (e-reader)
6:00 pm    page 80, read 8:30 am     (phone)

Her place is one small record per reader and book, sent as PUT /books/b7/place with the page and the time it was read. The server keeps the newest reading time (last write wins, by the device's timestamp), so the late page 80 changes nothing. Keeping whatever arrives last would send Ana 40 pages back. A conflicted copy, as Dropbox makes for files, would ask her a question after every offline ride, for one number that's replaced every minute.

Highlights and notes are records of their own, each with an id made on the device, so both devices' highlights are kept. Each device catches up by asking for the changes after the last one it has, as with Dropbox's change log.

Buying: each purchase once

On a train, Ana taps Buy on b7. The store charges her card, but the reply is lost, and the app tries again. As in Idempotency Keys, the app makes a key for the purchase and sends it on every try:

POST /purchases   {"book": "b7"}
Idempotency-Key: k1
  … no reply: the signal dropped
POST /purchases   {"book": "b7"}
Idempotency-Key: k1
  → the first reply: b7 is yours

The store claims k1 first, where each key can be saved only once, then charges, adds b7 to her library and stores the reply under k1. The retry gets that reply back: one charge. Checking her library before charging isn't enough: two copies arriving together both find nothing and both charge.

Downloads: locked to at most 6 devices

Publishers allow each account at most 6 devices (say), and a downloaded book must open with no signal. A common design has two layers. Each book file is encrypted once, with its own book key, so it's the same for every buyer and the CDN keeps one copy. Each device gets a small license: the book key locked with that device's own key, made only for Ana's registered devices, 3 of 6 used. A file copied to another device has no license there, so it doesn't open.

One key for the whole account would make devices impossible to count: any device holding it opens every book. Asking the server each time a book opens would break reading on a plane. A 7th device must take a removed device's place.

Search inside a book: on the device

Ana wants every page where Gatsby appears, even on a plane. The book is already on the device: a novel of about 100,000 words is about 600 KB of text. After the download, the app builds a small word index of it. For a toy book of four pages ("Gatsby waved", "Daisy saw a green light", "Gatsby threw a party", "the green light went out"), part of it reads:

word     pages
daisy    2
gatsby   1, 3
green    2, 4
light    2, 4
party    3

A search for "green light" keeps the pages in both rows: 2 and 4, offline, with no trip to the servers. What Ana doesn't have stays on the servers: the store's search over 10 million books (say), and a word inside a book she hasn't bought.

Same pattern as Spotify

The catalog carries over: book records point to files in object storage, a signed URL sends the app to a CDN edge for the bytes, and downloads stay encrypted and open offline. What changes is the weight: books are small and downloaded once per device, while place saves are many tiny writes.

Summary

  • Scope: buy, read offline on a few devices, synced place and notes, search inside.
  • Data: one place per reader and book, the newest reading time wins; highlights as records of their own.
  • API: PUT /books/b7/place, POST /purchases with an idempotency key.
  • Numbers: about 30,000 place saves a second at busy hours.
  • Services: sync, the store, and licenses for at most 6 devices.
  • Downloads: each book encrypted once; its key locked to each device.
  • Search inside: on the device, with a word index.
Keep going with system designInteractive lessons from the building blocks to Twitter, Uber and payments, the way interviews ask. Free to start.
Start learning free