Home

Storage Uploads

Supabase Storage provides two methods for uploading files:

  • Standard Uploads
  • Resumable Uploads

Standard Upload#

The standard file upload method is ideal for small files that are not larger than 6MB.

It uses the traditional multipart/form-data format and is simple to implement using the supabase-js SDK. Here's an example of how to upload a file using the standard upload method:

note

You can upload up to 5GB file size using the standard upload method.


For files greater than 6 MB in size, use TUS Resumable Upload for better reliability.


_14
import { createClient } from '@supabase/supabase-js'
_14
_14
// Create Supabase client
_14
const supabase = createClient('your_project_url', 'your_supabase_api_key')
_14
_14
// Upload file using standard upload
_14
async function uploadFile(file) {
_14
const { data, error } = await supabase.storage.from('bucket_name').upload('file_path', file)
_14
if (error) {
_14
// Handle error
_14
} else {
_14
// Handle success
_14
}
_14
}

Resumable Upload#

note

Resumable upload is in Beta. We are rolling this feature gradually, please contact us if you want to be prioritized.

The Resumable upload method is recommended for uploading large files that may exceed 6MB in size or for scenarios where network stability is a concern or if you simply want to have a progress bar for your uploads.

Supabase Storage implements the TUS protocol to enable resumable uploads. TUS stands for The Upload Server and is an open protocol for supporting resumable uploads. The protocol allows the upload process to be resumed from where it left off in case of interruptions. This method can be implemented using the tus-js-client library, or other client-side libraries like Uppy-js that support the TUS protocol.

Here's an example of how to upload a file using tus-js-client:


_49
const tus = require('tus-js-client')
_49
_49
const projectId = ''
_49
const token = ''
_49
_49
function uploadFile(bucketName, fileName, file) {
_49
return new Promise((resolve, reject) => {
_49
var upload = new tus.Upload(file, {
_49
endpoint: `https://${projectId}.supabase.co/storage/v1/upload/resumable`,
_49
retryDelays: [0, 3000, 5000, 10000, 20000],
_49
headers: {
_49
authorization: `Bearer ${token}`,
_49
'x-upsert': 'true', // optionally set upsert to true to overwrite existing files
_49
},
_49
uploadDataDuringCreation: true,
_49
metadata: {
_49
bucketName: bucketName,
_49
objectName: fileName,
_49
contentType: 'image/png',
_49
cacheControl: 3600,
_49
},
_49
chunkSize: 6 * 1024 * 1024, // NOTE: it must be set to 6MB (for now) do not change it
_49
onError: function (error) {
_49
console.log('Failed because: ' + error)
_49
reject(error)
_49
},
_49
onProgress: function (bytesUploaded, bytesTotal) {
_49
var percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2)
_49
console.log(bytesUploaded, bytesTotal, percentage + '%')
_49
},
_49
onSuccess: function () {
_49
// console.log(upload)
_49
console.log('Download %s from %s', upload.file.name, upload.url)
_49
resolve()
_49
},
_49
})
_49
_49
// Check if there are any previous uploads to continue.
_49
return upload.findPreviousUploads().then(function (previousUploads) {
_49
// Found previous uploads so we select the first one.
_49
if (previousUploads.length) {
_49
upload.resumeFromPreviousUpload(previousUploads[0])
_49
}
_49
_49
// Start the upload
_49
upload.start()
_49
})
_49
})
_49
}

Upload URL#

When uploading using the resumable upload endpoint, the TUS server creates a unique URL for each upload, even for multiple uploads to the same path. All chunks will be uploaded to this URL using the PATCH method.

This URL will be valid for up to 24 hours. If the upload is not completed within 24 hours, the URL will expire and you'll need to start the upload again. The TUS client library will automatically create a new URL if the previous one expires.

Concurrency#

When two or more clients try to upload to the same Upload URL only one of them will succeed. The other clients will receive a 409 Conflict error. Only 1 client can upload to the same Upload URL at a time which prevents data corruption.

note

We do not yet support checksum validation for the uploaded chunks. This means if a client changes the file mid way through the upload, the final upload will be an amalgamation of both the files. This has to be done intentionally by the client and is unlikely to happen in normal circumstances.

When two or more clients upload a file to the same path using different upload URLs, the first client to complete the upload will succeed and the other clients will receive a 409 Conflict error.

If you provide the x-upsert header the last client to complete the upload will succeed instead.

UppyJS Example#

You can check a full example using UppyJS Here

Framework integration for UppyJS:

Overwriting Files#

When uploading a file to a path that already exists, the default behavior is to return a 409 Conflict error. If you want to overwrite a file on a specific path you can set the x-upsert header to true.

We do advise against overwriting files when possible, as the CDN will take sometime to propagate the changes to all the edge nodes leading to stale content. Uploading a file to a new path is the recommended way to avoid propagation delays and stale content.

If you want to know more about our CDN, check the CDN guide.

Access Control with RLS Policies#

Both the standard file upload and TUS resumable file upload methods in Supabase Storage support Row-Level Security (RLS) policies. RLS allows you to define fine-grained access control rules to restrict access to files based on user roles, permissions, or other criteria. This ensures that your files are secure and accessible only to authorized users.

For more information on RLS policies, see the Storage Access Control guide.

Conclusion#

Supabase Storage provides multiple options for uploading files, including standard file upload and TUS resumable file upload, both of which use RLS policies for access control. Additionally, there are client-side libraries like Uppy-js that make it easy to implement TUS uploads in your application. Choose the upload method that best fits your needs based on file size, network stability, and other requirements.