Supabase vs PlanetScale for Indie Devs: Pricing Traps and Query Limits

May 16, 2026 8 min read 0 views
Two stylized database icons in contrasting colors with abstract branching schema lines on a minimal gradient background

You picked your stack, shipped your MVP, and now you're watching your free tier usage tick upward. Suddenly the database platform you chose looks a lot more expensive than the landing page suggested. Supabase and PlanetScale are both popular choices for indie developers, but they have very different cost structures β€” and the traps are easy to miss until you've already hit them.

What you'll learn

  • How the free tiers of Supabase and PlanetScale actually work (and when they pause or cut you off)
  • Where the query and row limits live and how fast you'll hit them
  • The pricing jumps you'll encounter going from free to paid
  • Which platform fits which type of project
  • How to stay within limits without rewriting your app

The Platforms at a Glance

Supabase is an open-source Firebase alternative built on PostgreSQL. You get a full Postgres database, authentication, object storage, edge functions, and a real-time subscription layer β€” all in one product. PlanetScale is a MySQL-compatible serverless database platform built on Vitess, the same technology that powers YouTube's database infrastructure. Its headline feature is branching: you can branch your database schema the way you branch code in Git.

Both pitch themselves as developer-friendly, and both are genuinely good products. The difference is in what they optimize for and, critically, how they charge you once you outgrow the free tier.

Supabase Free Tier: What You Actually Get

Supabase's free tier is generous on paper. You get two active projects, 500 MB of database storage, 1 GB of file storage, 50,000 monthly active users for auth, 2 GB of bandwidth, and 500,000 edge function invocations.

The hidden catch is project pausing. If a project receives no requests for seven days, Supabase pauses it automatically. When the next request comes in, the project has to wake up β€” and that cold start can take 20–30 seconds. For a side project you check weekly, this is annoying. For a demo you're showing to a potential client, it's embarrassing.

You can work around this with a simple cron job that pings your Supabase endpoint every few days. It's not elegant, but it works.

Storage and Bandwidth Traps

The 500 MB storage limit sounds reasonable until you realize it counts the database, indexes, and any stored data together. A moderately active app with decent indexing can fill that faster than you expect. Once you exceed it, you're on the paid plan at $25/month β€” there's no middle tier.

Bandwidth is the other trap. Supabase counts egress from the database, storage, and edge functions combined. If you're serving images from Supabase Storage directly to users, 2 GB goes quickly. Cache your assets at the edge or behind a CDN before you ship anything with media.

PlanetScale Free Tier: What You Actually Get

PlanetScale's free tier historically offered one database with 5 GB storage, 1 billion row reads per month, and 10 million row writes per month. That sounds enormous β€” and for most indie apps, it is. A read-heavy app serving thousands of users can stay comfortably within those limits.

Important: PlanetScale changed its pricing structure in 2024, retiring the free Hobby plan for new users and introducing a new Scaler plan as its entry point. If you're evaluating PlanetScale now, check the current plan page directly β€” the numbers shift, and marketing pages sometimes lag behind billing reality.

The key unit on PlanetScale is row reads, not query count. A single SELECT that scans 10,000 rows to return 5 results costs you 10,000 row reads, not 1. This changes how you think about query design significantly.

The Row Reads Problem

Poorly indexed queries are expensive on any database, but on PlanetScale they show up directly in your bill. A full table scan on a table with 100,000 rows consumes 100,000 row reads β€” even if the query returns nothing. Run that query 1,000 times a day and you've burned 100 million row reads before the month is halfway through.

PlanetScale has tooling to help with this. The query insights dashboard shows you which queries are most expensive by rows read, and the platform will actually warn you about missing indexes. Use it. Treat the query insights page as part of your regular development workflow, not something you look at when costs spike.

Pricing Comparison: Free to Paid

FeatureSupabase FreeSupabase Pro ($25/mo)PlanetScale Scaler
Storage500 MB8 GB (then $0.125/GB)10 GB (varies by plan)
Row reads/writesN/A (Postgres)N/A (Postgres)Metered
BranchingNoNoYes
Project pausingYes (7 days)NoNo
Auth includedYesYesNo
RealtimeYesYesNo

The table highlights the key structural difference: Supabase bundles a lot of services, while PlanetScale is laser-focused on the database itself. If you need auth, storage, and realtime out of the box, Supabase's $25/month gets you a lot. If you just need a fast, scalable MySQL database, PlanetScale is the sharper tool.

Query Limits and Connection Handling

Supabase uses PgBouncer for connection pooling by default. Each free project gets a limited number of connections β€” typically around 60 pooled connections, depending on the underlying compute size. For most indie apps this is fine. Where it becomes a problem is serverless deployments: if you're running hundreds of serverless function invocations simultaneously, each one trying to open a database connection, you'll hit limits. Use the pooler connection string, not the direct connection string, in any serverless environment.

PlanetScale handles connections differently because it's serverless by design. There's no persistent connection to manage β€” every query goes through an HTTP API under the hood. This makes it naturally suited to edge and serverless runtimes. You won't run out of connections, but you do trade the ability to use certain Postgres-specific features and transaction patterns.

Transactions and Foreign Keys

PlanetScale does not support foreign key constraints at the database level. This is a deliberate decision tied to how Vitess shards data β€” foreign keys don't work cleanly across shards. You can enforce referential integrity in your application layer, but if you rely on database-level constraints as a safety net, this will bite you.

Supabase is standard Postgres, so you get full foreign key support, check constraints, triggers, and everything else Postgres offers. If your data model is complex or heavily relational, Supabase wins this comparison without contest.

Developer Experience and Tooling

Supabase ships a genuinely good local development setup via the Supabase CLI. You run supabase start and get a full local stack β€” Postgres, Auth, Storage, and the dashboard β€” running in Docker. Migrations are managed with SQL files that you can version control and apply cleanly.

npx supabase init
npx supabase start
npx supabase db diff --use-migra -f add_users_table

PlanetScale's branching workflow is its killer feature for teams, but it's also useful solo. You create a branch off main, make schema changes, and open a deploy request β€” a pull request for your database schema. The platform checks for destructive changes before you merge. This is dramatically safer than running ALTER TABLE directly against a production database.

pscale branch create my-database add-index-to-orders
pscale connect my-database add-index-to-orders --port 3309
# Make your schema changes, then:
pscale deploy-request create my-database add-index-to-orders

Both workflows are solid. Which one you prefer depends on whether you're more comfortable thinking in SQL migrations or in Git-style branching.

Common Pitfalls to Watch For

Supabase: Forgetting to use the pooler. The direct Postgres connection string bypasses PgBouncer. In serverless environments, every function invocation that uses the direct string opens a new connection. You'll exhaust the connection limit under moderate load and see cryptic errors. Always use the SESSION or TRANSACTION pooler string.

Supabase: Row-level security off by default on new tables. When you create a new table via the dashboard, RLS is disabled. Any authenticated user can read and write every row. Enable RLS immediately and add policies before you connect any client-side code to the table.

PlanetScale: Full table scans on large tables. Because row reads drive your costs, an unindexed query on a big table is both slow and expensive. Run EXPLAIN on any query that touches tables over a few thousand rows. Add indexes before you go to production, not after.

PlanetScale: No ALTER TABLE in the same transaction as data changes. Vitess runs schema changes through its own online schema change tool. You cannot mix DDL and DML in the same transaction. If your ORM tries to do this (some do), you'll get an error. Separate schema migrations from data migrations.

Which One Should You Pick?

Pick Supabase if your project is a full-stack app that needs auth, file uploads, real-time features, or a complex relational data model. The bundled services save you from wiring together five separate tools. PostgreSQL's feature set is also unmatched for anything that involves geospatial data, full-text search, or JSON columns.

Pick PlanetScale if your project is data-intensive, scales horizontally, runs mostly in serverless or edge environments, and has a simpler schema without heavy relational constraints. The branching workflow is genuinely useful even on solo projects, and the MySQL ecosystem has broad ORM support.

If you're truly undecided, start with Supabase. The free tier is more stable for intermittent-use projects (once you solve the pausing problem), the tooling is excellent for solo developers, and you won't hit a wall when you need auth or storage.

Wrapping Up

The real cost of any database platform is what happens when you grow, not just what you pay on day one. Here are the concrete steps to take before you commit:

  1. Audit the current free tier limits on both platforms directly β€” pricing pages change, and this article will age. Confirm what the actual thresholds are on the day you sign up.
  2. If you choose Supabase, set up a lightweight ping job immediately to prevent your project from pausing, and enable RLS on every table before writing client-facing code.
  3. If you choose PlanetScale, run EXPLAIN on every query during development and treat the query insights dashboard as a first-class tool, not an afterthought.
  4. Model your expected usage before you hit production. Estimate your monthly active users, row reads, and storage needs, then cross-reference them against the plan limits. A quick spreadsheet saves a surprise invoice.
  5. Plan your migration path now. If you start on a free tier and need to upgrade, know exactly which plan you'd move to and what it costs. Surprises are cheaper when you've already thought them through.

πŸ“€ Share this article

Sign in to save

Comments (0)

No comments yet. Be the first!

Leave a Comment

Sign in to comment with your profile.

πŸ“¬ Weekly Newsletter

Stay ahead of the curve

Get the best programming tutorials, data analytics tips, and tool reviews delivered to your inbox every week.

No spam. Unsubscribe anytime.