How to Build a Secure File Sharing Platform Like Dropbox: Sync Architecture, Permissions, and Real Costs
Building a file sharing platform requires S3 object storage, chunked upload, versioning, permissions, document preview, full-text search, and encryption with access logging. RaftLabs builds these for law firms, healthcare, and SaaS. Web-only costs $120K-$160K, 12-14 weeks.
Key Takeaways
- Files go in object storage (AWS S3, Cloudflare R2). The database stores only metadata: file_id, name, size, mime_type, s3_key, owner_id, folder_id, version_id. Never store file bytes in the database. S3 costs $0.023 per GB per month, making a 10TB platform cost $230 per month in storage.
- Chunked multipart upload handles large files and network interruptions. Split files over 5MB into 5-10MB chunks, upload each to S3 via a pre-signed URL, then call CompleteMultipartUpload. The client can resume from the last successful chunk if interrupted.
- File versioning is built into S3. Enable bucket versioning and track each version in the database with version_number, s3_version_id, size, and uploaded_by. Set a lifecycle rule to delete versions older than 180 days or beyond the last 100.
- Desktop sync is the hardest technical component. The client watches a local folder using OS-level file system events, uploads changes, and polls for remote changes. Plan 8-12 weeks and $60K-$100K for this component alone.
- Build custom when data residency requirements rule out third-party services (HIPAA, EU data laws), when files are the core product experience (a law firm client portal), or when you need file storage as an embedded feature inside your own SaaS product.
Dropbox costs $15-$24 per user per month. Box costs $15-$35. For a 200-person team, that is $36,000-$84,000 per year. That number sounds like the argument for building your own. It is not.
Gartner's 2024 Cloud File Storage Market Guide estimates the cloud file storage market at $12.9 billion in 2024, growing at 17% annually. The growth is not from companies switching away from Dropbox. It is from teams building file storage as a feature inside vertical SaaS products where general-purpose consumer tools don't fit. IBM's 2024 Cost of a Data Breach Report found that data breaches involving cloud-stored files cost an average of $4.88 million. For regulated industries, data residency and access control requirements are the primary driver of custom builds.
"The organizations getting burned on cloud storage are the ones who let Dropbox sprawl across their company without access controls, then discovered in an audit that former employees still had access to sensitive documents. Purpose-built file storage with proper permission models and access logging isn't a luxury -- it's what compliance requires." -- Rich Campagna, former CISO at Barracuda Networks, speaking at RSA Conference 2024
The real reasons to build a custom file storage platform are control, compliance, and integration. A law firm's client portal where files drive the entire client relationship. A healthcare SaaS where HIPAA requires data to stay in specific regions and Dropbox cannot sign a BAA that covers your architecture. A company building a vertical SaaS product that needs file storage as an embedded feature, not as a separate tool users have to log into. A financial services firm with data residency requirements that mean EU client data cannot touch US servers.
Cost savings might appear after year three once you factor in the infrastructure. But cost is not the decision. Control is.
This article is the technical blueprint. The storage architecture, versioning, sharing model, large file uploads, document preview, search, security, and the honest cost and timeline for each component.
Who builds this
Five categories of teams build custom file storage platforms.
SaaS companies building a product where file management is a core feature, not an add-on. A legal tech company building a matter management platform needs document storage baked in, not linked out to Dropbox. A healthcare company building a patient record system cannot store documents in a consumer cloud storage tool.
Organizations with data residency requirements. EU companies operating under GDPR with strict data localization. Healthcare companies under HIPAA. Financial services firms with regulator-imposed data controls. When third-party services cannot meet these requirements, you build.
Companies building vertical-specific document portals. An architecture firm where project drawings, specifications, and RFIs flow between the firm, the contractor, and the client. A legal discovery portal where attorneys share case documents with structured access controls. A construction firm where building plans, permits, and inspection reports have a defined lifecycle.
Enterprises building internal document management systems where integration with internal tools (ERP, CRM, HR systems) is the primary requirement. No consumer file sharing tool integrates deeply enough.
Startups building a Dropbox competitor for a specific niche with specific workflow requirements that Dropbox's general-purpose UI does not serve.
Core storage architecture
AWS reports that S3 stores over 350 trillion objects and processes more than 100 million requests per second. At $0.023 per GB per month, a 10TB platform costs $230 per month in storage. The CDN costs for frequent downloads usually exceed storage costs. Design your cost model around egress, not storage.
The rule is simple: files go in object storage, metadata goes in the database.
AWS S3, Google Cloud Storage, and Cloudflare R2 are all viable. S3 is the default for most teams because of its tooling depth, CDN integration with CloudFront, and the mature Multipart Upload API. Cloudflare R2 eliminates egress fees, which matters if your files are downloaded at high volume. For a file-heavy application, R2 can reduce monthly costs significantly.
S3 costs $0.023 per GB per month. A platform with 10TB of stored files costs $230 per month in storage. That number scales linearly. The CDN costs for serving downloads are often higher than the storage costs.
The database stores file metadata: file_id, name, size, mime_type, s3_key, owner_id, folder_id, version_id, created_at, deleted_at. The s3_key is the path inside the S3 bucket. The file bytes never touch your database. Every query for a file goes to the database for the key, then to S3 (or CloudFront) for the bytes.
File access works through pre-signed URLs. When a user requests to download a file, your server generates a pre-signed S3 URL that expires in 15 minutes (or however long you choose) and redirects the browser to it. The file transfers directly from S3 to the user. Your server is not in the data path. This is correct for performance and cost.
Never serve files by reading them from S3 into your server's memory and piping them to the client. That approach kills your server under load.
Chunked upload for large files
Files over 5MB need chunked upload. Without it, a network interruption mid-upload forces the user to start over. For a 500MB design file or a 2GB video, that is unacceptable.
AWS S3 Multipart Upload handles this. The flow:
The client requests an upload from your server. Your server creates a Multipart Upload on S3 and generates pre-signed URLs, one per chunk. A 100MB file split into 10MB chunks needs 10 pre-signed URLs. The server returns the upload ID and all the URLs to the client.
The client splits the file into chunks and uploads each directly to S3 using the pre-signed URL for that chunk. Uploads can happen in parallel (3-5 at once is a good default). Each successful chunk upload returns an ETag from S3.
When all chunks are uploaded, the client sends the list of ETags to your server. Your server calls CompleteMultipartUpload on S3. S3 assembles the chunks into a single object.
If the upload fails mid-way, the client stores which chunks succeeded. On retry, it only uploads the failed chunks. The upload resumes from where it stopped.
Set an S3 lifecycle rule to abort and delete incomplete multipart uploads after 7 days. Otherwise, partial uploads accumulate and you pay for storage you cannot use.
File versioning
Every time a user uploads a file with the same name to the same folder, create a new version. Do not overwrite the previous file.
S3 supports versioning natively. Enable versioning on the bucket. Every upload to the same key generates a new s3_version_id. Old versions are preserved automatically.
Your database tracks versions separately: a file_versions table with file_id, version_number, s3_version_id, size, uploaded_by, uploaded_at. The files table's version_id column points to the current version.
Users can view version history and restore any previous version. Restoring a version creates a new version record pointing to the old s3_version_id. The original file bytes are never re-uploaded. S3 serves the old version using its version ID.
Set a retention policy: keep the last 100 versions, or versions from the last 180 days, whichever is fewer. Use an S3 Lifecycle rule to expire older versions. Without a lifecycle rule, version storage compounds fast for frequently updated files.
Sharing and permissions
File sharing has two modes and the architecture for each is different.
Internal sharing works through a permissions table. Each row records which user (or team) has which permission level on which file or folder: resource_id, resource_type (file or folder), principal_id, principal_type (user or team), permission (view, comment, edit, owner). Folder permissions cascade down to files unless a file has its own explicit permissions row.
Four permission levels cover most use cases. Owner: can delete, move, and manage sharing. Edit: can upload new versions and rename. Comment: can add comments but not change the file. View: read-only access.
External sharing generates a link. Three link types cover the common cases. Public: anyone with the link can access the file, no login required. Password-protected: the link requires a password before access is granted. Expiring: the link expires after a set time (7 days by default) or a set number of downloads (100 downloads is a reasonable default). Store external links in a share_links table: link_id, file_id, link_type, password_hash, expires_at, max_downloads, download_count, created_by.
Access revocation is important for security. When an employee leaves, an admin should be able to remove all their file access in one action. Build an admin view that shows all files shared with a user, and a bulk revocation endpoint.
Document preview and in-browser viewing
Users expect to preview a file without downloading it. Six file categories require different approaches.
PDFs render in-browser using PDF.js. Serve the PDF from CloudFront and let PDF.js handle rendering in a canvas element. No server-side work needed beyond storage.
Images (JPEG, PNG, WebP, GIF) serve directly from CloudFront. A CloudFront distribution in front of S3 handles CDN caching and geographic distribution. Image thumbnails for file listing views: generate them on upload using Sharp (Node.js) and store the thumbnail separately in S3.
Office documents (Word, Excel, PowerPoint) are the tricky ones. Options: run LibreOffice headless in a Docker container, convert the document to PDF at upload time, store the PDF version in S3, and serve the PDF preview via PDF.js. This works well and is fully self-contained. The alternative is using the Microsoft Office Online viewer (an iframe embed), which is free for publicly accessible files but requires the file to be publicly reachable.
Video files: convert to HLS (HTTP Live Streaming) format at upload time using ffmpeg or AWS MediaConvert. HLS breaks the video into small segments that stream progressively. A video.js or Plyr player in the browser plays the HLS stream. Users see video immediately without waiting for the full file to download.
Code files and plain text: syntax-highlighted preview via Prism.js. Read the file text from S3 and render it with syntax highlighting based on the file extension.
The document conversion pipeline (LibreOffice, ffmpeg) runs as a background job triggered after upload. Store the preview in S3 under a separate key with a _preview suffix. The file detail page polls for the preview until it is ready.
Search
Users need to find files by name and by content. Both are different problems.
Filename and folder search is a simple PostgreSQL full-text search on the files and folders tables. Filter by the user's accessible files using the permissions model.
Content search across file contents (finding "indemnification clause" inside a Word document) requires more work. At upload time, extract the text from documents. Use Apache Tika (a Java library that extracts text from hundreds of file formats) or AWS Textract (for PDFs and scanned images). Store the extracted text and index it in Elasticsearch.
Elasticsearch handles document-level security. Each indexed document includes the list of user IDs and team IDs with access. Every search query filters by the current user's access. Only accessible files appear in results.
For image and video files, search by filename and metadata only. AI-powered image search (searching by content of photos) is a separate, expensive feature. Skip it in the first version.
Add a typeahead endpoint with 200ms debounce on the client. Return the top 5 filename matches inline. A full search results page shows content matches with snippets.
Encryption and security
Most platforms need two things: encryption at rest and encryption in transit.
Encryption at rest: enable S3 server-side encryption. SSE-S3 (S3-managed keys) is the baseline. SSE-KMS (using AWS Key Management Service with your own managed key) gives you control over the encryption key, which is required for HIPAA and SOC 2. The difference in complexity is minimal. Default to SSE-KMS.
Encryption in transit: HTTPS everywhere. TLS 1.3 on all endpoints. No exceptions.
Zero-knowledge encryption (client-side encryption where the server never sees the plaintext file) is a separate category. The file is encrypted using the Web Crypto API before the bytes leave the user's device. The encryption key never leaves their browser. This means your server cannot generate previews, cannot index content for search, and cannot recover files if a user loses their key. It is correct for specific high-security use cases and significantly raises complexity. Do not default to it.
Antivirus scanning: scan every uploaded file before making it accessible. ClamAV is free and open source. Trend Micro File Security API is a managed alternative. Trigger a scan after the file lands in S3 using an S3 event notification. If the file fails the scan, mark it as quarantined, prevent access, and notify the uploader.
Access logging: every file access event must be logged. user_id, file_id, action (view, download, share, delete), ip_address, user_agent, timestamp. This is required for HIPAA audit trails and SOC 2 compliance. Store logs in a separate append-only table or ship them to a log management service (Datadog, AWS CloudWatch Logs).
The desktop sync client
The desktop sync client is the most technically complex component of a Dropbox alternative. It is also the feature most users expect from a Dropbox replacement.
The sync client does two things. It watches a local folder for changes and uploads them to the server. It also polls the server for changes made on other devices and downloads them.
File watching uses OS-level APIs: inotify on Linux, FSEvents on macOS, ReadDirectoryChangesW on Windows. The client listens for create, modify, rename, and delete events. When a file changes, it uploads the new version. When a file is deleted, it moves it to the server-side trash.
Conflict resolution is the hard problem. If a file is modified on two different devices while both are offline, you have two diverging versions. The standard resolution: create a conflict copy with the filename pattern document (username's conflicted copy 2026-05-24).pdf. Both versions are preserved. The user resolves the conflict manually.
Desktop app development options: an Electron app with Node.js covers all three platforms from a single codebase and takes 12-16 weeks. White-label SDKs (Solid Sync, Tresorit's white-label) reduce that to 4-6 weeks but add licensing costs. The simplest path: build web-only first, validate the product, then add the desktop client when users ask for it.
Tech stack
Web app: React. File upload component with drag-and-drop (react-dropzone), chunked upload logic, progress indicators, and the file browser UI.
Mobile: React Native covers iOS and Android from one codebase. The mobile client needs upload, browse, download, and sharing. Preview is limited to what the device can display natively.
Desktop sync: Electron with Node.js for cross-platform, or platform-native (Swift for macOS, C++ for Windows) for better performance and OS integration.
Backend: Node.js, PostgreSQL for metadata and permissions, AWS S3 for file storage, AWS CloudFront as CDN.
Document conversion: LibreOffice headless running in a Docker container, triggered by an SQS queue message after each upload.
Search: Elasticsearch for content indexing, PostgreSQL full-text search for filename search.
Additional services: Redis for session management and rate limiting, ClamAV for antivirus, SendGrid for email notifications (share notifications, access invitations, storage quota warnings).
Cost and timeline
Web-only platform (upload, download, sharing, versioning, preview, search): $120,000-$160,000, 12-14 weeks. This covers the full feature set for in-browser use with no sync client.
Add mobile apps (iOS and Android via React Native): $50,000-$80,000 additional, 6-8 weeks.
Desktop sync client: $60,000-$100,000 additional, 8-12 weeks. This is the hardest single component.
Full Dropbox alternative (web, mobile, desktop sync, document preview, full-text search): $250,000-$380,000, 22-30 weeks.
HIPAA compliance work (SSE-KMS, access logging, audit trail, BAA-compatible architecture): add $20,000-$40,000 to any tier.
Build vs. buy: the real decision
Dropbox Pro costs $15-$24 per user per month. Box Business costs $15-$35. Google Drive is included in Workspace at $6-$18 per user per month.
For a 200-person team using Dropbox Business: $36,000-$57,600 per year. A custom platform at $160,000 breaks even in three to four years on cost alone. That is not a compelling build argument.
Build custom when one or more of these apply.
Data residency is required and third-party services cannot comply. HIPAA without a BAA. EU data that must stay in the EU. Sector-specific regulations (defense, legal, government) that prohibit third-party cloud storage.
Files are the core product. A law firm's client portal is fundamentally a file sharing application. The document relationship drives the client relationship. The firm's software is the portal. That is not a use case for Dropbox; it is the product itself.
Deep integration with proprietary systems is required. Files need to trigger workflows in your ERP, be attached to records in your CRM, or be accessible inside your own SaaS product. Third-party file tools integrate through APIs with friction. Embedded file storage has none.
You are building file storage as a feature inside your own SaaS product. Your application needs users to upload, organize, and share files within the product experience. A white-labeled Dropbox is not viable. You build it.
For everything else, Dropbox, Box, and Google Drive are excellent. The cost is not the reason to build. The control and integration are.
If you are at the point where you need custom file storage, read how to build a productivity app like Notion for the block-based content model that often sits alongside document storage in the same platform.
RaftLabs has built file storage platforms for law firms, healthcare companies, and vertical SaaS products where compliance requirements ruled out general-purpose cloud tools. The consistent finding: the compliance architecture (SSE-KMS, access logging, audit trails, BAA-compatible design) takes as long as the product features. Budget for it from the start. See our SaaS application development service for project scoping, or start with an MVP that covers web-only before adding the desktop sync client.
Frequently asked questions
- A web-only platform covering upload, download, sharing, preview, and versioning costs $120K-$160K and takes 12-14 weeks. Adding mobile apps adds $50K-$80K and 6-8 weeks. A desktop sync client adds $60K-$100K and 8-12 weeks. A full Dropbox alternative with web, mobile, desktop sync, search, and document preview costs $250K-$380K and takes 22-30 weeks. The desktop sync client is the most expensive single component because of OS-level file system integration on three platforms.
- All three are viable. AWS S3 is the default choice: the broadest tooling support, native multipart upload API, mature lifecycle rules, and deep integration with CloudFront CDN. Google Cloud Storage is the right choice if you are already in GCP. Cloudflare R2 eliminates egress fees entirely, which matters if your files are downloaded frequently. For a file-heavy application with high download volume, R2 can reduce CDN costs significantly. For most teams starting out, S3 with CloudFront is the safest and best-supported path.
- Files over 5MB should be uploaded in chunks to handle network interruptions. The flow: the server generates a set of pre-signed S3 URLs, one per chunk. The client splits the file into 5-10MB chunks and uploads each directly to S3 using the pre-signed URLs. When all chunks are uploaded, the client calls a server endpoint which calls CompleteMultipartUpload on S3. S3 assembles the chunks into a single object. If the upload is interrupted, the client resumes from the last confirmed chunk. Incomplete multipart uploads are cleaned up by an S3 lifecycle rule after 7 days to avoid orphaned storage costs.
- Each file type requires a different approach. PDFs: render in-browser via PDF.js. Images: serve directly from CloudFront CDN. Office documents (Word, Excel, PowerPoint): convert to PDF at upload time using LibreOffice headless running in a Docker container, then serve the PDF preview. Video: convert to HLS via ffmpeg or AWS MediaConvert at upload time, then stream via a video player. Code files: syntax-highlighted text preview via Prism.js. The document conversion pipeline (LibreOffice headless) runs as a background job after upload and stores the preview version separately in S3.
- For HIPAA: encryption at rest using S3 server-side encryption with KMS (SSE-KMS with your own managed key), TLS 1.3 in transit, full access logging (every view, download, and share event logged with user_id, file_id, action, ip_address, timestamp), and a BAA with your cloud provider. For SOC 2: all the above plus antivirus scanning on upload (ClamAV or Trend Micro File Security API), role-based access control, audit trail for permission changes, and administrator controls for access revocation. Zero-knowledge client-side encryption (where the server never sees the plaintext) is available via the Web Crypto API but adds significant complexity and rules out server-side preview generation.
Ask an AI
Get an instant summary of this post from your preferred AI assistant.
Related articles

How to Build Tattoo Studio Management Software
Tattoo studios run on appointment deposits, signed consent forms, and multi-session project bookings that span years. Off-the-shelf salon tools miss all three. Here is what it takes to build software that actually fits how a tattoo business operates.

How to Build MedSpa Management Software (2026)
Aesthetic Record costs $699/month per location. A chain of 20 medSpas pays $167,000 a year for software that still cannot track Botox lot numbers or handle delta consent re-signing. Here is what custom medSpa management software actually needs, what it costs to build, and when a custom build makes financial sense.

How to Build Car Wash Management Software
Unlimited monthly memberships are why modern car washes are attractive investments. The software that powers them, license plate recognition, recurring billing, and multi-location reporting, is not something you buy off the shelf without trade-offs.
