Updated May 27, 2026

12 - Design a File Storage Service

📋 Jump to Takeaways

🎁 You edit a single paragraph in a 500MB document. How does the system sync just that change across all your devices without re-uploading the entire file?

A file storage service (like Dropbox or Google Drive) lets users upload files, sync them across devices, and share them. The challenges: handling large files over unreliable networks (resumable uploads), syncing changes across devices in real-time, and deduplicating storage when many users have the same files.

File Storage Requirements

File Storage Functional Requirements

  • Upload and download files (up to 5 GB)
  • Sync files across multiple devices automatically
  • File versioning (restore previous versions)
  • Share files/folders with other users
  • Work offline, sync when connection returns

File Storage Non-Functional Requirements

Metric Target
Users 50 million registered
Storage Average 5 GB per user = 250 PB total
Upload size Up to 5 GB per file
Sync latency < 5 seconds for small files
Durability 99.999999999% (eleven 9s, never lose a file)

File Storage Scope Exclusions

  • Real-time collaborative editing (Google Docs, not Dropbox)
  • File format conversion or preview generation
  • Full-text search across file contents

File Storage Estimation

  • 50M users × 5 GB average = 250 PB total storage
  • Uploads: ~10M files/day, average 5 MB = 50 TB/day ingestion
  • With deduplication (40-60% savings): ~20-30 TB/day net new storage

Storage-bound at petabyte scale. Deduplication is critical for cost control.


File Storage High-Level Design

┌─────────────────────────────────────────────────────────────────┐
│                     FILE STORAGE SERVICE                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌──────────┐     ┌──────────────┐     ┌──────────────────┐     │
│  │  Client  │────►│  API Server  │────►│  Metadata DB     │     │
│  │          │     │              │     │  (PostgreSQL)    │     │
│  └────┬─────┘     └──────────────┘     │  files, versions │     │
│       │                                │  sharing, blocks │     │
│       │                                └──────────────────┘     │
│       │                                                         │
│       │  (upload chunks directly)                               │
│       └───────────────────────────────►┌──────────────────┐     │
│                                        │  Block Storage   │     │
│                                        │  (S3)            │     │
│                                        │  content-        │     │
│                                        │  addressed       │     │
│                                        └──────────────────┘     │
│                                                                 │
│  ┌──────────────┐                                               │
│  │  Sync Service│  (notifies devices of changes via             │
│  │  (WebSocket/ │   long-polling)                               │
│  │   long-poll) │                                               │
│  └──────────────┘                                               │
└─────────────────────────────────────────────────────────────────┘

File Storage Deep Dive

File Chunking

A 5 GB file uploaded as one piece: if it fails at 4.5 GB, start over. Instead, split into 4 MB blocks:

  • Resumable uploads. Failed? Retry only the failed block
  • Parallel uploads. Upload 4 blocks simultaneously
  • Deduplication. Identical blocks stored once (see below)
  • Efficient sync. Changed one paragraph? Only re-upload that block

Content-Addressable Storage

Hash each block with SHA-256. The hash becomes the storage key:

Block content: "Hello world..." → SHA-256 → "a7f3c..."
Store at: s3://blocks/a7f3c...

Same content from another user -> same hash -> already stored -> skip

Two users with the same file share all blocks. A file with one changed paragraph shares all unchanged blocks with its previous version. Dropbox reported 40-60% storage savings from this approach.

Device Sync

Each user has a change log, an ordered list of file events:

cursor: 1050
events:
  1051: MODIFY /docs/report.pdf (blocks: [a7f, b3c, new_block_d4e])
  1052: CREATE /photos/vacation.jpg
  1053: DELETE /old/temp.txt

Sync protocol:

  1. Device connects, sends its last cursor position
  2. Server returns all events since that cursor
  3. Device applies changes (download new blocks, delete removed files)
  4. Device sends its own local changes (uploads)

Real-time notification: Long-polling or WebSocket tells devices "new changes available" so they sync immediately, not on a timer.

Conflict Resolution

Two devices edit the same file while offline:

Device A: edits report.pdf offline
Device B: edits report.pdf offline
Both come online → conflict!

Solution: Last-writer-wins + conflict copy. Keep the most recent version as the primary. Save the other as "report (conflict copy).pdf". Let the user decide which to keep. No data is lost.

Versioning

Every file change creates a new version (new block list):

report.pdf v1: blocks [a7f, b3c, d4e]
report.pdf v2: blocks [a7f, b3c, x9z]  ← only block 3 changed

Only the new/changed blocks are stored. Old versions reference the same unchanged blocks. Cheap version history without full copies.


Key Takeaways

  • Chunking enables resumable uploads and deduplication

    Split files into 4 MB blocks. Failed uploads retry one block. Identical blocks across users/versions stored once. Changed files only upload changed blocks.

  • Content-addressable storage (hash as key) deduplicates naturally

    Same content → same hash → same storage key. No explicit dedup logic needed. Two users with the same file cost zero extra storage.

  • Change log + cursor enables efficient sync

    Devices request "what changed since cursor X?" instead of comparing full file trees. Lightweight, incremental, works across any number of devices.

  • Conflict copies preserve data without complex merge logic

    Last-writer-wins is simple and predictable. The losing edit is saved as a conflict copy. The user resolves it. No data lost, no complex CRDTs needed.

Want the full design? The example "File Storage Service at Scale" covers block-level sync protocols, metadata schema, sharing permissions, and tiered storage strategies.


🎁 The user has typed just three characters. You have 50 milliseconds to search billions of terms and return the top 10 suggestions. What data structure makes this possible?

📖 Examples

Complete examples for this lesson.

📝 Ready to test your knowledge?

Answer the quiz below to mark this lesson complete.

Spot something off? Report an issue
© 2026 ByteLearn.dev. Free courses for developers. · Privacy