File Storage & Sync — Cheatsheet¶
One-page revision. Reproduce from memory and you can drive the interview.
Problem¶
Dropbox/Google Drive: store files, sync across a user's devices in seconds, share, version — efficient over the network, never lose a byte, at 100Ms of users and exabytes.
Profile (say first)¶
Metadata/data split + bandwidth efficiency. Blob storage is commodity (object store); the design is a consistent sharded metadata service + chunking/dedup/delta sync + a notification loop. Read-heavy, storage-dominated.
Requirements¶
- Must: chunked resumable up/download, near-real-time multi-device sync, delta transfer, dedup, durable + consistent file tree, versioning, conflict handling.
- Defer/seams: sharing (namespaces), search/previews, E2EE (kills cross-user dedup), selective sync.
- Dominant NFRs: durability (11 nines) · metadata strong consistency · bandwidth/storage efficiency · sync latency (sec).
Numbers (example)¶
| Storage | 500M × 50 GB ≈ 25 EB raw → ~12–17 EB deduped (+EC overhead) |
| Dedup | store unique chunks once → biggest cost lever; free uploads if content exists |
| Upload BW | ~100 GB/s avg ingress → delta sync + dedup |
| Download BW | ~10× uploads → CDN immutable blocks |
| Metadata QPS | ~10^5–10^6 ops/s, consistent → sharded + cached (the real DB problem) |
| Chunks | ~10^12+ immutable blocks → refcount + GC |
Architecture¶
Client sync engine: watch FS · chunk+hash · reconcile via cursor
│ 1.status(hashes) 2.PUT blocks 3.commit(meta) 4.GET /sync
▼ ▼ ▼ ▲
[Block Service] [Block Store] [Metadata Svc] │
status/GC/refcnt → object store, file tree, │
│ content-addr versions, │
CDN (immutable) (S3-class) chunk lists, ACLs, │
download cursor (sharded/ns, │
strong consistency) │
│ on commit │
▼ │
[Notification Svc] ────┘ push "changed"→ other devices → pull
Key ideas¶
- Metadata/data split — small transactional consistent tree vs huge immutable content-addressed bytes. The decision.
- Chunk (~4 MB) + content-address (hash) → delta sync + dedup + resumable + parallel, all from one move.
- Client works in hashes:
status()→ upload only missing → commit = atomic transaction (the file now exists). - Delta sync: edit 1 MB of 1 GB → move one chunk. Dedup: identical content stored once (global, with PoP caveat).
- Consistency: metadata strong (single-shard commit); blocks eventual (immutable → lag is safe).
- Sync: notification signal ("namespace changed") + cursor
/syncpull; poll is the correctness backstop. - Conflicts: baseVersion detects divergence → keep both (conflicted copy), never silent loss.
- GC: refcount + conservative mark-and-sweep (delete late).
Chunking¶
Fixed-size (simple; boundary-shift breaks dedup on edits) vs content-defined / rolling hash (insert stays local). Client-side chunk+hash; server verifies hash(bytes).
Bottlenecks (ranked)¶
- Metadata (QPS + consistency) → shard by namespace, cache, single-shard commits
- Upload BW → delta sync + dedup + resumable
- Download BW → CDN immutable blocks + client chunk cache
- Notification fan-out (shared folders) → signal + pull
- Block GC → refcount + async sweep
Failure one-liners¶
- Upload interrupted → resumable (status → upload missing); nothing visible pre-commit.
- Commit fails → idempotent retry; orphan blocks GC'd.
- Conflict → baseVersion → keep both. Corruption → hash check → refetch/EC repair.
- Metadata shard down → namespace-isolated; read-only/delayed sync. Notification missed → sync poll backstop.
- Dup upload → content-addressed no-op. Premature GC → conservative grace period.
Patterns used¶
sharding · caching · idempotency · queues+workers · real-time delivery (notify) · rate limiting (quotas).
SQL vs NoSQL¶
Metadata → sharded strongly-consistent transactional (relational/NewSQL) by namespace. Block index (hash→size/refcount) → KV. Blocks → object store (content-addressed, CDN). Cursor → in metadata (monotonic per namespace).
Summary line¶
"Split metadata from data: a sharded, strongly-consistent metadata store (file tree, versions, ordered chunk-hash list, cursor) where the commit is an atomic single-shard transaction, plus immutable ~4 MB content-addressed chunks in an S3-class object store, CDN-fronted. Client chunks + hashes locally, uploads only missing chunks, then commits — giving delta sync + global dedup. Devices sync via a cursor with a notification push and a poll backstop. Conflicts keep both copies; chunks are refcounted and GC'd conservatively."
← Back to README