MindForge
MindForge
DashboardHelp & Support
Dashboard
MindForge

Interview Preparation Bootcamp

Course progress

0%
0 of 177 modules complete
Start Here0/1
  • How to Use This Course
Data Structures & Algorithms0/27
  • Arrays and Hashing
  • Two Pointers
  • Sliding Window
  • Sliding Window: Harder Problems
  • Binary Search
  • Stacks
  • Practice Test: Arrays, Pointers, Windows, Search and Stacks
  • Trees: Traversals and Core Patterns
  • Binary Search Trees and Rebuilding a Tree
  • Tries (Prefix Trees)
  • Heaps and Priority Queues
  • Graphs: BFS and DFS
  • Topological Sort and Cycle Detection
  • Union-Find (Disjoint Set Union)
  • Practice Test: Trees, Heaps and Graphs
  • Dynamic Programming Basics
  • Dynamic Programming: Two Dimensions
  • Dynamic Programming: Hard String Matching
  • Backtracking
  • Backtracking: Constraint Satisfaction
  • Greedy Algorithms
  • Interval Problems
  • Bit Manipulation
  • Math and Geometry
  • String Manipulation
  • Pattern Recall and Mock Coding Rounds
  • Practice Test: DP, Backtracking, Greedy and More

System Design

Foundations0/16
  • The System Design Interview Framework
  • Back-of-the-Envelope Estimation
  • Networking and Protocols for Design
  • API Design and Idempotency
  • Load Balancing, Proxies, and Scaling Out
  • Caching and CDNs
  • Choosing a Database: Storage, Indexes and Transactions
  • Replication, Partitioning, and Sharding
  • CAP, PACELC, and Levels of Consistency
  • Messaging, Queues, and Event-Driven Architecture
  • Distributed Transactions and Data Integrity
  • Coordination, Consensus, and Distributed Locks
  • Reliability, Resilience, and Rate Limiting
  • Observability, Security, and Cost
  • System Design Cheat Sheet
  • Practice Test: System Design Foundations
Case Studies0/23
  • Design a URL Shortener
  • Design a Rate Limiter
  • Design a Notification Service
  • Design a Job Queue System
  • Design a Chat App (WhatsApp)
  • Design an Analytics Pipeline
  • Design a Multi-tenant SaaS Architecture
  • Design a Social Media Feed (Twitter/X)
  • Design a Search Autocomplete System
  • Design a File Storage Service (Dropbox)
  • Design Google Docs
  • Design a Code Review System
  • Design Netflix
  • Design YouTube
  • Design Spotify
  • Design Uber/Lyft
  • Design Airbnb
  • Design Ticketmaster (Eventbrite)
  • Design an E-commerce Cart, Checkout, and Catalog
  • Design a Payment System
  • Design a Logging and Monitoring System
  • Mock Design Rounds
  • Practice Test: System Design Case Studies
Low-Level Design0/19
  • The LLD Interview Framework and UML
  • OOP Foundations for Design
  • SOLID Principles
  • Creational Patterns
  • Structural Patterns
  • Behavioral Patterns I — Strategy, Observer, Command, State, Template Method
  • Behavioral Patterns II and Anti-Patterns
  • Concurrency in Low-Level Design
  • Design a Parking Lot
  • Design an Elevator System
  • Design a Movie Ticket Booking System
  • Design an Expense-Sharing App (Splitwise)
  • Design a Vending Machine and an ATM
  • Design a Rate Limiter and a Logging Framework
  • Design a Notification Service and an In-Memory Cache
  • Design Games — Tic-Tac-Toe, Snake and Ladder, Chess
  • Database Design for LLD
  • LLD Cheat Sheet and Recall Drill
  • Practice Test: Low-Level Design

Backend

Python0/5
  • How Python Runs Your Code
  • Functions Deep Dive: Closures, Generators, Context Managers, Scope
  • Classes Deep Dive: Method Types, MRO, Metaclasses
  • Standard Library and Serialization
  • Practice Test: Python
Django0/6
  • Django Request Lifecycle
  • Lab: Django Middleware — Request ID & Response Time
  • Django ORM and Querysets
  • Django's Cache Framework
  • Practice Test: Django
  • Django in Production: Debugging Labs
FastAPI0/5
  • FastAPI, ASGI, and Async
  • FastAPI Dependency Injection
  • FastAPI Background Tasks
  • Lab: FastAPI Async — Concurrent Aggregation
  • Practice Test: FastAPI
Databases (PostgreSQL)0/6
  • Indexing
  • Query Optimization
  • Transactions and Isolation
  • Migrations and Schema Changes
  • Hierarchical Data and Safe Concurrent Updates
  • Practice Test: Databases
Caching, Queues & Distributed Systems0/8
  • Redis Caching
  • Redis Advanced Patterns
  • Celery and Background Workers
  • Kafka and Message Queues
  • Async Pipelines
  • Distributed Systems Basics
  • Distributed Locks
  • Practice Test: Caching, Queues and Distributed Systems
APIs, Security & Deployment0/9
  • REST API Design
  • API Versioning and Error Handling
  • API Security and Authentication
  • WebSockets and Real-Time Systems
  • Docker and Containers
  • File Storage with S3
  • Testing Strategies
  • Mock Backend Round
  • Practice Test: APIs, Security and Deployment
Frontend0/38
  • HTML Document Structure and Semantics
  • CSS Box Model, Flexbox and Grid
  • CSS Architecture and Theming
  • CSS and Rendering Performance
  • Variables, Scope, Hoisting, and Truthiness
  • Functions, this, and Binding
  • Objects and Prototypal Inheritance
  • JavaScript Utility Patterns: Cloning, Caching, and Memory
  • Promises From Scratch
  • The Event Loop and Browser Rendering Pipeline
  • The DOM: Nodes, Events, and Traversal
  • Practice Test: HTML, CSS and JavaScript
  • React Rendering Fundamentals
  • React Hooks Internals
  • React Performance
  • Lab: React — Stateful Counter Component
  • State Management
  • State Machines in React
  • React Custom Hooks and Composition Patterns
  • TypeScript for React
  • React Testing
  • Practice Test: React
  • HTTP and Caching
  • Network Performance and Web Vitals
  • Code Splitting and Bundles
  • Virtualization
  • GraphQL and Data Fetching
  • Web Security
  • WebSockets and Real-time
  • SSR and Next.js
  • Micro-frontends
  • Build Tools and Bundling
  • Accessibility
  • Error Handling
  • Internationalization
  • Animation
  • Rapid Recall and Mock Frontend Rounds
  • Practice Test: Performance, Architecture and Production
Behavioral & Interview Day0/14
  • Resume and Project Walkthroughs
  • The STAR Method and Refining Your Stories
  • Conflict and Difficult Coworkers
  • Failures, Incidents, and Obstacles
  • Leadership, Mentorship, and Ownership
  • Teamwork, Communication, and Feedback
  • Growth and Handling Ambiguity
  • Career Goals, Why This Company, and Negotiation
  • Situational Questions
  • Company Research
  • Mock Behavioral Rounds
  • Interview Day
  • After the Interview
  • Practice Test: Behavioral and Interview Day
Design a File Storage Service (Dropbox)
Course contents

Interview Preparation Bootcamp

Course progress

0%
0 of 177 modules complete
Start Here0/1
  • How to Use This Course
Data Structures & Algorithms0/27
  • Arrays and Hashing
  • Two Pointers
  • Sliding Window
  • Sliding Window: Harder Problems
  • Binary Search
  • Stacks
  • Practice Test: Arrays, Pointers, Windows, Search and Stacks
  • Trees: Traversals and Core Patterns
  • Binary Search Trees and Rebuilding a Tree
  • Tries (Prefix Trees)
  • Heaps and Priority Queues
  • Graphs: BFS and DFS
  • Topological Sort and Cycle Detection
  • Union-Find (Disjoint Set Union)
  • Practice Test: Trees, Heaps and Graphs
  • Dynamic Programming Basics
  • Dynamic Programming: Two Dimensions
  • Dynamic Programming: Hard String Matching
  • Backtracking
  • Backtracking: Constraint Satisfaction
  • Greedy Algorithms
  • Interval Problems
  • Bit Manipulation
  • Math and Geometry
  • String Manipulation
  • Pattern Recall and Mock Coding Rounds
  • Practice Test: DP, Backtracking, Greedy and More

System Design

Foundations0/16
  • The System Design Interview Framework
  • Back-of-the-Envelope Estimation
  • Networking and Protocols for Design
  • API Design and Idempotency
  • Load Balancing, Proxies, and Scaling Out
  • Caching and CDNs
  • Choosing a Database: Storage, Indexes and Transactions
  • Replication, Partitioning, and Sharding
  • CAP, PACELC, and Levels of Consistency
  • Messaging, Queues, and Event-Driven Architecture
  • Distributed Transactions and Data Integrity
  • Coordination, Consensus, and Distributed Locks
  • Reliability, Resilience, and Rate Limiting
  • Observability, Security, and Cost
  • System Design Cheat Sheet
  • Practice Test: System Design Foundations
Case Studies0/23
  • Design a URL Shortener
  • Design a Rate Limiter
  • Design a Notification Service
  • Design a Job Queue System
  • Design a Chat App (WhatsApp)
  • Design an Analytics Pipeline
  • Design a Multi-tenant SaaS Architecture
  • Design a Social Media Feed (Twitter/X)
  • Design a Search Autocomplete System
  • Design a File Storage Service (Dropbox)
  • Design Google Docs
  • Design a Code Review System
  • Design Netflix
  • Design YouTube
  • Design Spotify
  • Design Uber/Lyft
  • Design Airbnb
  • Design Ticketmaster (Eventbrite)
  • Design an E-commerce Cart, Checkout, and Catalog
  • Design a Payment System
  • Design a Logging and Monitoring System
  • Mock Design Rounds
  • Practice Test: System Design Case Studies
Low-Level Design0/19
  • The LLD Interview Framework and UML
  • OOP Foundations for Design
  • SOLID Principles
  • Creational Patterns
  • Structural Patterns
  • Behavioral Patterns I — Strategy, Observer, Command, State, Template Method
  • Behavioral Patterns II and Anti-Patterns
  • Concurrency in Low-Level Design
  • Design a Parking Lot
  • Design an Elevator System
  • Design a Movie Ticket Booking System
  • Design an Expense-Sharing App (Splitwise)
  • Design a Vending Machine and an ATM
  • Design a Rate Limiter and a Logging Framework
  • Design a Notification Service and an In-Memory Cache
  • Design Games — Tic-Tac-Toe, Snake and Ladder, Chess
  • Database Design for LLD
  • LLD Cheat Sheet and Recall Drill
  • Practice Test: Low-Level Design

Backend

Python0/5
  • How Python Runs Your Code
  • Functions Deep Dive: Closures, Generators, Context Managers, Scope
  • Classes Deep Dive: Method Types, MRO, Metaclasses
  • Standard Library and Serialization
  • Practice Test: Python
Django0/6
  • Django Request Lifecycle
  • Lab: Django Middleware — Request ID & Response Time
  • Django ORM and Querysets
  • Django's Cache Framework
  • Practice Test: Django
  • Django in Production: Debugging Labs
FastAPI0/5
  • FastAPI, ASGI, and Async
  • FastAPI Dependency Injection
  • FastAPI Background Tasks
  • Lab: FastAPI Async — Concurrent Aggregation
  • Practice Test: FastAPI
Databases (PostgreSQL)0/6
  • Indexing
  • Query Optimization
  • Transactions and Isolation
  • Migrations and Schema Changes
  • Hierarchical Data and Safe Concurrent Updates
  • Practice Test: Databases
Caching, Queues & Distributed Systems0/8
  • Redis Caching
  • Redis Advanced Patterns
  • Celery and Background Workers
  • Kafka and Message Queues
  • Async Pipelines
  • Distributed Systems Basics
  • Distributed Locks
  • Practice Test: Caching, Queues and Distributed Systems
APIs, Security & Deployment0/9
  • REST API Design
  • API Versioning and Error Handling
  • API Security and Authentication
  • WebSockets and Real-Time Systems
  • Docker and Containers
  • File Storage with S3
  • Testing Strategies
  • Mock Backend Round
  • Practice Test: APIs, Security and Deployment
Frontend0/38
  • HTML Document Structure and Semantics
  • CSS Box Model, Flexbox and Grid
  • CSS Architecture and Theming
  • CSS and Rendering Performance
  • Variables, Scope, Hoisting, and Truthiness
  • Functions, this, and Binding
  • Objects and Prototypal Inheritance
  • JavaScript Utility Patterns: Cloning, Caching, and Memory
  • Promises From Scratch
  • The Event Loop and Browser Rendering Pipeline
  • The DOM: Nodes, Events, and Traversal
  • Practice Test: HTML, CSS and JavaScript
  • React Rendering Fundamentals
  • React Hooks Internals
  • React Performance
  • Lab: React — Stateful Counter Component
  • State Management
  • State Machines in React
  • React Custom Hooks and Composition Patterns
  • TypeScript for React
  • React Testing
  • Practice Test: React
  • HTTP and Caching
  • Network Performance and Web Vitals
  • Code Splitting and Bundles
  • Virtualization
  • GraphQL and Data Fetching
  • Web Security
  • WebSockets and Real-time
  • SSR and Next.js
  • Micro-frontends
  • Build Tools and Bundling
  • Accessibility
  • Error Handling
  • Internationalization
  • Animation
  • Rapid Recall and Mock Frontend Rounds
  • Practice Test: Performance, Architecture and Production
Behavioral & Interview Day0/14
  • Resume and Project Walkthroughs
  • The STAR Method and Refining Your Stories
  • Conflict and Difficult Coworkers
  • Failures, Incidents, and Obstacles
  • Leadership, Mentorship, and Ownership
  • Teamwork, Communication, and Feedback
  • Growth and Handling Ambiguity
  • Career Goals, Why This Company, and Negotiation
  • Situational Questions
  • Company Research
  • Mock Behavioral Rounds
  • Interview Day
  • After the Interview
  • Practice Test: Behavioral and Interview Day
Browsing without an account — progress is saved in this browser only.Sign in to save it

Design a File Storage Service (Dropbox)

System Design65 min
Sign in to open the interactive design canvas for this exercise.

Dropbox, or Google Drive, lets you upload files, sync them across devices, and share them with others. This is a genuinely different problem shape from a CRUD app or a feed: you're moving large binary data, not just database rows, and you need chunked uploads that can resume, deduplication, and a plan for when two devices edit the same file at once.

Requirements

Functional requirements

  • Upload and download files, organized into folders.
  • Sync changes across multiple devices automatically.
  • Share files and folders with other users.
  • Handle large files with chunked, resumable uploads.
  • Deduplicate identical file content across users.

Non-functional requirements

  • Metadata needs fairly strong consistency: you shouldn't see a stale folder listing right after your own upload finishes. Syncing across devices can lag by a few seconds, that's fine.
  • Durability: essentially never lose a file, matching the "eleven nines" real object storage services target.
  • Availability: uploads and downloads should degrade gracefully during a partial outage, not fail outright.
  • Bandwidth efficiency: never re-upload bytes that haven't changed.

Remember: this design only works because it separates two very different problems: structured, transactional metadata (which folder a file is in) from large, immutable binary blobs (the file's actual bytes). Mixing them into one store is the mistake to avoid.

Sign in to try this knowledge check.

Estimates

Assume 50 million users, averaging 5 GB stored each.

  • Total logical storage: 50M × 5 GB = 250 petabytes. Deduplication (many users storing the same popular files, OS images, common documents) brings the real physical number down meaningfully, but plan capacity off the logical total.
  • Daily upload traffic: if 10% of users upload something daily, averaging 10 MB each, that's 5 million uploads/day × 10 MB = 50 TB/day of new traffic.
  • Chunk size: 4 MB is a common choice: large enough that per-chunk overhead stays low, small enough that a failed chunk only costs 4 MB of re-upload, not the whole file.
  • Metadata: 50M users × roughly 10,000 files each = 500 billion file records. At about 500 bytes per record, that's 250 TB of metadata alone, which needs its own sharded, horizontally scaled store, separate from where the bytes live.

API

POST /files/upload/init        { filename, size, folder_id, chunk_hashes[] }
  -> { upload_id, chunks_needed[] }         -- server tells client which chunks it doesn't already have (dedup)

PUT  /files/upload/{upload_id}/chunk/{chunk_index}   (binary body, with chunk hash header)
  -> { received: true }

POST /files/upload/{upload_id}/complete
  -> { file_id, version }

GET  /files/{file_id}/download                        -> presigned blob URL
GET  /folders/{folder_id}                              -> { files[], folders[] }
POST /files/{file_id}/share    { target_user_id, permission }

-- sync
GET  /sync/changes?since_cursor=                       -> { changes[], next_cursor }

Data model

files
  id            UUID PK
  owner_id      UUID
  folder_id     UUID
  name          TEXT
  size          BIGINT
  content_hash  TEXT           -- hash of the full file (post-reassembly), used for dedup
  version       INT
  created_at, updated_at

chunks
  hash          TEXT PK        -- content hash of this chunk (e.g., SHA-256)
  blob_key      TEXT           -- pointer into blob storage (S3 key)
  ref_count     INT            -- how many files reference this chunk, for safe GC
  size          INT

file_chunks
  file_id       UUID
  chunk_index   INT
  chunk_hash    TEXT           -- FK to chunks.hash
  PRIMARY KEY (file_id, chunk_index)

folders
  id, owner_id, parent_id, name

shares
  file_id or folder_id, owner_id, target_user_id, permission (view/edit)

Splitting chunks (content-addressed, one row per unique piece of data, keyed by its own hash) from file_chunks (the ordered list of which chunks make up one specific file) is the one decision that makes both resumable upload and cross-user dedup work. A chunk is stored once, no matter how many files or users point at it.

Sign in to try this knowledge check.

High-level design

Client --> chunk the file locally, hash each chunk --> Upload API
                                                            |
                                        check chunk hashes against `chunks` table
                                        (skip chunks that already exist — dedup)
                                                            |
                                        upload only missing chunks --> Blob Storage (S3/GCS)
                                                            |
                              on complete: write file_chunks + files metadata (Postgres, sharded)
                                                            |
                                        publish "file_changed" event --> Sync service
                                                                              |
                                              notifies other devices (long-poll / websocket / push)
                                                                              |
                                              other devices pull /sync/changes, download new chunks

Deep dives

How does resumable upload work, and why does it come almost for free?

The client splits the file into fixed-size chunks, hashes each one locally, and sends the list of hashes to upload/init. The server checks each hash against the chunks table and responds with only the ones it doesn't already have, whether from an earlier partial upload by this same client, or from another user entirely (cross-user dedup, covered next). The client uploads just those missing chunks.

If the connection drops halfway through, the client simply calls init again on retry, and the server reports whatever chunks are still missing. Resume isn't a special protocol bolted on top, it falls naturally out of content-addressing: the server already knows exactly what it has and doesn't.

How does deduplication actually save storage?

Because chunks are stored by content hash rather than by owner or file, two different users uploading the same file, or two files sharing a common chunk like a document template, physically store that chunk exactly once. ref_count on the chunks table tracks how many file_chunks rows point at it, and garbage collection only deletes the underlying blob once that count hits zero. This is the single biggest storage-cost lever in the whole system: popular installers, templates, and stock assets let real physical storage land well below the logical total.

Remember: dedup only saves storage; it never changes who can access a file. Ownership and permissions live entirely in the metadata layer (files/shares), so sharing a chunk's bytes never leaks another user's content.

Sign in to try this knowledge check.

How does sync across devices, and conflict handling, work?

Each device keeps a local cursor, a token representing "the last change I've seen." On reconnect, or periodically, it calls GET /sync/changes?since_cursor= to pull only what changed since then, instead of re-listing the entire file tree. For near-real-time sync, a lightweight WebSocket or long-poll connection pushes a "something changed, go pull" signal, so devices don't have to poll aggressively; the actual change data still flows through the pull endpoint, keeping the protocol simple and resumable.

Conflicts happen when two devices edit the same file while offline and then both reconnect. Detect this with version numbers: each device remembers the version it last synced from, and if the server's current version has moved past that when the device tries to push its own edit, that's a real conflict, not a simple fast-forward. Don't silently overwrite one edit with the other. Write both: filename.docx and filename (conflicted copy from Device B, 2026-07-16).docx, exactly what Dropbox actually does, and let the person reconcile manually. True automatic merging only works for structured, mergeable formats (like a Google Docs-style editor), not arbitrary binary files.

Trade-offs and follow-up questions

Decision Benefit Cost
Content-addressed chunking Resume and cross-user dedup come for free Client-side hashing cost; garbage collection needs correct ref-counting
Blob storage for bytes, database for metadata Each layer scales on its own axis Two systems to keep consistent: a file only "exists" once both agree
Push notification plus pull sync Near-real-time without constant polling A little extra complexity running a signaling channel alongside the pull API
Conflicted-copy resolution Never silently loses data Worse UX than a true merge, acceptable since true merge isn't possible for arbitrary binary files

Q: How do you avoid re-uploading a file that a different user already uploaded? A: Chunk hashing plus content-addressed storage. If another user's file shares identical chunks, or the whole file matches by content_hash, upload/init reports those chunks as already present and the client skips uploading them. Storage is physically shared through ref_count; access is still enforced entirely at the metadata layer, so dedup never leaks content between users.

Q: What if two different chunks hash to the same value but aren't actually identical? A: Use a cryptographically strong hash like SHA-256, where a collision is astronomically unlikely, unlikely enough that essentially every production system treats a hash match as a content match. If extra caution is required, add a cheap secondary check like byte-length comparison before treating two chunks as identical.

Q: How do you delete a file without breaking other files that share its chunks through dedup? A: Deleting a file removes its file_chunks rows and decrements ref_count on each chunk it referenced. The underlying blob is only queued for garbage collection once ref_count reaches zero, meaning no other file still needs it. That's exactly why ref-counting, not just tracking a file ID, is required for safe dedup-aware deletion.

Sign in to try this knowledge check.
PreviousDesign a Search Autocomplete SystemNextDesign Google Docs

Course progress

0%
0 of 177 modules complete

On this page

  • Requirements
  • Estimates
  • API
  • Data model
  • High-level design
  • Deep dives
  • How does resumable upload work, and why does it come almost for free?
  • How does deduplication actually save storage?
  • How does sync across devices, and conflict handling, work?
  • Trade-offs and follow-up questions