Upload files of up to 4TB and resume any interrupted transfer

Upload and download files with one API call each, while Storage resumes an interrupted transfer from the last confirmed chunk. Storage also checksums every file with CRC32C, records each version, and serves the file from a CDN URL.

Organize files with containers, labels, and versions

Whether your application uploads a file through the REST API or through a pre-signed URL, the client can resume the transfer after a dropped connection. Group files into containers, tag them with labels and metadata so that you can search for them, and restore an earlier version of a file from its history.

How Storage stores, versions, and restores your files

Resumable uploads

Upload a file from your server, or generate a signed URL so that a browser or a mobile app can upload it directly. Storage accepts files of up to 4TB through a resumable transfer, which the client can pick up again at the next unconfirmed chunk when a connection fails.

Resumable downloads

Every file has a CDN URL that supports HTTP range requests, so a client whose connection drops can fetch the remaining byte range and append it to the partial file.

Data integrity

Storage computes a CRC32C checksum when each upload completes. If you turn on MD5 hashing, Storage can also report an existing object whose content matches a file that you are about to upload.

Labels and metadata

Attach up to 50 labels and custom key-value metadata to each object, then filter the object list of a container by those labels or metadata keys. Storage indexes them, so one list call returns every matching object.

Version history

Storage assigns a unique version ID to each version of a file. You can browse the history of a file, compare two versions, and restore an earlier one within your retention window.

Archive and restore

Archive a container or an object to move it into lower-cost storage. When you need it again, restore it on demand, with a retrieval time that you configure.

Overwrite protection

Turn on overwrite protection for a file so that Storage refuses any upload that tries to replace it. Storage also gives each object a generation number, so you can detect two writers that update the same file at once.

Sync status tracking

Storage marks each object as synced, pending, or tainted. Filter the object list by that status to find a transfer that Storage still reports as pending, or a failed transfer that Storage marks as tainted.

4TB
Max file size

With resumable upload

CRC32C
Checksum verification

Data integrity on every upload

11 nines
Durability

99.999999999% data durability

Build faster with solutions designed for real-world needs

Upload files of up to 4TB from a mobile app over an unreliable connection

Storage records each chunk of a resumable upload as it receives it, so after an interruption the client can ask Storage where to continue. With a signed URL, a browser or a mobile app can send those chunks straight to Storage, so your server receives none of the file's bytes.

Impact

The screen in the sample opens a document picker for a zipped MRI scan and checks the file against the 4TB limit. It then sends the scan to the tessera-medical-scans container in 16 MB chunks and shows the percentage uploaded, while its Cancel button can abort the transfer through an AbortController signal.

Prompt for a coding agent: Upload zipped MRI scans from the phone in 16 MB chunks, with progress and a Cancel button.

Conjoin IDE

Select a file to view its contents

Find duplicate files by MD5 and confirm each upload by checksum

Storage returns a CRC32C checksum for every upload, which you can compare with the checksum of your source file to confirm the transfer. With MD5 hashing on, the checkDuplicate call looks up an MD5 hash in a container and returns any object that has the same content.

Impact

Before the sample uploads a CAD drawing to the Sankofa library, it hashes the file in the browser and calls checkDuplicate with that hash. When Storage finds a match, the page reuses the existing object and skips the upload, so the container stores one copy of each drawing.

Prompt for a coding agent: Hash each drawing in the browser, and skip the upload when Storage already has a copy.

Conjoin IDE

Select a file to view its contents

Find invoices by label and metadata key in one list call

Each object can have up to 50 labels and custom metadata. A list call can filter on labels, on metadata keys, or on both, which lets you find files by customer, project, or document type.

Impact

The invoices page in the sample lists up to 100 of the newest Knaresborough Press invoices for the fiscal year in the URL, limited to unarchived files that have a customer_id metadata key. When a user picks another year in the dropdown, the page requests the list again with that year's label.

Prompt for a coding agent: List this year's unarchived invoices that have a customer ID, newest first.

Conjoin IDE

Select a file to view its contents

Handle concurrent writes safely with generation numbers

Storage increments the generation number of an object on every write. A conditional update succeeds only when the generation that you send matches the current one, while Storage turns down any upload that tries to replace a file under overwrite protection.

Impact

When two people save the same file at once, the second save will fail with a stale generation number, so your code can merge the changes or ask the user which version to keep.

Build your next app on Conjoin

Conjoin will open with a free Build tier, while the pricing page already lists the launch prices for Pro and Business. If you tell us what you're building, we'll talk you through early access.