The self-hosting argument never resolves because both sides are right about different things.
Own your data, no lock-in, cheaper at scale. Also true: it's an operational tax, upgrades cascade, and local drifts from prod.
Both hold. "Should I self-host Supabase" isn't one question, it's three, and most people answer all three with a single decision.
- Local dev, staging, and production are separate decisions with separate constraints
- Picking one answer for all three is where the pain comes from
- Local: worst default, cheapest to change
- Production: usually-correct default, most expensive to change
- Most people optimise the expensive one and inherit the cheap one
The three decisions
| Decision | Optimises for | Cost of getting it wrong |
|---|---|---|
| Local dev | Iteration speed, low friction | Paid daily, compounds quietly |
| Staging | Fidelity to production | Bugs reach users |
| Production | Reliability, operational burden | Paid at the worst possible moment |
They pull in opposite directions. Local wants to be fast and disposable. Staging wants to be identical to prod. Production wants to be reliable and ideally someone else's problem.
No single answer satisfies all three, which is why whichever one you pick feels wrong somewhere.
Local: the one worth changing
Worst default, and almost nobody revisits it.
The standard setup runs the full container stack. Gigabytes of RAM, tens of seconds to boot, a laptop that gets loud. The consequence isn't complaints, it's that people stop running it.
That's the actual cost and it appears in no comparison table. A local environment nobody runs is one that quietly stops working, and you find out the day prod breaks and three people spend an afternoon building a repro from scratch.
Switching cost here is also the lowest of the three. Local is disposable. If a lighter setup doesn't work, you lost an afternoon.
How to tell: is anyone on your team pointing at staging instead of running locally? Then you already have your answer.
Single-binary runtimes exist for this now. tinbase is the one my team builds, so discount accordingly. It serves the Supabase-compatible surface from one process. It's a local dev runtime, not a production self-hosting replacement, which is exactly why these decisions need separating.
Staging: the one people skip
Staging is where the parity argument belongs, and it's usually where nobody's looking.
If local runs a different implementation from prod, local passing stops guaranteeing prod passing. Real cost. But the fix isn't making local heavier, it's having something between local and prod that's genuinely faithful.
Run the full stack in staging. Once before a release, not every morning. One boot a week instead of one a day, and fidelity lands where fidelity matters.
Skip staging and try to get parity out of local, and you end up with the worst combination available: a heavy local setup that still isn't identical to prod.
Production: highest stakes, usually-correct default
Self-hosting prod means owning image updates, CVE patching, cert renewal, backup verification, and restore drills.
With a platform team, that amortises across roles that already exist. Without one, it's evenings and weekends, and it has no deadline pressure right up until it has all of it.
The honest test isn't cost. It's: when did you last restore from a backup?
If never, you're not self-hosting. You're holding an unverified assumption about data you can't afford to lose. A backup nobody has restored is a hypothesis.
Self-hosting prod is reasonable when: someone owns operations, upgrades have a runbook, restore drills are scheduled, and the hosted bill justifies the work. All four. Not one.
The mistake
People spend their thinking on the production decision, where the default is usually right and switching is expensive. Then they inherit the local decision, where the default is usually wrong and switching costs an afternoon.
Flip the allocation. Change local this week. Leave prod alone until all four conditions above are true.
Optimise the decision you pay for daily, not the one you argue about online.
Worked examples
Solo dev with a live product:
| Layer | Choice | Why |
|---|---|---|
| Local | Lightweight, no containers | Runs constantly, friction compounds |
| Staging | Full stack, before releases | Parity where it counts, weekly not daily |
| Production | Hosted | No ops capacity, no restore drills happening |
Team of fifteen with a platform engineer:
| Layer | Choice | Why |
|---|---|---|
| Local | Developer preference | Individual cost, individual call |
| Staging | Full stack, always running | Fidelity is cheap when someone owns it |
| Production | Either, run the numbers | Ops capacity makes it a real option |
Notice what moves. Production changes with team structure. Staging barely moves. Local is personal and should be.
The short version
If you have no staging environment, local is doing two jobs and doing at least one badly. Fix that first.
Then: light local, faithful staging, boring production. Revisit production only when all four conditions hold.
Which of the three did you actually decide on purpose? My bet is production, because it feels consequential, and that local came from a quickstart guide three years ago and nobody has touched it since.
Top comments (0)