Dropbox is a cloud storage and collaboration platform that lets users store, sync, and share files across devices. It is commonly used by individuals and teams to organize documents, collaborate on projects, and securely access files from anywhere. Over time, Dropbox has expanded beyond file storage into productivity tools like document workflows, e-signatures, and team collaboration features.
Product Design Requirements
Functional Requirements
- Users can upload files from any device.
- Users can download files from any device.
- Users can share files with others and view files shared with them.
- Users can automatically sync files across their devices.
Non-Functional Requirements
- The system should be highly available, favoring availability over strict consistency.
- The system should support large file uploads, up to 50GB.
- The system should protect user data and provide recovery mechanisms for lost or corrupted files.
- The system should minimize latency for uploads, downloads, and file synchronization.
Design Setup
Data Model
- File: Represents the raw file content that users upload, download, share, and sync.
- FileMetadata: Stores descriptive information about a file, such as its name, size, MIME type, owner, and upload time.
- User: Represents an account in the system that can own, access, and share files.
API Design
The API is the main interface between clients and the file storage system. Defining it early helps clarify the core product behavior and guides the high-level design. At this stage, we can start with simple APIs that map directly to the functional requirements, while noting that some of them may evolve later as we discuss scalability and performance trade-offs.
Firstly, an user should be able to upload a file along with its metadata.
POST /files Request: { file, metadata }
Secondly, an user should be able to retrieve a file and its associated metadata.
GET /files/{fileId} Response: { file, metadata }
Next, user should be able to share a file with one or more other users.
POST /files/{fileId}/share Request: { users: [] }
Lastly, clients also need a way to discover remote changes so they can sync local files with the server.
GET /files/changes?since={timestamp} Response: { changes: [] }
Each change event can include the file ID, change type, and updated metadata.
{ fileId, changeType, (`created` | `updated` | `deleted`) metadata }