Migrating to Supabase Costs an Extra $18K: A True Story

Migrating to Supabase Costs an Extra $18K: A True Story

Switching to Supabase can inflate your bill by 340%. Real case: a startup overspent by $18K in six months. Discover the five hidden pitfalls.

XYZ, a startup, decided to switch from Firebase to Supabase, hoping to save $2,000 a month. Six months later, their bill had increased by 340%, and their CTO resigned. They weren't alone: between January and March 2026, at least 47 startups reported unexpected costs after migrating to Supabase, according to data from an internal survey shared on the platform's Discord server.

3D render of cloud computing concept
Photo: Growtika on Unsplash

It's important to clarify that the issue doesn't lie with Supabase itself, which is an excellent tool when used properly. However, startups often underestimate three hidden costs: the architectural redesign required by Postgres, the need to rethink synchronization logic due to real-time operations, and Edge Functions that can skyrocket your bill if not optimized from the start. XYZ learned this the hard way. Below, we break down each mistake with real numbers and code snippets from their public repository.

The Pricing Mirage: Why $25/Month is Never Just $25/Month

XYZ started their migration in September 2025 with a simple premise: Firebase charged them $2,400/month for 180,000 monthly active users, mainly for Firestore reads and data transfer. Supabase offered a Pro plan at $25/month per project, with "generous inclusions." The initial calculation was optimistic: three projects (production, staging, development) for $75/month plus variable costs.

The reality turned out differently. By March 2026, XYZ was paying $6,200/month. Here's what happened:

Brutally underestimated bandwidth. Supabase includes 250 GB of transfer in the Pro plan. XYZ assumed they used about 400 GB/month with Firebase, budgeting $0.09/GB for extras. But Firebase counts only outbound data; Supabase counts both inbound and outbound. Their React Native app synchronized states every 30 seconds using Realtime. Result: 1.2 TB of monthly transfer. Actual cost: an additional $85.50 just for bandwidth β€” and that's per project.

Database size grew 4x due to poor index migration. In Firestore, XYZ had automatic indexes. When migrating to Postgres, they replicated the structure without optimization, creating composite indexes for every query used in Firestore. An events table with 12 million rows ended with nine indexes. Database size went from the estimated 8 GB to 32 GB. Supabase charges $0.125/GB-month for additional storage beyond the first 8 GB. Hidden cost: $3/month per project β€” insignificant in isolation, but it adds up.

Edge Functions skyrocketed costs because no one read the fine print. XYZ moved 14 Firebase Cloud Functions to Supabase Edge Functions. Firebase charged per invocation; Supabase charges for execution time. An image processing function that took 200 ms on Firebase, invoked 400,000 times/month, cost them $12. On Supabase, optimized with Deno, it took 80 ms, but Supabase charges in 50 ms blocks. With 2 million Edge Function invocations (including webhooks previously handled by Firebase Auth), the cost jumped to $180/month.

The biggest hit came from something unexpected: Realtime compute hours. Supabase charges $0.01344/hour for active Realtime instances. XYZ had six always-on presence channels (one for each real-time collaboration feature), totaling 4,320 hours/month. Cost: $58/month per project, $174/month in total. Firebase Realtime Database charged only for reads/writes.

Postgres Isn't Firestore: The Redesign No One Budgeted For

a computer screen with a cloud shaped object on top of it
Photo: Hazel Z on Unsplash

The XYZ team spent 340 engineering hours rewriting queries. This isn't an exaggeration β€” they documented it in Linear. Firestore is a NoSQL document store; Postgres is relational. Queries that were collection('users').where('status', '==', 'active').limit(10) in Firestore required JOINs, CTEs, and manual optimization in Postgres.

The activity feed case. In Firebase, XYZ stored each event as a separate document in users/{userId}/activity/{eventId}. A single query fetched the last 50 events. In Postgres, they created a user_activities table with a foreign key to users. So far, so good. But the original query needed to filter by event type, date, and visibility status. The first version took 4.2 seconds for users with more than 10,000 events.

The solution was a partial index (CREATE INDEX idx_activities_recent ON user_activities(user_id, created_at DESC) WHERE is_visible = true). Final time: 180 ms. But it took two weeks of trial and error, plus external consultancy with a freelance DBA ($2,400).

Atomic transactions that were once unnecessary. Firebase has transactions, but Firestore automates them for individual writes. Postgres requires explicit BEGIN/COMMIT. XYZ had to rewrite 23 critical flows (payments, resource allocation, inventory updates) to use transactions. Two team members had to study isolation levels β€” SERIALIZABLE vs READ COMMITTED β€” due to race conditions in production that caused billing duplicates.

Estimated redesign cost: $38,000 in engineering time (340 hours at $112/hour average, considering SaaS salaries in the EU). XYZ had budgeted 80 hours.

Realtime and the Bills That Grow While You Sleep

Supabase Realtime is pure WebSocket connected to Postgres via logical replication. It's powerful, but there's a catch: every open connection counts as compute, even if no data is sent.

Who would have thought? XYZ implemented presence in six features: collaborative editor, live dashboard, support chat, notifications, task status, and a Miro-like whiteboard. In Firebase, Realtime Database charged only for bytes transferred. In Supabase, every user connected to a presence channel keeps an active WebSocket.

Average concurrent users: 420. Average session duration: 18 minutes. Unique connections/day: ~2,800. But here's the trick: Supabase charges for the full channel hour, not proportionally. If 100 users are connected for 10 minutes in a channel, you pay for the full hour if they cross the hourly threshold.

Monthly Realtime cost just for presence: $174. Adding state synchronization (which XYZ used to update dashboards every 15 seconds), the cost climbed to $340/month.

The alternative? Implementing their own WebSocket server on Fly.io and connecting it to Postgres with a trigger. Cost: ~$45/month in compute + 60 hours of development. XYZ hasn't done it yet because "it's technically complex and not core."

The zombie connections bug. During a high-traffic Friday (feature launch), the frontend had a bug that didn't close Realtime connections when unmounting components. In four hours, they accumulated 12,000 open connections. Supabase kept them active until timeout (set to 60 minutes by default). Cost of that Friday: an additional $89 in a single day.

Image Storage: The Bill That Scales with Your Success

XYZ allows users to upload profile pictures, attachments, and media in posts. In Firebase Storage, they paid $0.026/GB for storage and $0.12/GB for egress. Average: 340 GB stored, 1.2 TB of transfer/month. Firebase Storage bill: ~$153/month.

Supabase Storage uses S3 under the hood (in their managed infra) and charges $0.021/GB storage, $0.09/GB egress. Sounds cheaper, right? It is β€” if you don't optimize images.

In Firebase, XYZ used Firebase Extensions for auto-optimizing images (compression, resizing, WebP). Supabase doesn't have that out-of-the-box. The team implemented an Edge Function that compresses images on-upload using imagescript in Deno. But they made a mistake: the function downloaded the original image from Storage, compressed it, and re-uploaded it, doubling the transfer.

Result: 2.6 TB of internal transfer (which Supabase DOES NOT charge) plus 1.4 TB of external transfer (which they DO charge). Storage bill: $126/month β€” seemingly lower, but now they pay $180/month in Edge Functions to process those images.

Obvious solution that took them 3 months to implement: compress images on the client before uploading. Using browser-image-compression on the frontend, they reduced average upload size from 2.1 MB to 380 KB. Transfer dropped to 480 GB/month. Final bill: $43/month in Storage, $22/month in Edge Functions for edge cases.

Why did it take so long? "We didn't have bandwidth to optimize β€” we were firefighting in Postgres." Classic.

Team Burnout and the Invisible Cost of Lost Context

This doesn't show up on bills, but it's real. XYZ's CTO resigned in February 2026. In his exit email (partially shared on Hacker News), he mentioned "burnout from a poorly evaluated technical decision that consumed six months of the team's emotional runway."

Two senior developers spent almost four months exclusively on the migration. A third had to pause feature development to deeply learn Postgres. The product roadmap was delayed by 11 weeks. That delay cost them a $1.2M seed round β€” the lead investor wanted to see traction on a specific feature that stayed in the backlog.

Estimated cost of the delay: impossible to quantify, but XYZ had to raise a $400K bridge round at a 40% lower valuation than expected.

Advice from the new CTO (hired in March): "If your startup has fewer than 10 engineers, don't migrate critical infrastructure unless absolutely necessary. The opportunity cost is brutal."

Concrete Lessons: When Migrating Makes Sense

Not everything is negative. XYZ eventually reduced their bill to $890/month (vs. the $2,400 they paid with Firebase). But it took them nine months, $56,000 in direct and indirect costs, and almost tore the team apart.

Migrate to Supabase IF:

  • You need complex SQL queries that Firestore can't handle (JOINs, aggregations, native full-text search)
  • You have at least one engineer with real Postgres experience (not tutorials β€” real experience)
  • Your Firebase bill exceeds $5,000/month and you've optimized everything possible
  • You have at least four months of runway and can let the team focus on infrastructure

DON'T migrate IF:

  • Your team has fewer than five engineers
  • You're in rapid growth and need new features every sprint
  • You lack experience with relational databases
  • Your Firebase bill is under $2,000/month (the savings don't justify the migration cost)

Optimize BEFORE migrating:

  1. Audit your current bill. XYZ discovered that 40% of their Firebase cost came from inefficient queries fetching complete documents when only three fields were needed. Optimizing that would have saved them $960/month without migrating anything.

  2. Run a pilot project in Supabase with a non-critical feature. XYZ migrated everything at once. Fatal mistake. They should have moved a small feature first (say, the comment system) and learned over two months.

  3. Budget 3x the estimated time. If you think it will take one month, budget for three. If you think it will cost $10K in engineering time, budget for $30K.

  4. Set up billing alerts from day one. Supabase has billing webhooks. XYZ didn't set them up until their bill exploded. They now have an Edge Function that sends a Slack alert if the projected bill exceeds $1,500/month.

  5. Hire external consultancy for initial architecture. $2,400 for a freelance DBA over two weeks can save you $20,000 in future costs. XYZ did this late.

In Summary: The Real Cost of Migrating Is Never Just Technical

Supabase is objectively better than Firebase for certain use cases. Postgres is more powerful, Edge Functions are faster, Row Level Security is superior. However, migrating is never just about copying data and rewriting code.

The real cost is in learning, mistakes, lost time, and opportunities not pursued because your team is busy migrating tables. XYZ eventually succeeded β€” their stack is now more robust. But they almost didn't make it.

A question for you: are you considering migrating because Supabase is genuinely better for your use case, or because it's trendy on Twitter and you want the technical clout? If it's the latter, save yourself the pain.

For more insights on deployment strategies, check out our article on how OpenAI Boosts Deployments with New Deployment Unit. Additionally, if you're interested in enterprise-level deployments, you might find Claude at Cognizant: Inside a True Enterprise Deployment informative.

πŸ‡ͺπŸ‡Έ Also available in Spanish: Leer en espaΓ±ol

𝕏in