Upload files from the browser, serve them back and manage them.
#Upload
const file = event.target.files[0]
const { data, error } = await stitchdb.storage
.from('avatars')
.upload(`${user.id}/avatar.png`, file, { upsert: true })
const { data: { publicUrl } } = stitchdb.storage.from('avatars').getPublicUrl(data.path)Pass { contentType, cacheControl: '3600', upsert } as options. Large files can use resumable uploads (TUS) at /storage/v1/upload/resumable; Studio uses them automatically.
#Download
const { data } = await stitchdb.storage.from('avatars').download('path/avatar.png')#List, move, copy and delete
const { data: files } = await stitchdb.storage.from('avatars').list('folder', { limit: 100, offset: 0, sortBy: { column: 'name', order: 'asc' } })
await stitchdb.storage.from('avatars').move('old/path.png', 'new/path.png')
await stitchdb.storage.from('avatars').copy('a.png', 'b.png')
await stitchdb.storage.from('avatars').remove(['a.png', 'b.png'])#Caching and compression
Files in public buckets (/storage/v1/object/public/…) are cached on every server that answers for your project, like a CDN. On a server with a read replica in another region, nearby users get the file from there instead of from your primary server.
- How long a copy is used follows the file's own
Cache-Control. The SDKs upload withmax-age=3600unless you passcacheControl. A file withoutCache-Controlis not cached. - Expired copies are checked again with the file's ETag, so an unchanged file is not sent again from the primary. If the primary server cannot be reached, the last copy is served.
- Range requests (for example video seeking) and files of 100 MB or more are not cached.
- The
X-Cacheheader showsHIT,MISS,REVALIDATEDorSTALE. After you replace a file under the same name, add a query like?v=2to fetch the new one before the old copy expires. - Private files, signed URLs and the S3 endpoint are never cached.
Text files over 1 KB (JSON, CSV, plain text, CSS, JavaScript, XML, SVG, wasm, uncompressed fonts) are sent compressed with brotli or gzip when the client asks for it. Images, video, archives, PDF and files that already have a Content-Encoding are sent as they are. Egress counts the bytes that really went out, so compressed files cost less. Cached files still count as egress.
#Limits
Uploads are limited per file by your plan (and by the bucket's own limit if it is lower). While file storage is over its limit, uploads return 413 until files are removed. See Storage limits.