I randomly checked my Firebase dashboard one day and my heart sank.
$300. In one month. For an app I thought was "basically free to run."
Turns out "free tier" doesn't mean much when you're making inefficient queries to thousands of active users.
Here's what went wrong, and why I eventually migrated away from Firebase entirely.
The Three Mistakes That Cost Me $300
Mistake #1: No Caching (The Biggest One)
I was fetching the same data over and over again. Every time a user opened the app, I'd query Firestore for data that hadn't changed in months.
My app shows past exam questions. These questions don't change. They're literally historical data. But every single user, every single session, was hitting Firestore to fetch them.
The math:
- ~10,000 active users
- Average 3-5 app opens per day per active user
- Each open = full query to fetch questions
- Firestore charges per document read
That's 30,000-50,000 unnecessary Firestore reads per day. Every single day.
What I should have done: Aggressively cache anything that doesn't change. Past exam questions? Cache them locally. Don't hit the database unless absolutely necessary.
Mistake #2: No Pagination
I was loading entire question sets at once. Instead of showing 10 questions and loading more as needed, I'd fetch 50-100 questions upfront.
More documents read = higher bill.
What I should have done: Implement pagination from day one. Load 10-20 items initially, fetch more only when the user scrolls. Firestore charges per read, only read what you need.
Mistake #3: No Billing Alerts
The worst part? I had no idea this was happening until I randomly checked my dashboard.
Firebase lets you set up billing alerts. I didn't. So I went weeks burning money without knowing.
What I should have done: Set up billing alerts immediately. Get notified when you hit $10, $25, $50. Don't wait until you're at $300 to find out.
What I Did to Fix It
Fix #1: Aggressive Caching
I implemented local caching for anything that doesn't change. Past questions get cached on the device after the first fetch. Users only hit Firestore when:
- They're accessing new content
- Cache is outdated (which for past questions, never happens)
This alone cut my Firestore reads by ~80%.
Fix #2: Pagination
I rewrote my queries to load data in batches:
// Before: Load everything
const questions = await firestore()
.collection('questions')
.get();
// After: Load 20 at a time
const questions = await firestore()
.collection('questions')
.limit(20)
.get();
Users don't need to see 100 questions at once. They need 10-20, then more as they scroll.
Fix #3: Billing Alerts
I set up alerts in the Firebase console:
- $10 threshold: "Okay, things are running normally"
- $25 threshold: "Check what's spiking"
- $50 threshold: "Something is wrong, investigate now"
This way I'd never wake up to a surprise $300 bill again.
The Bill Dropped... But I Still Migrated Away
After implementing these fixes, my Firebase bill dropped to ~$15-20/month. Much better.
But here's the thing: Firebase gets expensive at scale, even when you're being careful.
Even with ~10,000 active users , I was constantly worried about costs. One inefficient query, one spike in usage, and my bill could explode again. I didn't want to spend my time optimizing for Firebase's pricing model, I wanted to build features.
So I migrated.
My New Stack (And Why It's Cheaper)
I moved to:
- NestJS backend (full control over my API)
- MongoDB Atlas (free tierno per-read pricing)
- Cloudflare R2 (storage with generous free tier)
- $5/month VPS (to run the NestJS backend)
Total cost now: $5/month. That's it. Not $15-20. Not $300. Just the VPS.
MongoDB Atlas free tier handles my database. Cloudflare R2 free tier handles my storage. The only thing I actually pay for is the server to run my backend.
What I Learned About Firebase
Firebase is great for:
- Prototypes and MVPs
- Apps with small, predictable traffic
- Teams that don't want to manage infrastructure
Firebase is NOT great for:
- Apps with high read volume
- Apps where data doesn't change often (you're paying to re-fetch the same thing)
- Apps at scale where costs matter
If you're serving mostly static or slowly-changing data to thousands of users, you'll get killed by per-read pricing.
What I'd Do Differently
If I were starting this app from scratch today:
- Set up billing alerts before writing a single line of code - Know when costs spike
- Cache aggressively from day one - If data doesn't change, don't fetch it again
- Implement pagination immediately - Never load more than you need
- Question whether Firebase is the right choice - For high-read, low-write apps, traditional backends are often cheaper
Or honestly? Start with a $5 VPS and a traditional stack. You'll have more control and predictable costs.
The Bottom Line
Firebase's "pay as you go" pricing sounds great until you realize you're paying for every single read, even when you're fetching the same data for the hundredth time.
I went from $0 to $300 in one month because I didn't understand how Firebase pricing works. I fixed it and got down to $15-20/month. Then I migrated entirely and now pay $5/month total.
The lesson: Know your pricing model before you scale. Firebase is convenient, but convenience has a cost.
Written while debugging to: [J. Cole – Poor Thang]
Top comments (0)