Scaling a Lovable app past the Supabase free tier
The default Lovable stack (Lovable plus Supabase) is genuinely good for the first version of an app. Single signup, generous free tier, auth and database and storage bundled. The problems show up later, when your app has real users and the bill or the architecture starts pushing back.
This post is about that "later." What actually breaks, and what to do about it without rewriting your app.
Contents
- Where the default stack breaks
- Three paths off
- Migrating the database
- Keeping auth working during the move
- What you do not need to migrate
Where the default stack breaks
The free tier itself is rarely the problem. Most apps that hit the free-tier ceiling are happy to pay. The breaks are usually structural.
The pricing cliff. Supabase free is two projects, 500MB database, 5GB bandwidth. The Pro plan is $25 per month and covers most growing apps. But certain dimensions (database compute add-ons, larger storage, point-in-time recovery, longer log retention) are priced per dimension on top of the base. The bill can get to $150 per month surprisingly fast for an app with modest traffic but a database that grew.
Single engine. Supabase is Postgres-only. If your app needs anything else (Redis for sessions, vector search at scale, ClickHouse for analytics, MongoDB for a third-party integration) you are now multi-vendor. That is fine, it just changes the operational story.
Auth coupled to the database. Supabase auth lives in your Supabase Postgres. The auth.users table is in the same instance as your application tables, and row-level security policies often reference it. Moving the database without moving the auth is harder than it looks because the foreign keys and RLS policies expect both to be present.
Connection limits. Supabase's pooled connection limit scales with the compute size, not the plan tier. A small instance tops out at a couple hundred pooler clients, and the ceiling only rises when you pay for more compute. A growing app with serverless functions can hit that ceiling in a single bad afternoon. The fix exists (more compute, transaction-mode pooling) but it is a fix you have to think about, and Lovable does not warn you about it in advance.
None of these are dealbreakers on their own. The decision to move usually comes when two of them happen at once.
Three paths off
There are three reasonable moves.
Stay on Supabase, pay for the upgrades. If you like the bundled developer experience and your app fits within Supabase's shape, this is the cheapest path measured in your time. Pay the $25 base, add the dimensions you need, do not migrate. The cost is a yearly $300 to $1800 depending on growth, but you keep your weekends.
Move the database, keep Supabase for auth. This is what most teams actually do. The Postgres goes to a database vendor (Layerbase, Neon, your own host). Supabase becomes auth-only. The free tier for auth alone is generous, your bill drops, and you keep the auth UX you already wired up. One caveat if you lean on the free tier for this: a free Supabase project pauses after about seven days of inactivity, and a paused project takes its Auth API down with it, so every login fails until you restore it. Keep the auth-only project on a paid plan, or treat auth-on-Supabase as a bridge rather than the destination. It is still the lowest-risk move because it changes one thing at a time.
Move everything off Supabase. Database, auth, and storage all leave. This used to mean re-homing auth on Clerk or Better-Auth and forcing every user to reset their password, which is why most teams avoided it. That part changed: migrating a Supabase project to Layerbase brings the auth.users table across with the password hashes intact, so you skip the mass reset. Storage (the actual files) is still a separate copy to R2 or S3. The users and their credentials travel, which removes the worst part, though Layerbase does not run a login service, so you still wire login against the migrated table on the new side.
I will cover the middle path in detail because it is still what a lot of Lovable teams reach for first, and the steps are concrete. The full-move auth import has its own walkthrough in Migrating from Supabase to Layerbase.
Migrating the database
The migration is the same shape as any Postgres-to-Postgres move: dump from Supabase, restore to the new host, repoint the connection string.
Layerbase has a built-in flow that runs the dump and restore for you, and imports your Supabase auth users in the same pass. In the dashboard, choose New database, then Migrating from another platform, then Supabase. Paste a Supabase access token, pick the project, paste its database password once, and it copies the schema, the data, and the users. That is the path most people want; the walkthrough is in Migrating from Supabase to Layerbase.
If you would rather run the dump by hand, the manual steps are below.
Step 1: Provision the new database
Visit layerbase.com/create/postgresql and create a Postgres named for the project (lovable-app-prod). Provisioning is about ten seconds.
Copy the connection string. It looks like:
postgresql://layerbase:<password>@your-host.cloud.layerbase.dev:5432/app?sslmode=requireStep 2: Dump from Supabase
Supabase exposes a direct connection string in your project dashboard (Settings, Database, Connection string, "URI"). Use it with pg_dump:
pg_dump \
--no-owner --no-acl \
--schema=public \
--schema=storage \
"postgresql://postgres:<password>@db.<project>.supabase.co:5432/postgres" \
> supabase-dump.sqlA few things:
--no-owner --no-aclstrips the Supabase-specific ownership and grants. Without these flags, the restore will try toGRANTthings to roles that do not exist on the destination and the whole restore will fail.--schema=public --schema=storagedumps just your application tables and the storage tables. Theauthschema stays on Supabase if you are following the middle path.- Run from a machine with the same Postgres major version as Supabase (currently 17). Mismatched
pg_dumpversions can produce dumps the destination cannot read.
Step 3: Restore to Layerbase
psql \
"postgresql://layerbase:<password>@your-host.cloud.layerbase.dev:5432/app?sslmode=require" \
< supabase-dump.sqlFor a small database (under 1GB) this takes a couple of minutes. For larger databases use pg_restore with -j 4 for parallel restore:
# If you used pg_dump -Fc (custom format) instead of plain SQL:
pg_restore \
--no-owner --no-acl -j 4 \
-d "postgresql://layerbase:<password>@your-host.cloud.layerbase.dev:5432/app?sslmode=require" \
supabase-dump.dumpStep 4: Repoint Lovable
In your Lovable env settings, change DATABASE_URL to the new connection string. If your generated code talks to the database through the Supabase JS client (not just auth), that swap does not happen in the browser bundle: supabase-js is an HTTP client that is safe to run in the SPA, while postgres and pg are raw TCP drivers that need a server process. Move those queries into a server layer first (a Supabase Edge Function, or your own API after a GitHub sync) and point the driver at the new connection string there. Connect a Postgres database to a Lovable app walks through both paths.
Step 5: Verify and cut over
Before you flip production, run the app against the new database in a staging environment. Spot-check the row count for each table:
select schemaname, relname, n_live_tup
from pg_stat_user_tables
order by n_live_tup desc;The counts should match Supabase. If they do, flip production by deploying the env var change. If they do not, find out why before flipping.
Keeping auth working during the move
You have two options here, and the second one got a lot easier recently.
Bring auth with you. Migrating the Supabase project to Layerbase copies auth.users across with the bcrypt password hashes untouched, so you are not forced to reset everyone, and you manage the accounts from the Auth console. The user IDs (UUIDs) are preserved, so the user_id columns in your tables still match and the foreign keys below are not a problem. The one caveat: Layerbase does not run a login service, so you wire login against the migrated table yourself. Migrating from Supabase to Layerbase covers exactly how, including why this is not the Better Auth wizard.
Leave auth on Supabase. Still reasonable if you only want to move the database and not think about auth yet. The auth table lookups keep going to Supabase while your application queries hit Layerbase. The two are decoupled. The catch on a free project: if it sits idle for about a week Supabase pauses it, and a paused project's Auth API is down until you restore it, so keep the auth-only project on a paid plan if logins need to stay up.
If you go the leave-it route, the piece that needs attention is foreign keys. If your application tables have FOREIGN KEY (user_id) REFERENCES auth.users(id), that foreign key cannot exist on Layerbase because the auth.users table is on Supabase. Drop those foreign keys:
alter table public.posts drop constraint if exists posts_user_id_fkey;
alter table public.comments drop constraint if exists comments_user_id_fkey;
-- and so on for each table that references auth.usersYou lose database-enforced referential integrity for the user reference. You can replace it with application-level checks (validate the user exists before insert) or accept the looser coupling. Most teams accept it because the auth side controls user creation.
The user IDs themselves stay the same (UUIDs from Supabase). All your user_id columns continue to work.
Row-level security policies that reference auth.uid() need to be reimplemented in your application code, because auth.uid() is a Supabase-specific function. This is the part that takes the most work. In practice, most Lovable apps use RLS lightly (a few "user can only see their own rows" policies) and replacing those with application-level filters takes an afternoon.
What you do not need to migrate
A short list to keep the scope clear.
- Auth users. Optional. You can bring them to Layerbase with their password hashes (no resets), or leave them on Supabase if you only want to move the database for now. The middle path just means you do not have to move them yet, not that you cannot.
- Storage objects. If you use Supabase storage and want to leave it, that is a separate migration. Most teams leave it in place for the same reason as auth: the cost is low and the migration is annoying.
- Edge functions. Lovable's deploy story does not depend on Supabase edge functions. If you wrote any (you probably did not), they need to be reimplemented as API routes in your Lovable app.
- Realtime subscriptions. If you use Supabase realtime, you will need a replacement. Postgres LISTEN/NOTIFY plus a thin WebSocket layer works. Or skip it and use polling. Realtime is the part of Supabase that is hardest to leave; if you depend on it heavily, the middle path may not be the right one.
Wrapping up
The short version of "do I move and how":
- If the Supabase bill is $25 per month and you are happy with the experience, do not move. There is no win.
- If the bill is climbing past $100 per month and growing, run the migration. It pays for itself.
- Move the database first. This is the lowest-risk, highest-leverage step.
- Bring the auth users along if you want to leave Supabase entirely. The hashes migrate, so it no longer means a forced reset for every user. Or keep auth on Supabase for now and move it later. Both are fine.
The destination is your choice. Layerbase Cloud gives you plain managed Postgres with room to add Redis and Qdrant later if your app grows that way. Neon gives you branching for preview deploys. A $5 VPS gives you a fixed bill and operational work. All three are valid, and the migration steps above are identical for any destination that speaks Postgres.
For local development against the new setup, the Layerbase CLI runs Postgres locally and accepts the same dump file. Develop against a local copy, deploy against the cloud one.
Keep reading
- Supabase alternatives for Lovable appsLovable defaults to Supabase. Here is the honest shortlist of what else to use for the database layer, and when each one is the right pick.
- Migrating from Supabase to LayerbaseMove your Postgres and your Supabase Auth users to Layerbase in one pass. The password hashes come across untouched, so you skip the forced reset, then you wire login against your own database.
- Connect a Postgres database to a Lovable appLovable runs on Supabase by design, and you cannot swap in your own Postgres from inside a Lovable-hosted app. Here are the two paths that actually work, and where your own database fits.
- Supabase alternatives: what to use when the meter stops making senseSupabase is a good product with a metered bill and a Postgres-only ceiling. Here is the honest shortlist of alternatives, what each one is actually for, and when you should just stay.