If you’ve built a side project recently, you’ve probably used Supabase. It is an incredibly powerful open-source Firebase alternative, and their free tier is famously generous.
But last week, I woke up to a dreaded email: “Your project has been scheduled to be paused due to inactivity.”
My app, PDF Pro AI (a 100% private WebAssembly-based PDF editor and AI document analyzer), was getting traffic. People were actively using it. So why was Supabase threatening to shut off the lights?
Here is exactly what happened, why the architecture was fundamentally mismatched, and how I permanently fixed it by migrating to Vercel Blob Storage in under an hour.
The Architecture Problem: Storage vs. Database
When I built the AI features for PDF Pro (like the ATS Resume Scanner and Bank Statement Analyzer), I needed a temporary place to store the user's PDF for exactly 5 seconds.
The flow looked like this:
- User uploads a PDF.
- Next.js pushes the PDF to a Supabase Storage Bucket.
- The serverless route passes the Supabase URL to the Gemini API for AI extraction.
- The backend immediately deletes the PDF from the bucket (because we are fiercely committed to zero-retention privacy).
The catch? I was only using Supabase Storage. I didn't need the PostgreSQL database, authentication, or Edge Functions. I didn't have a single table in the public schema.
The "Inactivity" Trap
Supabase is fundamentally a database company. To save on cloud resources, they run automated sweeps that pause free-tier projects if they don't detect "active database queries" or REST API calls for 7 days.
Because I was only doing temporary file uploads to a storage bucket—and immediately deleting them—my project triggered the inactivity alarm.
I tried a hacky workaround: I set up a Vercel Cron Job to blindly ping a non-existent _keep_alive table in Supabase every night at midnight.
// My desperate attempt to keep the database awake
export async function GET() {
const supabase = createClient(URL, KEY);
// Ping a dummy table. Even if it 404s, it counts as a DB ping... right?
await supabase.from('_keep_alive').select('*').limit(1);
return NextResponse.json({ status: 'ok' });
}
typescript
It didn't work. Supabase's API Gateway blocked the request before it reached the database engine because the table didn't exist, so it never registered as "activity." A few days later, I got the final warning email.
The Pivot: Moving to Native Infrastructure
I realized that using a heavy relational database platform purely as a temporary file-holding bucket was massive overkill. Since my entire frontend and serverless API was already hosted on Vercel, I decided to rip off the band-aid and migrate to Vercel Blob Storage.
Vercel Blob is essentially a lightweight wrapper around Cloudflare R2, designed specifically for serverless edge environments.
Why Vercel Blob was the perfect fit:
No "Inactivity" Pauses: It doesn't sleep. It's just dumb, reliable object storage.
Generous Free Tier: 250MB of storage and 50GB of bandwidth/month. Since I delete files immediately after processing, I will never hit the 250MB limit.
Zero Configuration: No buckets to provision, no RLS (Row Level Security) policies to write, and no database credentials to leak.
The Migration (It took 20 minutes)
The code switch was unbelievably satisfying. I got to delete an entire lib/supabase.ts configuration file, uninstall the heavy @supabase/supabase-js package, and delete my hacky cron job.
Here is what the upload logic looked like before:
The Old Way (Supabase):
import { supabase } from '@/lib/supabase';
const filePath = `uploads/${Date.now()}-${file.name}`;
const { error } = await supabase.storage.from('pdf-pro-uploads').upload(filePath, file);
const { data: { publicUrl } } = supabase.storage.from('pdf-pro-uploads').getPublicUrl(filePath);
The New Way (Vercel Blob):
import { upload } from '@vercel/blob/client';
const newBlob = await upload(`uploads/${Date.now()}-${file.name}`, file, {
access: 'public',
handleUploadUrl: '/api/upload',
});
const publicUrl = newBlob.url;
It is cleaner, requires fewer network hops from my serverless functions, and the Vercel Blob client handles multipart uploads automatically under the hood.
The Takeaway
Don't use a Swiss Army Knife when you just need a spoon.
Supabase is an absolutely brilliant piece of technology, and I will 100% use it for my next project that actually requires relational data and auth. But if you are building an AI wrapper, a document processor, or any app that just needs to hold a file in the cloud for a few seconds, look into native edge storage like Vercel Blob or Cloudflare R2.
By aligning my infrastructure exactly with my use case, my app is faster, my codebase is lighter, and best of all—I don't have to worry about the lights getting turned off while I sleep.
If you want to see the resulting architecture in action (and how fast Vercel Blob handles uploads), you can try the AI Bank Statement Analyzer
or the
100% Local PDF Merger
Top comments (0)