# Free Firebase and Supabase Alternative: SQLite You Own

> No paused projects, no daily read quota. Your database lives on your own server, and the same app can move to Supabase or MongoDB when you outgrow it.

Source: https://boringpush.com/blog/free-firebase-supabase-alternative-sqlite

## Your side project was paused while you slept

You ship a small app on Supabase's free plan. A week later you're busy with your day job, nobody signs in, and the project goes quiet. Supabase's pricing page says it plainly: "Free projects are paused after 1 week of inactivity."

Firebase's free plan has a different edge. Cloud Firestore on the Spark plan allows 50K document reads a day. A busy list page that reads 50 documents per visit hits that after about 1,000 visits.

Neither is a scandal. Free tiers need limits. But if you want a database that's free, always on and has no meter, the oldest answer still works: a database on a server you rent.

## What you get

Your database lives on your own server, right next to your app. It never pauses, has no daily quota and costs nothing beyond the server.

Sign-in, file uploads, backups and upkeep come with it. And when you're ready for something bigger, the same app runs on Supabase or MongoDB.

## The free tiers, side by side

Supabase and Firebase numbers come from their own pricing pages, checked on 2026-10-20.

| | Supabase Free | Firebase Spark | BoringPush on SQLite |
|---|---|---|---|
| Price | $0 | $0 | $0 (runs on your $4–6 server) |
| Paid step | Pro from $25/mo, $10 compute credits included | Blaze, pay as you go | A bigger server, when you need one |
| Database size | 500 MB | 1 GiB stored (Firestore) | Your disk |
| Daily quota | None | 50K reads, 20K writes, 20K deletes | None |
| Goes to sleep | After 1 week of inactivity | Not stated on the page | No |
| Active projects | 2 | Not stated on the page | As many as your server holds |
| Sign-in included | Yes, 50,000 monthly active users | Separate product, own limits | Google and email magic links |
| File storage | 1 GB | Separate product | Uploads go straight to Cloudflare R2 or Amazon S3 |

## Everything that comes with it

**Sign-in.** Your users can sign in with Google or an email link. They live in your own database, not in a vendor's console.

**File uploads.** Files go from the browser straight to your own storage bucket on Cloudflare R2 or Amazon S3. They never slow your server down.

**Upkeep that runs itself.** Your database is snapshotted every day, and the last 7 days are kept. It's tidied up every hour and every month so it stays small and quick.

**Off-site backups.** A snapshot on the same disk dies with the disk. So there's a one-command copy to R2 or S3, under separate credentials, and you can make it impossible to delete for a set number of days.

## Outgrow it? Change one setting

This is what makes a SQLite start safe. BoringPush speaks to your data in one language, and three databases understand it: SQLite, Supabase and MongoDB.

```bash
DB_PROVIDER=sqlite      # the default
# DB_PROVIDER=supabase
# DB_PROVIDER=mongodb
```

"SQLite now, Supabase later" isn't a rewrite. You move the data, flip the setting and run your tests. If you need [several servers writing at once](/blog/one-codebase-three-databases-sqlite-supabase-mongodb), that's the moment to switch.

## Safer around AI agents

Coding agents like to "just check the database." In BoringPush, an agent looks at your data through a read-only window, so a careless query can't delete anything. Changes to the live database need a human at the keyboard. The [PocketOS write-up](/blog/pocketos-agent-disaster-defenses) explains why that matters.

## Know this first

Firebase and Supabase do things a single database file doesn't. Live updates that push changes to every open browser are the big one. Mobile SDKs with offline sync are another.

Scaling is the third. One database lives on one server, so you scale up, not out. And somebody, you, owns the server and its disk.

For a typical SaaS with users, records, payments and a dashboard, none of that bites for a long time. And if your app does need live updates, BoringPush runs on Supabase with one setting.

## Why BoringPush is the way to do this

Starting on a hosted backend means starting with someone else's limits. Starting on your own database means starting with none, and still having a way up.

BoringPush gives you both: a database that's free and always on today, and one setting that moves you to Supabase or MongoDB later. Nothing to rewrite, nothing you can't leave. That's the safest way to begin.

## FAQ

### Is SQLite really OK for a production SaaS?

For one server and normal web traffic, yes, with backups in place. The limit is concurrent writers: SQLite allows one write at a time, so a write-heavy app on many servers needs Postgres. See the [SQLite production playbook](/blog/sqlite-prod-playbook).

### What happens to my data if the server dies?

The daily snapshots on that server go with it, which is why off-site backups exist. Run the off-site backup on a schedule and your latest snapshot lives in R2 or S3, under separate credentials. With the lock on, those credentials can't delete it early.

### Can I start on Supabase and move to SQLite instead?

Yes, it works both ways. The data shape is the same on all three, so the move is an export plus one setting. Try it on a test copy first.

### Do I need Firebase for Google sign-in?

No. Google sign-in and email links are built in, and users are stored in whichever database you chose. You need a Google OAuth client from Google, nothing else.

### How big can the database get?

Far bigger than a 500 MB free tier. The practical limit is your server's disk.

## Keep reading

- [One Codebase, Three Databases: SQLite, Supabase, MongoDB](/blog/one-codebase-three-databases-sqlite-supabase-mongodb) — how the three stay in step
- [SQLite vs Mongo vs Supabase: 2 Triggers End the Debate](/blog/sqlite-vs-mongodb-vs-supabase-nextjs) — when to switch
- [Free Vercel Alternative: Host Next.js on a $6 VPS](/blog/free-vercel-alternative-nextjs-vps) — the server your database lives on

[Get BoringPush →](/#get)
