Supabase Storage
Supabase Storage provides a robust, scalable solution for managing files of any size with fine-grained access controls and optimized delivery. Built on S3-compatible infrastructure, it integrates seamlessly with PostgreSQL's Row Level Security (RLS) to give you database-level control over file access. This approach leverages the same Supabase Database infrastructure you're already using for your application data.
Unlike Firebase Storage, Supabase Storage leverages standard SQL-based policies that you're already using for your database, eliminating the need to learn a separate permission system. Every file operation passes through the same RLS policies that protect your data, ensuring consistent security across your entire application.
The storage system supports multiple upload protocols including standard multipart uploads for simple files and TUS protocol for resumable uploads of large files. With a global CDN distributing your assets from over 285 cities worldwide, your users receive content from the nearest edge location for optimal performance.
For teams building modern web and mobile applications, Supabase Storage offers a compelling alternative to Firebase that combines the flexibility of open-source technology with the familiarity of PostgreSQL. Whether you're building a content management system, a media-heavy application, or a multi-tenant platform, the integration between Storage and your database eliminates the friction of managing separate permission systems.
Three specialized bucket types for different use cases
Files Buckets
General-purpose storage for images, videos, documents, and any file type with CDN delivery and RLS integration
Analytics Buckets
Apache Iceberg format support for data lakes, time-series data, and large-scale analytical workloads
Vector Buckets
Specialized storage for AI embeddings with HNSW indexes and similarity search capabilities
Bucket Architecture and Organization
Public vs Private Access Model
Every bucket operates in either public or private mode, fundamentally determining how files are served and what access controls apply. Understanding this distinction is crucial for implementing correct security policies for your use case.
Private buckets enforce strict access control on all operations. When a bucket is private, every file access requires authentication and passes through RLS policy evaluation. The bucket owner or authenticated users with appropriate permissions can access files, but anonymous users receive access denied responses. Private buckets are the default configuration and should be used for sensitive data, user-specific content, and any files that require authentication.
Private bucket access can be granted through two mechanisms: authenticated requests with valid JWT tokens, or signed URLs that grant time-limited access to specific files. Signed URLs are particularly useful for sharing private files with external users or for temporary access scenarios without requiring authentication in your application.
Public buckets bypass access controls for retrieval operations, meaning anyone with the file URL can access the content. However, upload, delete, modify, and copy operations remain subject to RLS policies even in public buckets. This hybrid model makes public buckets ideal for publicly shared content like website assets, marketing materials, or user-generated content intended for open distribution.
Public buckets offer better performance for frequently accessed files because the CDN caches content aggressively without authentication checks. This reduces latency for public assets while maintaining control over who can modify the content. For applications serving static assets like product images, brand assets, or downloadable resources, public buckets with appropriate RLS policies for uploads provide the optimal balance of performance and security.
For more details on implementing RLS policies for storage, see our guide on Supabase Row Level Security.
CDN Caching and Performance
The access model directly impacts how the CDN caches your content. Public bucket files are cached at edge locations based on the cache control headers set during upload, enabling aggressive caching strategies that minimize origin requests. Private bucket files bypass CDN caching for the actual content since each request requires authentication, though users still benefit from CDN routing that minimizes geographic latency.
For hybrid applications with both public and private content, maintaining separate buckets for each access pattern prevents authentication checks from affecting cache behavior for public content. This separation also simplifies your policy logic since you don't need to account for different access requirements within the same bucket.
Upload Methods
Standard File Uploads
Supabase Storage supports standard file uploads through the JavaScript/TypeScript SDK, which handles multipart form data for files of any size. The upload method accepts file objects from browser inputs or Node.js buffers, automatically determining appropriate chunk sizes and handling the upload process.
The upload function provides several configuration options that control upload behavior. The cacheControl parameter sets the CDN cache header value, determining how long cached copies remain valid. The upsert parameter determines whether an existing file at the same path should be replaced, which is useful for profile picture updates or document revisions.
For production applications, consider implementing client-side file validation before upload to reject files that exceed size limits or don't match allowed content types. This reduces failed upload attempts and improves user experience by providing immediate feedback.
Resumable Uploads with TUS Protocol
For large files or unreliable network conditions, Supabase Storage implements the TUS (Tus Resumable Upload Protocol) for resumable uploads. TUS breaks files into smaller chunks and supports upload resumption from the last successfully uploaded chunk, making it ideal for video files, large datasets, or applications where network interruptions are common.
Resumable uploads integrate seamlessly with the Uppy upload library through the TUS plugin. The integration requires configuring the TUS endpoint with your Supabase project URL and including the authentication token in request headers. Once configured, Uppy handles chunk management, progress tracking, and automatic resumption on failure.
Use resumable uploads when dealing with files exceeding 50MB, when your users have unreliable internet connections, or when uploading video content that would be costly to re-upload after network failures. The overhead of chunk management is negligible for typical uploads but becomes essential for large file reliability.
For implementation examples with Next.js, see our guide on Supabase + Next.js Integration.
1const { data, error } = await supabase.storage2 .from('avatars')3 .upload(`public/${userId}.png`, fileObject, {4 cacheControl: '3600',5 upsert: false6 });7 8const { data: { publicUrl } } = supabase.storage9 .from('avatars')10 .getPublicUrl(`public/${userId}.png`);Row Level Security Policies
Policy Fundamentals
Supabase Storage leverages PostgreSQL's Row Level Security system to control access, meaning your storage policies use the same syntax and patterns as your database policies. This consistency simplifies security implementation and maintenance across your application.
Policies can control four operations: SELECT for downloading and viewing files, INSERT for uploading new files, UPDATE for modifying file metadata, and DELETE for removing files. Each operation can have separate policies with different conditions, allowing fine-grained control over who can perform each action.
The storage.objects table contains all files across all buckets, with columns including bucket_id, name (full path including folders), owner_id (user ID of the uploader), and custom metadata columns. Policies can reference any of these columns plus helper functions like storage.foldername() for folder-based access control. This integration means you can reference data from your application tables when making access decisions, enabling patterns like organization-based access control.
For comprehensive RLS patterns and examples, see our detailed guide on Supabase Row Level Security.
Common Policy Patterns
Authenticated User Upload Policy: Restricts uploads to authenticated users for a specific bucket, ensuring only logged-in users can add files. The WITH CHECK clause defines conditions for insert operations, while USING defines conditions for select operations.
User File Access Policy: Grants users access to files they uploaded using the owner_id column that automatically tracks file ownership. The policy checks whether the requesting user's ID matches the file's owner, ensuring users can only access their own content.
Role-Based Access Control: For administrative scenarios, policies can check user roles stored in your database rather than relying solely on authentication status. This enables patterns where admins have full access while regular users have limited permissions.
1-- Allow authenticated users to upload to their own folder2CREATE POLICY "Allow authenticated uploads"3ON storage.objects4FOR INSERT5TO authenticated6WITH CHECK (7 bucket_id = 'user-content' AND8 storage.foldername(name)[1] = auth.uid()::text9);10 11-- Allow users to access their own files12CREATE POLICY "Individual user access"13ON storage.objects14FOR SELECT15TO authenticated16USING (17 owner_id = auth.uid() OR18 (SELECT auth.jwt()->>'sub') = owner_id19);Image Transformations
Supabase Storage includes built-in image processing capabilities that transform images on-the-fly without requiring separate processing infrastructure. When you request an image with transformation parameters, the CDN edge server processes the request and returns the optimized version while caching the result for future requests.
Available Transformations
The transformation system supports resizing to specific dimensions, maintaining aspect ratio or cropping to exact sizes, quality adjustment for file size optimization, and format conversion between formats like WebP, AVIF, JPEG, and PNG. These transformations occur at the CDN edge, reducing origin server load and improving response times for your users.
// Request an image with transformations
const { data, error } = await supabase.storage
.from('images')
.download('photos/cat.jpg', {
transform: {
width: 800,
height: 600,
resize: 'cover',
format: 'webp',
quality: 80
}
});
Transformation URL Parameters
For direct URL access rather than SDK usage, transformations can be specified through URL query parameters appended to the file URL. This approach is useful for image tags in HTML or when generating URLs for display in your application.
<img
src="https://[project].supabase.co/storage/v1/object/public/images/photo.jpg?width=400&height=300&resize=cover&format=webp"
alt="Transformed image"
/>
The CDN caches transformed images automatically, so subsequent requests for the same transformation receive the cached result without additional processing. This caching behavior makes image transformations both performant and cost-effective for high-traffic applications. By selecting appropriate image formats and quality settings, you can significantly reduce bandwidth usage while maintaining visual quality.
Global Content Delivery Network
Supabase Storage includes a global CDN that distributes your files across edge locations worldwide, serving content from the geographic location closest to each user. This distribution dramatically reduces latency compared to serving all requests from a single origin server.
CDN Configuration
The CDN automatically caches public bucket files at edge locations with configurable cache durations. Private files are not cached at the CDN layer because each request requires authentication, but authenticated users still benefit from CDN routing that minimizes distance to the nearest edge point of presence.
Cache control headers specified during upload determine how long the CDN caches files before revalidating with the origin. Static assets like logos and images benefit from longer cache durations, while user-generated content might use shorter durations or cache-busting strategies through unique filenames.
Performance Optimization
Several strategies maximize CDN effectiveness for storage-backed content. First, using public buckets for static assets enables maximum caching effectiveness. Second, implementing proper cache control headers during upload or through subsequent update operations controls cache duration. Third, using consistent URLs for unchanging content prevents unnecessary cache invalidation.
For applications with both public and private content, consider maintaining separate buckets for each access pattern. This separation prevents authentication checks from affecting cache behavior for public content while maintaining security isolation for private files. The resulting architecture provides optimal performance for public assets while maintaining strict access controls for private content.
Optimized file delivery through CDN reduces bandwidth costs and improves user experience, especially for applications with global audiences. Combined with our web development services, this approach ensures your media-rich applications perform exceptionally well worldwide.
CDN Coverage
285+
Edge Locations
6
Continents
50ms
Avg Latency
Why Supabase Storage Over Firebase
For teams choosing between Supabase and Firebase for their backend platform, the storage component reflects the broader architectural differences between these solutions. Supabase Storage offers advantages in flexibility, security consistency, and data portability that matter for production applications.
Key Advantages
SQL-Based Access Control: Firebase Storage uses security rules with a proprietary syntax that differs from Firestore's rules and doesn't leverage database relationships. Supabase Storage policies use standard SQL, integrate with your existing database schema, and support complex queries that Firebase rules cannot express. If you're already using PostgreSQL for your data, this consistency eliminates context switching and reduces security bugs.
Open Source and Portability: Unlike Firebase's proprietary storage system, Supabase Storage is built on open-source technology that you can self-host if needed. This portability protects your application from vendor lock-in and provides deployment flexibility that proprietary solutions cannot match. For organizations with specific compliance requirements or data residency needs, the ability to self-host provides crucial flexibility.
PostgreSQL Integration: Files in Supabase Storage are tracked in the storage.objects table within your PostgreSQL database, enabling joins between file metadata and other tables. You can query files based on any metadata column, create relationships between files and database records, and use PostgreSQL's full query capabilities for file management operations. This integration is particularly valuable for applications that need to associate files with database entities, such as product images linked to inventory records or document attachments linked to customer records.
S3 Compatibility: Supabase Storage uses S3-compatible APIs under the hood, making it compatible with S3 tools and libraries. If you later need to migrate to a different S3 provider or integrate with AWS services directly, your application code requires minimal changes. This compatibility also means you can use existing S3 migration tools and workflows if you need to move data between providers.
When evaluating backend platforms, the storage layer's integration with your database and existing infrastructure is a critical consideration. Our AI automation services can help you leverage Supabase Storage for intelligent document processing and media workflows.
Implementation Best Practices
Bucket Organization Strategy
Design your bucket structure around access patterns rather than file types. Group files that share the same access policies into the same bucket, minimizing the number of policies you need to maintain. For most applications, three to five buckets suffice: one for public assets, one for authenticated user content, one for private documents, and potentially dedicated buckets for media files that require specific processing.
Consider using folder hierarchies within buckets for additional organization. For multi-tenant applications, create folder structures that mirror your tenant organization, enabling simple RLS policies that restrict access based on folder paths. This approach scales well as your application grows while keeping policy management manageable.
Policy Testing Approach
Before deploying policies to production, test them thoroughly using the Supabase dashboard's policy debugging tools. Create test users with different roles and verify that each policy correctly allows or denies access as expected. Pay particular attention to edge cases like null values, empty strings, and unusual path formats that might bypass intended restrictions.
Document your policy logic clearly so that future developers understand why each policy exists and what access patterns it enables. This documentation becomes invaluable as your application grows and policy complexity increases.
Monitoring and Observability
Enable storage logging to track upload attempts, access patterns, and policy evaluations. The Supabase dashboard provides metrics on storage usage, bandwidth, and request volumes that help identify unusual activity or performance issues. Set up alerts for unexpected changes in storage consumption or access patterns that might indicate security concerns.
For applications with regulatory requirements, implement audit logging that captures policy decisions and access attempts. This logging provides an audit trail for compliance purposes and helps with security incident investigation when needed.
Frequently Asked Questions
Sources
- Supabase Storage Overview - Official documentation covering all aspects of Supabase Storage
- Storage Buckets Fundamentals - Detailed information on bucket access models
- Storage Access Control - RLS policy implementation and security best practices
- Supabase Storage and Image Proxy - Third-party analysis of storage features