Almost every SaaS needs file uploads: profile pictures, CSV imports, document attachments, image uploads. Getting file storage wrong leads to security vulnerabilities, storage cost explosions, or a poor user experience. Here's the right way to handle it.
Never Upload Files to Your Server
The most common mistake: accepting file uploads directly to your Next.js API routes and storing them on the server filesystem. Problems: server disk fills up, files are lost on redeploy, no CDN delivery, poor performance at scale. Always store files in object storage.
Supabase Storage
If you're using Supabase, their Storage service is the obvious choice. It's an S3-compatible object store with built-in access control that respects your RLS policies. Files uploaded to a user's "bucket" are automatically restricted to that user or organization.
Implementation: generate a signed upload URL on your server, have the client upload directly to Supabase Storage, save the file URL to your database.
The Direct Upload Pattern
Don't proxy file uploads through your server. Use direct uploads:
- Client requests an upload URL from your API
- Your API generates a pre-signed upload URL from Supabase Storage
- Client uploads the file directly to Supabase (not through your server)
- Client notifies your API that the upload is complete
- Your API saves the file reference to your database
This pattern means large files don't touch your server at all, saving bandwidth and compute costs.
File Validation
Always validate on both the client and server: file type (check MIME type, not just extension), file size limit (reject files over your max), and for user-uploaded images, validate dimensions and optionally re-encode with Sharp to strip metadata and enforce format.
Build Proper File Handling Into Your SaaS
I take 2 clients per month. Ship your SaaS in 2–4 weeks with a developer who has done it 350+ times.
Start on Fiverr →Image Optimization
For user-uploaded images shown in your UI: store the original, but generate resized thumbnails for display. Supabase Storage's built-in image transformation API can resize images on-the-fly without you storing multiple versions.
Optimizing Uploaded Images Automatically
User-uploaded images are frequently oversized. A profile photo uploaded at 4MB and displayed at 64px is wasting bandwidth on every page load. Add automatic image processing to your upload pipeline: resize images to the maximum display dimensions, convert to WebP format, and strip EXIF metadata for privacy. Cloudflare Images or a simple Sharp processing step in your upload handler handles all of this in under 100ms. The resulting storage cost savings and performance improvements are significant at any meaningful scale.