Resumable uploads explained
A resumable upload is a conversation, not a single request. The client sends pieces and the server keeps count. After a break, they agree on where to continue. This is how the tus protocol does it.
A resumable upload splits a file into chunks and tracks how many bytes the server has received. After a break, the client asks the server how far it got and carries on from there. The tus protocol does this over plain HTTP with a few extra headers. VideoBB uses it for every upload.
HTTP was designed around the idea that a request either completes or fails. That is fine for a page. It is hopeless for a two-gigabyte file, where one request may need to stay open for half an hour. Over that time, the network will almost surely drop at least once. Resumable uploads fix that mismatch. Several services have invented their own versions, but one open protocol has become the common reference.
This guide explains tus, the protocol VideoBB uses. It shows what the browser and server say to each other during an upload. It explains why recovery is so cheap and what the optional extensions add. No code is needed to follow it. The request-level view will make sense to anyone who has opened a browser's network tab. For the rest of the upload journey, start at the uploading video hub.
The problem with one big request
A traditional file upload is a single POST with the file in the body. The server reads the body from the start and, when it ends, has the file. If the connection breaks at any point, the server holds an incomplete body and must discard it. It cannot know whether the client will continue. The client, for its part, cannot ask how far the server got. On retry it starts from byte zero. A single request also has to pass through every proxy and load balancer on the path. Each has its own limit on request size and its own idea of how long a request may stay open. MDN documents the 413 Content Too Large response that results when a limit is exceeded. For a small file none of this matters. For a video it is the whole problem.
Resumable means that an upload can be interrupted at any moment and can be resumed without re-uploading the previous data again.
tus resumable upload protocol, tus.io
The core idea: offsets
The tus protocol replaces the one big request with a small conversation. The client first creates an upload on the server, telling it the total length. The server replies with a URL that represents this specific upload. The client then sends the file's bytes in PATCH requests to that URL, each declaring the offset at which its data begins. The server appends the data and records the new offset. If the connection breaks, the client sends a HEAD request to the same URL, and the server replies with the offset it currently holds. The client resumes from exactly that byte. Every request is ordinary HTTP with a handful of extra headers, so it passes through proxies, CDNs and load balancers like any other traffic.
The requests in a tus upload
The core protocol uses three request types; the headers below are the ones that carry the state.
| Request | Purpose | Key headers |
|---|---|---|
| POST (creation extension) | Create the upload and learn its URL | Upload-Length, Upload-Metadata; response carries Location |
| PATCH | Send a chunk starting at a known offset | Upload-Offset, Content-Type: application/offset+octet-stream |
| HEAD | Ask how many bytes the server holds | Response carries Upload-Offset and Upload-Length |
| OPTIONS | Discover which extensions the server supports | Tus-Version, Tus-Extension, Tus-Max-Size |
| DELETE (termination extension) | Abandon an upload and free its storage | Tus-Resumable |
What happens on the client
The browser never loads the whole file into memory. It holds a reference to the file the user chose and reads it in slices with Blob.slice. Each slice becomes the body of one PATCH request. Chunk size is the client's choice. Larger chunks mean fewer requests and less overhead, but more data lost when a chunk fails partway. Smaller chunks mean the opposite. Clients typically pick something in the range of a few megabytes to a few tens of megabytes. On a failed request the client waits, retries the HEAD, and continues. All of this happens inside the upload page. So the user sees a progress bar that pauses and continues, not an error and a restart. The 2 GB upload guide covers what the user can do to help it along.
What happens on the server
The server's job is to store each chunk at the right position and to answer HEAD requests accurately. It must never report an offset higher than the bytes it has durably written, or a resumed upload will have a hole. This is why a tus server writes chunks to storage before acknowledging them, and why the acknowledged offset is the only source of truth. Once the offset equals the declared length, the upload is complete. The file then moves to the next stage. On VideoBB that means probing it and starting transcoding. What is video hosting follows the file from there.
The optional extensions and why they exist
The core protocol is deliberately minimal. Extensions add what particular deployments need. Creation lets the client make a new upload with a POST rather than requiring a URL to exist already; almost every server supports it. Expiration lets the server say how long an unfinished upload will be kept before it is discarded, which stops abandoned uploads consuming storage forever. Checksum lets the client attach a hash to each chunk. The server can then catch damage in transit, instead of finding it when the video fails to decode. Termination lets a client cancel an upload it no longer wants. Concatenation lets several partial uploads be combined into one, which enables uploading chunks in parallel. A server advertises which of these it supports in the Tus-Extension header of an OPTIONS response.
One request vs resumable
The same 2 GB upload, interrupted once at the 90 percent mark.
Single POST
- One request, one connection, one chance
- Server discards the partial body on interruption
- Client retries from byte zero: 1.8 GB re-sent
- Subject to proxy body-size limits and request timeouts
- Whole file may be buffered in memory or on disk before processing
tus
- Many small requests to one upload URL
- Server keeps every chunk it has acknowledged
- Client reads the offset and re-sends only the interrupted chunk
- Each request is small enough for any proxy
- Chunks are written as they arrive; nothing is buffered whole
What resumable does not fix
It is worth being precise about the limits. Resumable uploads make interruptions cheap. They do not make a slow connection fast, and they cannot help with a file the server will refuse. A file over the size limit will be rejected at creation, since the client declares the length up front and the server compares it with Tus-Max-Size. A file in an unsupported container will be accepted by tus, which is agnostic about content, and then rejected by the probe that runs afterwards. And a truncated source uploads perfectly and plays badly. Why video uploads fail separates these cases, and upload speed and time covers the part resumability cannot change.
Frequently asked questions
Is tus specific to VideoBB?
No. tus is an open protocol with a public specification and open-source client and server implementations. VideoBB uses it because it is a well-understood standard rather than a proprietary scheme. Any tus client library can talk to any tus server, which is part of the point.
What chunk size should an uploader use?
There is no single right answer; it is a trade-off. Larger chunks reduce request overhead but lose more data when a request fails. Most clients settle on a few megabytes to a few tens of megabytes. On an unreliable connection, smaller chunks recover more cheaply; on a fast wired connection, larger chunks are more efficient.
Can an upload resume on a different device?
The protocol allows it if the client knows the upload URL and has the same file. But browser clients usually store that URL locally, so in practice you resume from the same browser. The safest expectation is that resuming works from the machine and browser where the upload began. On VideoBB that means the same browser within 48 hours, as the help page on resuming an interrupted upload sets out.
How long does the server keep an unfinished upload?
That is governed by the expiration extension. The server tells the client how long it will hold the partial upload, and discards it afterwards to free storage. The exact window is a server setting, and on VideoBB it is 48 hours. If you return after it has passed, the upload starts again from the beginning.
Sources
- tus resumable upload protocol 1.0.0 — The full specification, including the core protocol and extensions.
- MDN: Blob.slice() — The browser API used to read a file in chunks.
- MDN: 413 Content Too Large — The failure mode single-request uploads hit at proxies.
- MDN: HTTP request methods — PATCH, HEAD, OPTIONS and DELETE as used by tus.
Related guides

How to upload 2 GB video files
Large uploads fail for boring reasons: a sleeping laptop, a flaky Wi-Fi hop, a file that was never going to be accepted. Here is how to get a big file up in one go, and what to do when it stops.

Why video uploads fail
An upload that stops, stalls, restarts or is rejected is almost always one of a short list of causes. Learn to tell them apart from what the browser shows you, and fix the right one.

What is video hosting?
A plain-English tour of what a video host does with your file after upload. It also shows the point where a video tag on your own server stops being enough.

Video upload speed and time
Upload time is file size divided by upload speed, and upload speed is the number nobody checks. Here are the sums, a reference table and the few changes that really help.