Create signed URL with 60 second expiry for storage objects
The createSignedUrl() method on a storage bucket reference generates a signed URL with a specified expiry time in seconds. In the image captioning example, a 60-second expiry is used to allow time for the Hugging Face API to fetch and process the image.
Storage API provides S3-compatible object storage
The Storage API is an S3-compatible object storage service that stores metadata in Postgres. Source code is at github.com/supabase/storage-api, written in Node.js/TypeScript, and licensed under Apache 2.0.
Resumable uploads for large files
Upload large files using resumable uploads. This feature is generally available and fully available on self-hosted deployments.
Supabase file storage
Supabase Storage helps you store and serve files. This feature is generally available and fully available on self-hosted deployments.
Content Delivery Network for storage
Cache large files using the Supabase CDN. This feature is generally available but requires Cloudflare for self-hosted deployments.
Image transformations in storage
Transform images on the fly. This feature is generally available and fully available on self-hosted deployments.
Smart CDN for storage assets
Automatically revalidate assets at the edge via the Smart CDN. This feature is generally available but requires Cloudflare for self-hosted deployments.
S3 compatibility for storage
Interact with Supabase Storage from any tool which supports the S3 protocol. This feature is generally available and fully available on self-hosted deployments.
Install image picker for profile photos in Expo
To enable profile photo uploads in an Expo app, install the image picker dependency with: npx expo install expo-image-picker.
Supabase Storage integration for file management
Every Supabase project is pre-configured with Storage for managing large files like photos and videos. This can be integrated into React Native apps to allow users to upload and manage profile images and other media.
Flutter storage bucket publicity setting
Ensure the 'avatars' storage bucket is set to public to allow images to be accessed via signed URLs. Toggle bucket publicity in the Supabase Dashboard by clicking the dot menu next to the bucket name. A public bucket displays an orange 'Public' badge next to the bucket name.
Flutter storage image upload implementation
To upload an image to Supabase storage, use the `image_picker` package (version ^1.0.5) to select an image. Read the image bytes with `await imageFile.readAsBytes()`. Extract the file extension and generate a file name. Upload using `await supabase.storage.from('avatars').uploadBinary(filePath, bytes, fileOptions: FileOptions(contentType: imageFile.mimeType))`. Generate a signed URL with `await supabase.storage.from('avatars').createSignedUrl(filePath, 60 * 60 * 24 * 365 * 10)` for a 10-year expiry. Catch `StorageException` for upload errors.
Storage download with supabase.storage.from().download()
Download files from Supabase Storage using supabase.storage.from('bucket_name').download(path). The method returns a data object (a Blob) that can be converted to an object URL with URL.createObjectURL().
Storage file upload with random filename
Upload files to Supabase Storage using supabase.storage.from('bucket_name').upload(filePath, file). Generate unique filenames with random numbers and preserve the original file extension to avoid conflicts.
Supabase Storage integration in Refine for file uploads
Supabase configures every project with Storage for managing large files like photos and videos. In Refine apps, use the supabaseClient to interact with Supabase Storage for implementing file upload functionality such as profile photo uploads.
Supabase Storage usage in SvelteKit
Supabase automatically configures every project with Storage for managing large files like photos and videos. This can be accessed through the Supabase client for file uploads and downloads.
Swift: Upload file to Storage
Use `supabase.storage.from(bucketName).upload(filePath, data, options)` to upload a file. The FileOptions can specify contentType. Returns the file path. Example: `try await supabase.storage.from("avatars").upload(filePath, data: data, options: FileOptions(contentType: "image/jpeg"))`
Swift: Download file from Storage
Use `supabase.storage.from(bucketName).download(path:)` to download file data. Returns Data that can be converted to UIImage or other types. Example: `let data = try await supabase.storage.from("avatars").download(path: path)`
Storage errors troubleshooting table
Symptom: Upload or list fails; public bucket inaccessible; relation "objects" does not exist; file size limit; folder or RLS issue. Layer: Storage → storage_logs, postgres_logs. Troubleshooting guides: Public bucket upload/list; 403 RLS on upload; relation objects does not exist; File size limits; Folder ops/hierarchical RLS.
File uploads to Supabase Storage from Android
Use storage.from("bucketName").upload(path = "fileName.png", data = imageFile, upsert = true) to upload files. The upsert parameter allows replacing existing files. After upload, construct the public URL as "${BuildConfig.SUPABASE_URL}/storage/v1/object/public/${imageFileName}" and replace spaces with %20. Avoid spaces in bucket names to simplify URL encoding.
Amazon S3 log drain configuration
Logs are written as batched files to an existing S3 bucket. Required configuration: S3 Bucket (name of an existing S3 bucket), Region (AWS region where the bucket is located), Access Key ID (used for authentication), Secret Access Key (used for authentication), and Batch Timeout (ms) (maximum wait before flushing a batch, recommended: 2000–5000ms). The AWS account tied to the Access Key ID must have write permissions on the specified S3 bucket.
Storage report charts and metrics
The Storage report includes: Total Requests (overall request volume to Storage, shows traffic patterns and usage trends including top routes), Response Speed (average response time for storage requests, shows performance bottlenecks and optimization opportunities including top routes), Network Traffic (ingress and egress usage, shows data transfer costs and CDN effectiveness), Request Caching (cache hit rates and miss patterns, shows CDN performance and cost optimization including top routes).
Project permissions table by role - Storage
Storage permissions by role:
Buckets (Create, Update, Delete): Owner, Admin, and Developer. (View, List): Owner, Admin, Developer, and Read-Only.
Files (Create/Upload, Update, Delete): Owner, Admin, and Developer. (List): Owner, Admin, Developer, and Read-Only.
Download storage objects before deletion
Before deleting a project, back up all important files from Storage buckets using the Supabase dashboard or API to download files in bulk, and store them in a secure location outside of Supabase.
Storage egress definition and example
Storage egress is data sent from Supabase Storage to the client when retrieving assets, including downloading files, images, or other stored content via the JavaScript Client SDK. Example: when a user downloads an invoice from an online shop as a PDF file, the file sent back to the client contributes to Storage Egress.
Cached egress definition
Cached egress is egress served from the CDN via cache hits. Cached and uncached egress have independent quotas and independent pricing. Cached egress is typically incurred for storage through the Smart CDN.
Storage Image Transformations: API example with width and height
Creating a signed URL with image transformation using createSignedUrl accepts a transform parameter with width and height properties. Example: `supabase.storage.from('bucket').createSignedUrl('image-1.jpg', 60000, { transform: { width: 200, height: 200, } })`
Storage Image Transformations: download method with transform
The download method also supports image transformation via a transform parameter with width and height. Example: `supabase.storage.from('bucket').download('image-2.jpg', { transform: { width: 800, height: 300, } })`
Storage Image Transformations: optimize usage strategies
To optimize Storage Image Transformations usage: pre-generate common variants instead of transforming images on the fly; optimize original image sizes by uploading in optimized format and resolution; leverage Smart CDN caching or other caching solutions to serve transformed images efficiently and avoid unnecessary repeated transformations; control browser storage duration using the Cache-Control header.
Query storage objects larger than 5 MB
You can query the storage schema to list files larger than 5 MB using: select name, bucket_id as bucket, case when (metadata->>'size')::int >= 1073741824 then ((metadata->>'size')::int / 1073741824.0)::numeric(10, 2) || ' GB' when (metadata->>'size')::int >= 1048576 then ((metadata->>'size')::int / 1048576.0)::numeric(10, 2) || ' MB' when (metadata->>'size')::int >= 1024 then ((metadata->>'size')::int / 1024.0)::numeric(10, 2) || ' KB' else (metadata->>'size')::int || ' bytes' end as size from storage.objects where (metadata->>'size')::int > 1048576 * 5 order by (metadata->>'size')::int desc
Query total size per bucket
You can query the storage schema to list buckets with their total size using: select bucket_id, (sum((metadata->>'size')::int) / 1048576.0)::numeric(10, 2) as total_size_megabyte from storage.objects group by bucket_id order by total_size_megabyte desc
Storage optimization methods
To optimize storage usage, you should limit the upload size for your buckets and delete assets that are no longer in use.
Download Firebase Storage bucket command
Use command: node download.js <prefix> [<folder>] [<batchSize>] [<limit>] [<token>]
Parameters:
- <prefix>: The prefix of the files to download. Use empty prefix "" to process the root bucket.
- <folder>: (optional) Name of subfolder for downloaded files, created as a subfolder of the current folder (e.g., ./downloads/). Default is downloads.
- <batchSize>: (optional) Default is 100.
- <limit>: (optional) Stop after processing this many files. Use 0 for no limit.
- <token>: (optional) Begin processing at this pageToken. For batch processing with multiple executions, use the same parameters with a new token on subsequent calls, using the token from the last call to continue.
Auto-created buckets in Supabase migration
If the bucket doesn't exist during upload, it is created as a non-public bucket. You must set permissions on this new bucket in the Supabase Dashboard before users can download any files.
Upload files to Supabase Storage bucket command
Use command: node upload.js <prefix> <folder> <bucket>
Parameters:
- <prefix>: The prefix of the files to download. Use empty prefix "" to process all files.
- <folder>: Name of subfolder of files to upload, read as a subfolder of the current folder (e.g., ./downloads/). Default is downloads.
- <bucket>: Name of the bucket to upload to.
Firebase Storage to Supabase migration overview
Supabase provides tools to convert storage files from Firebase Storage to Supabase Storage. The migration is a two-step process: files are downloaded from a Firebase storage bucket to a local filesystem, then files are uploaded from the local filesystem to a Supabase storage bucket.
Clone firebase-to-supabase repository
Clone the firebase-to-supabase repository from https://github.com/supabase-community/firebase-to-supabase.git
Configure Supabase credentials for migration
Rename supabase-keys-sample.js to supabase-keys.js in the /storage directory. Go to your Supabase project's API settings in the Dashboard. Copy the Project URL and update the SUPABASE_URL value in supabase-keys.js. Under Project API keys, copy the secret key and update the SUPABASE_KEY value in supabase-keys.js.
Storage schema ownership requirements
All entities under the storage schema must be owned by the supabase_storage_admin role. Breaking this assumption risks rendering the storage service inoperational for the project.
Storage security guides index
Supabase provides security guides for storage covering: object ownership, access control, and custom roles with the storage schema. The Storage API documentation contains hints about required RLS policy permissions.
Sync storage buckets configuration
RLS policies on storage buckets can be pulled locally by running 'supabase db pull --schema storage'. Buckets and objects themselves are rows in storage tables and won't appear in schema. Define buckets via supabase/config.toml with properties like public (boolean), file_size_limit (string), allowed_mime_types (array), and objects_path (string pointing to local directory). Upload files to buckets using 'supabase seed buckets'.
Storage bucket configuration example
Example storage bucket configuration in supabase/config.toml: [storage.buckets.images] public = false, file_size_limit = "50MiB", allowed_mime_types = ["image/png", "image/jpeg"], objects_path = "./images". This uploads files from supabase/images directory to a bucket named 'images' with the command 'supabase seed buckets'.
Example: Storage error handling
const { data, error } = await supabase.storage.from('avatars').upload('public/avatar1.png', avatarFile); if (error) { console.error(error); return; }
StorageError fields
StorageError exposes error.statusCode (HTTP status as a string) and a structured error name (e.g. 'Duplicate', 'NotFound').
Storage migration script batch processing
The storage migration script processes files in batches of 10 per batch using Promise.all for parallel processing. This improves efficiency while managing concurrent requests.
Storage migration preserves bucket configuration
When creating new buckets during storage migration, the script preserves the original bucket configuration including: public/private status (public property), file size limits (fileSizeLimit), and allowed MIME types (allowedMimeTypes).
Storage migration preserves file metadata
The storage migration script preserves file metadata during upload, including: contentType (MIME type), and cacheControl headers. The upsert option is set to true to overwrite existing files with the same path.
Storage migration script handles nested folders
The storage migration script recursively traverses and lists files in nested folder structures within buckets, handling paths that include folder separators.
Migrate storage objects with Node.js script
To migrate storage objects between projects, create a Node.js project with @supabase/supabase-js and use a migration script. The script must: (1) Connect to both old and new Supabase projects with service keys, (2) List all buckets and files from old project, (3) Create buckets in new project if they don't exist, (4) Download files from old project and upload to new project in batches. The script should preserve metadata like content type and cache control.
Storage migration script setup
To set up a storage migration script: (1) Create a new JavaScript project directory, (2) Initialize with npm init -y and install @supabase/supabase-js, (3) Create an index.js file with the migration code, (4) Get secret/service_role keys for both projects from the API keys page, (5) Copy project URLs from Data API settings, (6) Add these details to the script's OLD_PROJECT_URL, OLD_PROJECT_SERVICE_KEY, NEW_PROJECT_URL, and NEW_PROJECT_SERVICE_KEY variables, (7) Run with node index.js.
Storage migration script conflict strategies
The storage migration script offers four options when target buckets already exist: (1) Skip existing buckets and don't migrate them, (2) Merge files into existing buckets (may overwrite existing files), (3) Rename buckets in target by adding '_migrated' suffix, (4) Cancel the entire migration.
Storage files not included in database backup
After restoring the backup, the buckets and files metadata will appear in the dashboard of the new project. However, the actual storage files stored in the S3 buckets will not be present and must be migrated separately.
Supabase Storage for profile photos
Every Supabase project is configured with Storage by default for managing large files like photos and videos. Storage can be used to store user profile photos in user management applications. To implement profile photo uploads, create an Avatar component (e.g., using `ng g c avatar` in Angular). The user management tutorial demonstrates how to add profile photo upload capability using the Avatar component.