CASE STUDY

Offline Multi-Device E-Book Reader (Kindle-style)

3 min read·410 words·Intermediate

Asked at

1 candidate report in Jan 2026

How to use this case study

SDE-2 / Mid

Design APIs and schema for books, a user's library, downloads, and syncing reading position across devices.

SDE-3 / Senior

Go deeper on offline-first sync (queued changes, conflict rules like furthest position wins), annotations sync, and DRM-protected downloads.

Staff / Principal

Discuss scale (millions of devices syncing), large book files via CDN, and conflict resolution for notes edited on two devices.


0) Problem Restatement

Amazon asked: design an e-book reader service with APIs, a database schema and an architecture. A user buys books, reads offline, and uses several devices (phone, tablet, e-reader) for the same book. The system must sync reading position, bookmarks, highlights and notes across devices, even when devices were offline and made changes at the same time.


1) Requirements

  • Library of owned books, and download of book files (DRM-protected).
  • Read fully offline.
  • Sync position ("page 142 on your phone, jump there?"), bookmarks, highlights and notes.
  • Resolve conflicts from offline edits sensibly.


2) Architecture

Architecture Diagram

flowchart LR
    D1["Phone"] -->|"sync changes"| SYNC["Sync Service"]
    D2["E-reader"] --> SYNC
    SYNC --> DB[("Reading state + annotations DB")]
    D1 -->|"download"| CDN["CDN - encrypted book files"]
    LIC["License / DRM service"] --> D1
    STORE["Store / purchases"] --> LIB[("Library - entitlements")]
    SYNC --> LIB
    SYNC -->|"push: new position"| D2

3) Data Model

books:        book_id, title, authors, format, file_versions
library:      user_id, book_id, acquired_at, license_status
positions:    user_id, book_id, device_id, location (e.g. EPUB CFI / percent), updated_at
annotations:  annotation_id (UUID from device), user_id, book_id, type (bookmark|highlight|note),
              range_start, range_end, text, color, updated_at, deleted (tombstone), version

Locations use a stable format that doesn't depend on font size (e.g., an EPUB CFI or a character offset), since "page 142" differs per device.


4) Offline-First Sync

  • The device keeps everything locally and records changes in a local log (position updates, new or edited or deleted annotations) with timestamps.
  • When online, it sends POST /sync { since_cursor, changes[] }. The server applies them and returns all changes since the cursor from other devices, plus a new cursor.
  • Conflict rules (keep them simple and explain them):
  • Reading position: store each device's latest position. When opening a book, if another device is further ahead (or more recent), offer "Jump to page X?" (Kindle's "furthest page read" behavior). Don't move the user automatically.
  • Annotations: each has a unique client-generated ID, so creations never conflict. Edits of the same note on two devices → last-write-wins by timestamp (or keep both versions as a conflict copy). Deletes are tombstones, so a stale device doesn't resurrect the note.


5) Downloads and DRM

  • Book files are encrypted and served by a CDN. The device gets a license (a key bound to the device and account) from the license service. A device limit per book or account applies.
  • Returning or refunding a book revokes the license at the next sync.


6) Wrap-Up

Store the library, per-device reading positions (in font-independent locations) and annotations (client-generated IDs, versions, tombstones) on the server. Devices work offline and sync by sending their local change log and pulling changes since a cursor, with simple conflict rules: offer a jump to the furthest or most recent position, last-write-wins for edited annotations, and tombstones for deletes. Deliver encrypted books through a CDN with device-bound licenses.

More Case Studies

Practice with a Mock Interview

Apply what you learned in a live system design mock interview with our AI interviewer.

Start System Design Interview →