Costs Don't Spike All at Once
Your SaaS backend doesn't get expensive all at once. It happens one unoptimized query, one uncached response, one unmonitored background job at a time. Each one is small enough to ignore. Together, they double your bill.
The problem isn't that cloud services are overpriced. The problem is that their pricing models reward efficiency and punish waste, and most teams don't realize which of their patterns are wasteful until the invoice arrives.
If you're building a SaaS product and want to get the architecture right from the start, start here: Custom software development.
This post breaks down the five cost drivers that actually matter, with real numbers from Firebase and Supabase to make the patterns concrete. For broader architecture context, see: SaaS architecture for scalability.
The 5 Cost Drivers
Every expensive SaaS backend traces back to one or more of these: unbounded database operations, egress, background jobs, data growth, and pricing model mismatch. Here's how each one works and what to do about it.
Unbounded Database Reads and Writes
This is the most common cost driver. It looks innocent: a list page that loads all records, a real-time listener that re-fetches on every change, a dashboard that queries the same data on every page load.
How It Costs You on Firebase
Firestore charges per operation on the Blaze plan: $0.06 per 100K reads, $0.18 per 100K writes, $0.02 per 100K deletes. The free tier gives you 50K reads, 20K writes, and 20K deletes per day.
These numbers look small. But a list page with 100 items that re-renders on every navigation is 100 reads per page view. If 500 users hit that page 10 times per day, that's 500,000 reads per day, or about $0.30/day just for one list page. Add real-time listeners that re-read on any document change, and reads compound fast.
How It Costs You on Supabase
Supabase doesn't charge per read. Instead, Postgres queries consume compute. Supabase's Pro plan ($25/month) includes a Micro compute instance. For production workloads, you need at least a Large instance ($110/month) to get dedicated CPU.
Unoptimized queries (missing indexes, full table scans, N+1 patterns) don't show up as line items. They show up as slow responses, connection pool exhaustion, and the need to upgrade compute to handle what a tuned database could handle on a smaller instance.
The Fix
- Paginate everything. No list should load all records.
- Use cursor-based pagination, not OFFSET (which gets slower as you go deeper).
- Cache repeated reads. If a dashboard shows the same summary to every user, compute it once and cache it.
- Denormalize aggregates. Instead of counting records on every request, maintain a summary document or materialized view.
Egress Surprises
Egress is data leaving your cloud provider's network. Every API response, image download, file transfer, and webhook payload generates egress. It's invisible in development and obvious on the invoice.
How It Costs You on Firebase
Firebase Hosting includes 10 GB/month of bandwidth on the free tier. Beyond that, Blaze plan bandwidth for Cloud Storage is $0.15/GB for uncached content. Firestore egress is separate from read charges: you pay for the bytes transferred, not just the operation count.
An image-heavy app serving 500 KB images to 1,000 daily users downloading 10 images each generates about 150 GB/month of egress just from images, costing roughly $22/month from storage egress alone.
How It Costs You on Supabase
Supabase includes bandwidth per tier: 5 GB on Free, 250 GB on Pro ($25/month), 250 GB on Team ($599/month). Overages are billed per GB. The bandwidth quota covers Storage, Realtime, Auth, Functions, and Database egress combined.
For a Pro plan, 250 GB sounds generous until you realize it covers all services. A busy real-time feature or file-heavy application can eat through it.
The Fix
- Put a CDN in front of everything static. Images, JS bundles, fonts, and CSS should never hit your origin server twice.
- Compress API responses. Enable gzip/brotli at the edge.
- Optimize images. Serve WebP, use responsive sizes, and lazy-load below the fold.
- Cache aggressively. Set proper cache headers so repeated requests don't generate new egress.
Background Jobs and Functions
Serverless functions are convenient. They're also easy to over-use. A function that runs on every database write, a cron job that fires every minute, a webhook handler that does too much work per invocation, these add up.
How It Costs You on Firebase
Cloud Functions (1st gen) charges per invocation plus compute time: $0.40 per million invocations, $0.0000025 per GB-second of memory, $0.00001 per GHz-second of CPU. The free tier includes 2 million invocations/month.
A function that triggers on every Firestore write and takes 500ms to execute doesn't sound expensive. But 100K writes/day means 100K invocations/day, or 3 million/month. At 256 MB memory and 500ms each, that's roughly 375,000 GB-seconds/month. After the free tier, you're paying for compute on every invocation.
How It Costs You on Supabase
Supabase Edge Functions run on Deno Deploy with a 2-second CPU time limit per request and a 150-second idle timeout. Functions are included in paid plans, but the compute they consume comes from your overall Supabase compute allocation.
The risk isn't per-invocation cost; it's that poorly written functions saturate your Edge Function capacity and force compute upgrades.
The Fix
- Don't trigger functions on every write. Batch where possible.
- Use job queues for background work. Process in batches, not per-event.
- Set appropriate schedules. Does that cron really need to run every minute, or would every 15 minutes work?
- Add timeouts. Kill functions that run longer than expected rather than letting them consume resources silently.
Data Growth Without Retention
Databases grow. Without cleanup, they grow forever. Storage costs compound monthly, and query performance degrades as tables get larger.
How It Costs You on Firebase
Firestore charges $0.18/GB/month for document storage. Cloud Storage charges $0.026/GB/month. These seem small, but they only go up. An app that creates 100K documents/month at 5 KB each adds 500 MB/year of Firestore storage. After three years, you're paying for 1.5 GB of data you may never query again.
The bigger cost is query performance. Larger collections mean slower queries (especially without proper indexing), which means more compute, which means higher bills or degraded user experience.
How It Costs You on Supabase
Supabase includes 8 GB of database storage on the Pro plan. Beyond that, additional storage is billed per GB. Postgres performance degrades with table bloat (dead tuples from updates and deletes), requiring periodic VACUUM operations.
Without retention policies, your database grows until you either upgrade compute to handle the size or queries start timing out.
The Fix
- Define retention policies from day one. How long does data need to be queryable?
- Archive old data. Move it to cheaper storage (S3, GCS) and keep Snowflake or Postgres lean.
- Run cleanup jobs. Soft-deletes are fine, but eventually delete or archive the underlying data.
- Monitor table sizes. Set alerts when tables cross size thresholds.
Pricing Model Mismatch
Firebase and Supabase use fundamentally different pricing models. Choosing the wrong one for your usage pattern is an expensive mistake.
Per-Operation (Firebase)
Firebase charges per read, write, delete, invocation, and byte transferred. This works well when usage is low and predictable. It breaks when usage scales unevenly, particularly reads. A feature that's popular but read-heavy (dashboards, search results, feeds) becomes disproportionately expensive.
Compute-Baseline (Supabase)
Supabase charges a fixed monthly fee per compute instance. A Micro instance is $10/month; a Large instance is $110/month. You get predictable compute, and queries don't have per-operation costs. This works well for steady, predictable workloads. It breaks when traffic spikes beyond your instance capacity, requiring an upgrade or suffering degraded performance.
When Each Model Works
Per-operation (Firebase) works when:
- Usage is low and sporadic
- You have many small apps with minimal traffic
- Read/write patterns are balanced
Compute-baseline (Supabase) works when:
- Usage is steady and growing
- You have heavy read workloads (dashboards, analytics)
- You want predictable monthly costs
The fix: Model your expected usage against both pricing structures before choosing. Use the free tiers to benchmark real patterns, not projections. See also: SaaS MVP development guide.
Firebase Cost Behavior in Practice
Here is what a typical mid-stage SaaS app looks like on Firebase's Blaze plan.
Scenario: Task management SaaS, 2,000 monthly active users, moderate usage.
| Service | Usage | Estimated Monthly Cost |
|---|---|---|
| Firestore reads | 15M reads/month | ~$9 |
| Firestore writes | 3M writes/month | ~$5.40 |
| Firestore storage | 5 GB | ~$0.90 |
| Cloud Functions | 5M invocations, 256 MB, 300ms avg | ~$3-5 |
| Cloud Storage | 50 GB stored, 200 GB download | ~$31 |
| Hosting bandwidth | 100 GB/month | ~$15 |
| Authentication | 2,000 MAU | Free |
| Estimated total | ~$65-70/month |
This looks cheap. The problem is what happens at 10x scale. Firestore reads go from $9 to $90. Cloud Storage egress goes from $31 to $310. Functions from $5 to $50. The total goes from $70 to $450+ without any architecture changes.
The per-operation model scales linearly with usage, which sounds fair but means costs track directly with growth. Without optimization, you're paying a tax on every new user.
Supabase Cost Behavior in Practice
Here is the same scenario on Supabase.
Scenario: Task management SaaS, 2,000 monthly active users, moderate usage.
| Service | Usage | Estimated Monthly Cost |
|---|---|---|
| Pro plan base | Includes Micro compute | $25 |
| Compute upgrade (Small) | Steady production workload | +$5 ($15 - $10 included) |
| Database storage | 5 GB (within 8 GB included) | $0 |
| Bandwidth | 150 GB/month (within 250 GB) | $0 |
| Auth | 2,000 MAU (within 100K) | $0 |
| File storage | 50 GB (within 100 GB) | $0 |
| Estimated total | ~$30/month |
At 10x scale, the main cost increase is compute. Moving from Small ($15/month) to Medium ($60/month) or Large ($110/month) to handle the load. Bandwidth might exceed the 250 GB included, adding per-GB overages. But the growth curve is stepped, not linear. You pay more at each compute tier, not on every additional query.
The trade-off: Supabase is cheaper at steady-state but less flexible when you need different scaling dimensions (e.g., scaling reads independently of writes).
Practical Mitigations Checklist
These apply regardless of which backend you use.
- Paginate every list endpoint. Default to 20-50 items. Never return unbounded results.
- Add application-level caching. Redis or in-memory cache for repeated queries. Even 60-second TTLs reduce database load dramatically.
- Put a CDN in front of all static assets. Images, fonts, CSS, JS. One-time setup, permanent savings.
- Implement data retention policies. Define how long each data type needs to live. Archive or delete the rest.
- Monitor usage dashboards weekly. Don't wait for the monthly bill. Both Firebase and Supabase provide usage dashboards.
- Set billing alerts. Both platforms support spend alerts. Set them at 50%, 80%, and 100% of your expected bill.
- Audit background jobs quarterly. Review every function and cron. Kill the ones that no longer serve a purpose.
- Load test with realistic data. Cost benchmarks on empty databases are meaningless. Test with production-scale data volumes.
- Review queries before shipping. One missing index can cost more than a month of compute. Use EXPLAIN on Postgres; review Firestore query patterns for unnecessary collection reads.
Cost predictability is one of six dimensions we use to evaluate tools. Get it right early, and scaling becomes a planning exercise instead of a crisis.
For more on the build vs buy decision: Custom vs off-the-shelf software.
Best For / Not For
This guide is best for:
- Teams choosing between Firebase and Supabase for a SaaS backend
- Auditing existing backend costs to find savings
- Planning infrastructure for a Next.js or full-stack web application
- Understanding which pricing model fits your usage patterns
This guide is not for:
- Enterprise platforms with dedicated infrastructure teams (different cost dynamics)
- Static sites (minimal backend costs)
- Teams with dedicated DevOps managing custom Kubernetes clusters
Getting Help
If your backend costs are growing faster than your revenue, or if you're planning a new SaaS product and want to avoid the common cost traps, we can help you choose the right architecture and optimize what you've already built.
Start here: Custom software development
Have a specific question? Get in touch.
FAQs
1. Why is my SaaS backend so expensive?
The five most common cost drivers are unbounded database reads, egress surprises, background jobs running too often, data growth without retention policies, and pricing model mismatch. Most teams discover these after launch, not before.
2. Is Firebase expensive for small apps?
No. Firebase's Spark (free) tier is generous for small apps: 1 GB Firestore storage, 50K reads/day, 20K writes/day. Costs increase on the Blaze (pay-as-you-go) plan as usage scales, particularly Firestore reads and egress.
3. Is Supabase cheaper than Firebase?
It depends on your usage pattern. Supabase's compute-baseline model is more predictable for steady workloads. Firebase's per-operation model can be cheaper for low-volume apps but scales unpredictably. Model your expected usage against both.
4. How do I reduce SaaS backend costs?
Start with pagination (stop loading all records), add caching (CDN for static assets, application cache for repeated queries), implement retention policies (archive or delete old data), and monitor usage dashboards before bills arrive.
5. What is egress and why does it matter?
Egress is data leaving your cloud provider's network. Every API response, image download, and file transfer generates egress. It's often the most surprising cost because it's invisible until the bill arrives.
6. Should I use Firebase or Supabase for my Next.js app?
Firebase works well if you need real-time listeners, simple auth, and are comfortable with a NoSQL model. Supabase works well if you prefer Postgres, need relational queries, and want a more predictable pricing model. Both integrate with Next.js.
Eiji
Founder & Lead Developer at eidoSOFT
How I Evaluate Developer Tools for Production
How to Calculate ROI on Business Automation (Template Included)
Related Articles
SaaS Architecture for Scalability - Multi-Tenancy, Databases, and Microservices
A comprehensive guide to SaaS architecture covering multi-tenancy models, AI-native design patterns, serverless databases, microservices, credit-based pricing, and infrastructure decisions for building scalable products in 2026.
SaaS MVP Development Guide - Launch Your Product in 8-12 Weeks
A practical guide to SaaS MVP development covering feature prioritization, tech stack decisions, development timelines, and launch strategy to get your product to market faster.