This page discusses XML API multipart uploads in Cloud Storage. This upload
method uploads files in parts and then assembles them into a single object using
a final request. XML API multipart uploads are compatible with Amazon S3
multipart uploads.

> [!NOTE]
> **Note:** Within the [JSON API](https://docs.cloud.google.com/storage/docs/json_api), there is an unrelated [type of single-request upload](https://docs.cloud.google.com/storage/docs/uploads) also called a "multipart upload".

## Overview

An *XML API multipart upload* lets you upload data in multiple parts and
then assemble them into a final object. This behavior has several advantages,
particularly for large files:

- You can upload parts simultaneously, reducing the time it takes to upload the
  data in its entirety.

- If one of the upload operations fails, you only have to re-upload a portion
  of the overall object, instead of restarting from the beginning.

- Since the total file size is not specified in advance, you can use XML API
  multipart uploads for [streaming uploads](https://docs.cloud.google.com/storage/docs/streaming-uploads) or for compressing data
  on-the-fly while uploading.

An XML API multipart upload has three required steps:

1. [Initiate the upload](https://docs.cloud.google.com/storage/docs/xml-api/post-object-multipart) using a `POST` request, which includes specifying
   any metadata that the completed object should have. The response returns an
   [`UploadId`](https://docs.cloud.google.com/storage/docs/xml-api/reference-headers#uploadid-multipart) that you use in all subsequent requests associated with
   the upload.

2. [Upload the data](https://docs.cloud.google.com/storage/docs/xml-api/put-object-multipart) using one or more `PUT` requests.

3. [Complete the upload](https://docs.cloud.google.com/storage/docs/xml-api/post-object-complete) using a `POST` request. This request overwrites
   any existing object in the bucket with the same name.

There is no limit to how long a multipart upload and its uploaded parts can
remain unfinished or idle in a bucket.

- Successfully uploaded parts count toward your [monthly storage usage](https://docs.cloud.google.com/storage/pricing#storage-pricing).
- You can avoid a buildup of abandoned multipart uploads by using [Object Lifecycle Management](https://docs.cloud.google.com/storage/docs/lifecycle#abort-mpu) to automatically remove multipart uploads when they reach a specified age.

## Considerations

The following limitations apply to using XML API multipart uploads:

- There are [limits](https://docs.cloud.google.com/storage/quotas#requests) to the minimum size a part can be, the maximum size a part can be, and the number of parts used to assemble the completed upload.
- [Preconditions](https://docs.cloud.google.com/storage/docs/request-preconditions) are not supported in the requests.
- [MD5 hashes](https://docs.cloud.google.com/storage/docs/metadata#md5) don't exist for objects uploaded using this method.
- This upload method is not supported in the Google Cloud console or the Google Cloud CLI.

Keep in mind the following when working with XML API multipart uploads:

- XML API multipart uploads have [specific IAM permissions](https://docs.cloud.google.com/storage/docs/access-control/iam-permissions#multipart-uploads).
  If you use [custom IAM roles](https://docs.cloud.google.com/iam/docs/creating-custom-roles), you should ensure those
  roles have the permissions you need.

- While you can initiate an upload and upload parts, the request to
  complete the upload fails if it would overwrite an object that has
  a [hold](https://docs.cloud.google.com/storage/docs/object-holds) on it or an unfulfilled [retention period](https://docs.cloud.google.com/storage/docs/bucket-lock).

- You can [list ongoing uploads](https://docs.cloud.google.com/storage/docs/xml-api/get-bucket-uploads) in a bucket, but only a completed upload
  appears in the normal list of objects in the bucket.

- An uploaded part can be subject to [early deletion charges](https://docs.cloud.google.com/storage/pricing#early-delete) if it is
  never used.

## How client libraries use XML API multipart uploads

This section provides information about performing XML API multipart uploads
with client libraries that support it.

### Client libraries


### Java


For more information, see the
[Cloud Storage Java API
reference documentation](https://cloud.google.com/java/docs/reference/google-cloud-storage/latest/overview).


To authenticate to Cloud Storage, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/storage/docs/authentication#client-libs).

The following sample initiates a multipart upload:


    import com.google.cloud.storage.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.HttpStorageOptions.html;
    import com.google.cloud.storage.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadClient.html;
    import com.google.cloud.storage.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadSettings.html;
    import com.google.cloud.storage.multipartupload.model.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.CreateMultipartUploadRequest.html;
    import com.google.cloud.storage.multipartupload.model.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.CreateMultipartUploadResponse.html;
    import java.util.HashMap;
    import java.util.Map;

    public class CreateMultipartUpload {
      public static void createMultipartUpload(String projectId, String bucketName, String objectName) {
        // The ID of your GCP project
        // String projectId = "your-project-id";

        // The ID of your GCS bucket
        // String sourceBucketName = "your-unique-bucket-name";

        // The ID of your GCS object
        // String sourceObjectName = "your-object-name";

        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.HttpStorageOptions.html storageOptions =
            https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.HttpStorageOptions.html.newBuilder().setProjectId(projectId).build();
        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadSettings.html mpuSettings = https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadSettings.html.of(storageOptions);
        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadClient.html mpuClient = https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadClient.html.create(mpuSettings);

        System.out.println("Initiating multipart upload for " + objectName);

        Map<String, String> metadata = new HashMap<>();
        metadata.put("key1", "value1");
        String contentType = "text/plain";
        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.CreateMultipartUploadRequest.html createRequest =
            https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.CreateMultipartUploadRequest.html.builder()
                .bucket(bucketName)
                .key(objectName)
                .metadata(metadata)
                .contentType(contentType)
                .build();

        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.CreateMultipartUploadResponse.html createResponse = mpuClient.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadClient.html#com_google_cloud_storage_MultipartUploadClient_createMultipartUpload_com_google_cloud_storage_multipartupload_model_CreateMultipartUploadRequest_(createRequest);
        String uploadId = createResponse.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.CreateMultipartUploadResponse.html#com_google_cloud_storage_multipartupload_model_CreateMultipartUploadResponse_uploadId__();
        System.out.println("Upload ID: " + uploadId);
      }
    }

The following sample uploads an individual object part:


    import com.google.cloud.storage.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.HttpStorageOptions.html;
    import com.google.cloud.storage.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadClient.html;
    import com.google.cloud.storage.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadSettings.html;
    import com.google.cloud.storage.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.RequestBody.html;
    import com.google.cloud.storage.multipartupload.model.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.UploadPartRequest.html;
    import com.google.cloud.storage.multipartupload.model.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.UploadPartResponse.html;
    import java.io.IOException;
    import java.nio.ByteBuffer;
    import java.util.Random;

    public class UploadPart {
      public static void uploadPart(
          String projectId, String bucketName, String objectName, String uploadId, int partNumber)
          throws IOException {
        // The ID of your GCP project
        // String projectId = "your-project-id";

        // The ID of your GCS bucket
        // String bucketName = "your-unique-bucket-name";

        // The ID of your GCS object
        // String objectName = "your-object-name";

        // The ID of the multipart upload
        // String uploadId = "your-upload-id";

        // The part number of the part being uploaded
        // int partNumber = 1;

        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.HttpStorageOptions.html storageOptions =
            https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.HttpStorageOptions.html.newBuilder().setProjectId(projectId).build();
        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadSettings.html mpuSettings = https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadSettings.html.of(storageOptions);
        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadClient.html mpuClient = https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadClient.html.create(mpuSettings);

        // The minimum part size for a multipart upload is 5 MiB, except for the last part.
        byte[] bytes = new byte[5 * 1024 * 1024];
        new Random().nextBytes(bytes);
        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.RequestBody.html requestBody = https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.RequestBody.html.of(ByteBuffer.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.HttpStorageRpcHasherHelper.html#com_google_cloud_storage_HttpStorageRpcHasherHelper_wrap_java_io_OutputStream_boolean_(bytes));

        System.out.println("Uploading part " + partNumber);
        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.UploadPartRequest.html uploadPartRequest =
            https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.UploadPartRequest.html.builder()
                .bucket(bucketName)
                .key(objectName)
                .partNumber(partNumber)
                .uploadId(uploadId)
                .build();

        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.UploadPartResponse.html uploadPartResponse = mpuClient.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadClient.html#com_google_cloud_storage_MultipartUploadClient_uploadPart_com_google_cloud_storage_multipartupload_model_UploadPartRequest_com_google_cloud_storage_RequestBody_(uploadPartRequest, requestBody);

        System.out.println("Part " + partNumber + " uploaded with ETag: " + uploadPartResponse.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.UploadPartResponse.html#com_google_cloud_storage_multipartupload_model_UploadPartResponse_eTag__());
      }
    }

The following sample lists object parts:


    import com.google.cloud.storage.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.HttpStorageOptions.html;
    import com.google.cloud.storage.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadClient.html;
    import com.google.cloud.storage.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadSettings.html;
    import com.google.cloud.storage.multipartupload.model.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.ListPartsRequest.html;
    import com.google.cloud.storage.multipartupload.model.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.ListPartsResponse.html;
    import com.google.cloud.storage.multipartupload.model.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.Part.html;

    public class ListParts {
      public static void listParts(
          String projectId, String bucketName, String objectName, String uploadId) {
        // The ID of your GCP project
        // String projectId = "your-project-id";

        // The ID of your GCS bucket
        // String bucketName = "your-unique-bucket-name";

        // The ID of your GCS object
        // String objectName = "your-object-name";

        // The ID of the multipart upload
        // String uploadId = "your-upload-id";

        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.HttpStorageOptions.html storageOptions =
            https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.HttpStorageOptions.html.newBuilder().setProjectId(projectId).build();
        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadSettings.html mpuSettings = https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadSettings.html.of(storageOptions);
        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadClient.html mpuClient = https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadClient.html.create(mpuSettings);

        System.out.println("Listing parts for upload ID: " + uploadId);

        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.ListPartsRequest.html listPartsRequest =
            https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.ListPartsRequest.html.builder().bucket(bucketName).key(objectName).uploadId(uploadId).build();

        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.ListPartsResponse.html listPartsResponse = mpuClient.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadClient.html#com_google_cloud_storage_MultipartUploadClient_listParts_com_google_cloud_storage_multipartupload_model_ListPartsRequest_(listPartsRequest);

        if (listPartsResponse.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.ListPartsResponse.html#com_google_cloud_storage_multipartupload_model_ListPartsResponse_parts__() == null || listPartsResponse.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.ListPartsResponse.html#com_google_cloud_storage_multipartupload_model_ListPartsResponse_parts__().isEmpty()) {
          System.out.println("No parts have been uploaded yet.");
          return;
        }

        System.out.println("Uploaded Parts:");
        for (https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.Part.html part : listPartsResponse.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.ListPartsResponse.html#com_google_cloud_storage_multipartupload_model_ListPartsResponse_parts__()) {
          System.out.println("  - Part Number: " + part.partNumber());
          System.out.println("    ETag: " + part.eTag());
          System.out.println("    Size: " + part.size() + " bytes");
          System.out.println("    Last Modified: " + part.lastModified());
        }
      }
    }

The following sample completes a multipart upload:


    import com.google.cloud.storage.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.HttpStorageOptions.html;
    import com.google.cloud.storage.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadClient.html;
    import com.google.cloud.storage.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadSettings.html;
    import com.google.cloud.storage.multipartupload.model.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.CompleteMultipartUploadRequest.html;
    import com.google.cloud.storage.multipartupload.model.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.CompleteMultipartUploadResponse.html;
    import com.google.cloud.storage.multipartupload.model.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.CompletedMultipartUpload.html;
    import com.google.cloud.storage.multipartupload.model.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.CompletedPart.html;
    import java.util.List;

    public class CompleteMultipartUpload {
      public static void completeMultipartUpload(
          String projectId,
          String bucketName,
          String objectName,
          String uploadId,
          List<CompletedPart> completedParts) {

        // The ID of your GCP project
        // String projectId = "your-project-id";

        // The ID of your GCS bucket
        // String bucketName = "your-unique-bucket-name";

        // The ID of your GCS object
        // String objectName = "your-object-name";

        // The ID of the multipart upload
        // String uploadId = "your-upload-id";

        // The list of completed parts from the UploadPart responses.
        // List<CompletedPart> completedParts = ...;

        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.HttpStorageOptions.html storageOptions =
            https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.HttpStorageOptions.html.newBuilder().setProjectId(projectId).build();
        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadSettings.html mpuSettings = https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadSettings.html.of(storageOptions);
        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadClient.html mpuClient = https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadClient.html.create(mpuSettings);

        System.out.println("Completing multipart upload for " + objectName);

        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.CompletedMultipartUpload.html completedMultipartUpload =
            https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.CompletedMultipartUpload.html.builder().parts(completedParts).build();

        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.CompleteMultipartUploadRequest.html completeRequest =
            https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.CompleteMultipartUploadRequest.html.builder()
                .bucket(bucketName)
                .key(objectName)
                .uploadId(uploadId)
                .multipartUpload(completedMultipartUpload)
                .build();

        https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.CompleteMultipartUploadResponse.html completeResponse =
            mpuClient.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.MultipartUploadClient.html#com_google_cloud_storage_MultipartUploadClient_completeMultipartUpload_com_google_cloud_storage_multipartupload_model_CompleteMultipartUploadRequest_(completeRequest);

        System.out.println(
            "Upload complete for "
                + completeResponse.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.CompleteMultipartUploadResponse.html#com_google_cloud_storage_multipartupload_model_CompleteMultipartUploadResponse_key__()
                + " in bucket "
                + completeResponse.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.CompleteMultipartUploadResponse.html#com_google_cloud_storage_multipartupload_model_CompleteMultipartUploadResponse_bucket__());
        System.out.println("Final ETag: " + completeResponse.https://docs.cloud.google.com/java/docs/reference/google-cloud-storage/latest/com.google.cloud.storage.multipartupload.model.CompleteMultipartUploadResponse.html#com_google_cloud_storage_multipartupload_model_CompleteMultipartUploadResponse_etag__());
      }
    }

### Node.js


For more information, see the
[Cloud Storage Node.js API
reference documentation](https://cloud.google.com/nodejs/docs/reference/storage/latest).


To authenticate to Cloud Storage, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/storage/docs/authentication#client-libs).

You can perform XML API multipart uploads using the
[`uploadFileInChunks`](https://googleapis.dev/nodejs/storage/latest/TransferManager.html#uploadFileInChunks)
method. For example:

    /**
     * TODO(developer): Uncomment the following lines before running the sample.
     */
    // The ID of your GCS bucket
    // const bucketName = 'your-unique-bucket-name';

    // The path of file to upload
    // const filePath = 'path/to/your/file';

    // The size of each chunk to be uploaded
    // const chunkSize = 32 * 1024 * 1024;

    // Imports the Google Cloud client library
    const {Storage, TransferManager} = require('https://docs.cloud.google.com/nodejs/docs/reference/storage/latest/overview.html');

    // Creates a client
    const storage = new https://docs.cloud.google.com/nodejs/docs/reference/storage-control/latest/storage-control/protos.google.storage.v2.storage-class.html();

    // Creates a transfer manager client
    const transferManager = new https://docs.cloud.google.com/nodejs/docs/reference/storage/latest/storage/transfermanager.html(storage.bucket(bucketName));

    async function uploadFileInChunksWithTransferManager() {
      // Uploads the files
      await transferManager.https://docs.cloud.google.com/nodejs/docs/reference/storage/latest/storage/transfermanager.html(filePath, {
        chunkSizeBytes: chunkSize,
      });

      console.log(`${filePath} uploaded to ${bucketName}.`);
    }

    uploadFileInChunksWithTransferManager().catch(console.error);

### Python


For more information, see the
[Cloud Storage Python API
reference documentation](https://cloud.google.com/python/docs/reference/storage/latest).


To authenticate to Cloud Storage, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/storage/docs/authentication#client-libs).

You can perform XML API multipart uploads using the
[`upload_chunks_concurrently`](https://docs.cloud.google.com/python/docs/reference/storage/latest/google.cloud.storage.transfer_manager#google_cloud_storage_transfer_manager_upload_chunks_concurrently)
method. For example:

    def upload_chunks_concurrently(
        bucket_name,
        source_filename,
        destination_blob_name,
        chunk_size=32 * 1024 * 1024,
        workers=8,
    ):
        """Upload a single file, in chunks, concurrently in a process pool."""
        # The ID of your GCS bucket
        # bucket_name = "your-bucket-name"

        # The path to your file to upload
        # source_filename = "local/path/to/file"

        # The ID of your GCS object
        # destination_blob_name = "storage-object-name"

        # The size of each chunk. The performance impact of this value depends on
        # the use case. The remote service has a minimum of 5 MiB and a maximum of
        # 5 GiB.
        # chunk_size = 32 * 1024 * 1024 (32 MiB)

        # The maximum number of processes to use for the operation. The performance
        # impact of this value depends on the use case. Each additional process
        # occupies some CPU and memory resources until finished. Threads can be used
        # instead of processes by passing `worker_type=transfer_manager.THREAD`.
        # workers=8

        from google.cloud.storage import https://docs.cloud.google.com/python/docs/reference/storage/latest/google.cloud.storage.client.Client.html, https://docs.cloud.google.com/python/docs/reference/storage/latest/google.cloud.storage.transfer_manager.html

        storage_client = Client()
        bucket = storage_client.https://docs.cloud.google.com/python/docs/reference/storage/latest/google.cloud.storage.client.Client.html#google_cloud_storage_client_Client_bucket(bucket_name)
        blob = bucket.blob(destination_blob_name)

        https://docs.cloud.google.com/python/docs/reference/storage/latest/google.cloud.storage.transfer_manager.html.https://docs.cloud.google.com/python/docs/reference/storage/latest/google.cloud.storage.transfer_manager.html(
            source_filename, blob, chunk_size=chunk_size, max_workers=workers
        )

        print(f"File {source_filename} uploaded to {destination_blob_name}.")


    if __name__ == "__main__":
        argparse = argparse.ArgumentParser(
            description="Upload a file to GCS in chunks concurrently."
        )
        argparse.add_argument(
            "--bucket_name", help="The name of the GCS bucket to upload to."
        )
        argparse.add_argument(
            "--source_filename", help="The local path to the file to upload."
        )
        argparse.add_argument(
            "--destination_blob_name", help="The name of the object in GCS."
        )
        argparse.add_argument(
            "--chunk_size",
            type=int,
            default=32 * 1024 * 1024,
            help="The size of each chunk in bytes (default: 32 MiB). The remote\
                  service has a minimum of 5 MiB and a maximum of 5 GiB",
        )
        argparse.add_argument(
            "--workers",
            type=int,
            default=8,
            help="The number of worker processes to use (default: 8).",
        )
        args = argparse.parse_args()
        upload_chunks_concurrently(
            args.bucket_name,
            args.source_filename,
            args.destination_blob_name,
            args.https://docs.cloud.google.com/python/docs/reference/storage/latest/google.cloud.storage.blob.Blob.html#google_cloud_storage_blob_Blob_chunk_size,
            args.workers,
        )

<br />

## What's next

- Explore additional [uploading methods](https://docs.cloud.google.com/storage/docs/uploads) for Cloud Storage.
- Learn about [truncated exponential backoff](https://docs.cloud.google.com/storage/docs/retry-strategy) and when to retry requests.