Performing a Resumable Upload

This page describes how to make a resumable upload request in the Drive API.
This protocol allows you to resume an upload operation after a
communication failure interrupts the flow of data. Use this option if:

You are transferring large files.

The likelihood of a network interruption or some other transmission failure
is high (for example, if you are uploading a file from a mobile app).

Resumable uploads can also reduce your bandwidth usage when there is a network
failure, because you don't have to restart large file uploads from the
beginning.

Learn about request URIs

When you upload media, you use a special URI. In fact, methods that support
media uploads have two URI endpoints:

The /upload URI, for the media. The format of the /upload endpoint is the
standard resource URI with an /upload prefix. Use this URI when transferring
the media data itself. Example: POST /upload/drive/v3/files.

The standard resource URI, for the metadata. If the resource contains any
data fields, those fields are used to store metadata describing the uploaded
file. You can use this URI when creating or updating metadata values.
Example: POST /drive/v3/files/.

Initiating a resumable upload session

To initiate a resumable upload session:

Create a request to the method's /upload URI. To create a new file, use
POST. To update an existing file, use PUT.

If you have metadata for the file, add the metadata to the request body in
JSON format. Otherwise, leave the request body empty.

Add the following HTTP headers:

X-Upload-Content-Type. Optional. Set to the MIME type of the file data,
which will be transferred in subsequent requests. If the MIME type of the
data is not specified in metadata or through this header, the object will
be served as
application/octet-stream.

X-Upload-Content-Length. Optional. Set to the number of bytes of file
data, which will be transferred in subsequent requests.

Content-Type. Required if you have metadata for the file. Set to
application/json; charset=UTF-8.

Content-Length. Required unless you are using chunked transfer
encoding. Set to the number of bytes in the body of this
initial request.

Send the request.

Example: Initiating a resumable upload session

The following example shows how to initiate a resumable session to upload
a new file:

Saving the resumable session URI

If the session initiation request succeeds, the response includes a 200 OK
HTTP status code. In addition, it includes a Location header that specifies
the resumable session URI. Use the resumable session URI to upload the file data
and query the upload status.

Note: A resumable session URI expires after one week.

Copy and save the resumable session URI so you can use it for subsequent
requests.

Example: Saving the resumable session URI

The following example shows a response that includes a resumable session URI:

Uploading the file

In a single request. This approach is usually best, since it requires
fewer requests and thus has better performance.

In multiple chunks. Use this approach if:

You need to reduce the amount of data transferred in any single request.
You might need to do this when there is a fixed time limit for individual
requests, as is true for certain classes of Google App Engine requests.

You need to provide a customized indicator showing the upload progress.

Single request

To upload the file in a single request:

Create a PUT request to the resumable session URI.

Add the file's data to the request body.

Add a Content-Length HTTP header, set to the number of bytes in the
file.

Multiple chunks

To upload the file in multiple chunks:

Create a PUT request to the resumable session URI.

Add the chunk's data to the request body. Create chunks in multiples of
256 KB (256 x 1024 bytes) in size, except for the final chunk that completes
the upload. Keep the chunk size as large as possible so that the upload is
efficient.

Add the following HTTP headers:

Content-Length. Set to the number of bytes in the current chunk.

Content-Range: Set to show which bytes in the file
you are uploading. For example, Content-Range: bytes 0-524287/2000000
shows that you are uploading the first 524,288 bytes (256 x 1024 x 2) in
a 2,000,000 byte file.

Repeat steps 1 through 4 for each remaining chunk in the file. Use the
Range header in the response to determine where to start the next chunk.
Do not assume that the server received all bytes sent in the previous
request.

When the entire file upload is complete, you receive a 200 OK or 201
Created response, along with any metadata associated with the resource.

Example: Uploading the file

Single request

The following example shows a resumable request to upload an entire
2,000,000-byte JPEG file, using the resumable session URI obtained in the
previous step:

Use the upper value returned in the Range header to determine where to
start the next chunk. Continue to PUT each chunk of the file until the
entire file has been uploaded.

When the entire upload is complete, you receive a 200 OK or 201 Created
response, along with any metadata associated with the resource.

Resuming an interrupted upload

If an upload request is terminated before receiving a response, or if you
receive a 503 Service Unavailable response, then you need to resume the
interrupted upload. To do this:

To request the upload status, create an empty PUT request to the resumable
session URI.

Add a Content-Range header indicating that the current position in the file
is unknown.

For example, set the Content-Range to */2000000 if your total
file length is 2,000,000 bytes.

If you don't know the full size of the file, set the Content-Range to
*/*.

Send the request.

Process the response.

A 200 OK or 201 Created response indicates that the upload was
completed, and no further action is necessary.

A 308 Resume Incomplete response indicates that you need to continue
uploading the file.

A 404 Not Found response indicates the upload session has expired and the
upload needs to be restarted from the beginning.

If you received a 308 Resume Incomplete response, process the response's
Range header, which specifies which bytes the server has received so far. The
response will not have a Range header if no bytes have been received yet.

For example, a Range header of bytes=0-42 indicates that the first
43 bytes of the file have been received.

Now that you know where to resume the upload, continue uploading the file,
either by sending the remaining data or by sending the next chunk. Include a
Content-Range header indicating which portion of the file you are sending.

For example, Content-Range: bytes 43-1999999/2000000 indicates that you
are sending bytes 43 through 1,999,999.

Handling errors

When uploading media, be sure to follow these best practices related to error
handling:

Resume or retry uploads that fail due to connection interruptions or any 5xx
errors, including:

500 Internal Server Error

502 Bad Gateway

503 Service Unavailable

504 Gateway Timeout

Resume or retry uploads that fail due to 403 rate limit errors.

Use an exponential backoff strategy if any 5xx server error is returned when
resuming or retrying upload requests. These errors can occur if a server is
getting overloaded. Exponential backoff can help alleviate these kinds of
problems when there is a high volume of requests or heavy network traffic.

Restart uploads if a 404 Not Found error is received after attempting to
resume or upload a chunk. This indicates the upload session has expired and
must be restarted from the beginning. Upload sessions expire after
1 week of inactivity.