DEV Community

Libme
Libme

Posted on

Scale-to-Zero vs Provisioned Managed Postgres: Which Pricing Model Fits Your Traffic?

TL;DR: Scale-to-zero Postgres (billed mostly on compute time actually used) wins when your database is idle most of the day, such as side projects, staging, and per-PR previews. A provisioned instance (billed per hour whether or not anyone queries it) wins once your database is busy for a large fraction of the month, because you stop paying a premium for elasticity you no longer use. The break-even is a ratio of active hours to total hours, and you can compute it in ten lines of code with your own provider's current rates.

I'm deliberately not publishing a price table. Rates change, and a stale number in a reference post does more harm than none. What lasts is the shape of each billing model, and that shape is what decides your bill. Everything provider-specific below is as of October 2026; check the pricing page before you commit.

What are the three billing models for managed Postgres?

Almost every managed Postgres offering falls into one of these:

  1. Provisioned instance. You pick an instance size and pay per hour while it exists, plus storage, backup storage, and sometimes provisioned IOPS. Amazon RDS for PostgreSQL is the canonical example. Running idle costs the same as running flat out.
  2. Plan-based project. You pay a flat monthly tier per project that bundles a compute size, storage and bandwidth, with overage charges beyond the bundle. Supabase works this way as of this writing. Free-tier projects have historically been paused after a period of inactivity, which is a limitation, not a feature.
  3. Usage-based, scale-to-zero. Compute is billed by the time (and size) it is actually running, and it suspends when idle. Neon is the best-known Postgres example, and Aurora Serverless v2 added the ability to scale down to zero capacity with auto-pause in late 2024.

The key takeaway: the pricing model decides your bill more than the headline "per GB" or "per vCPU" rate does.

Why does scale-to-zero stop being cheaper?

Two mechanics erode the advantage, and both bit me when I modeled a small production workload.

Rate premium. Per-hour compute on elastic offerings is usually priced higher than the equivalent always-on capacity, because the provider is carrying idle capacity for you. That premium is invisible while your database sleeps 20 hours a day. It dominates once it sleeps 2.

Cold starts keep it awake. A scale-to-zero database suspends after an idle timeout. If anything pings it more often than that timeout (a health check, a cron job, a monitoring probe, an ORM that opens a connection at boot), it never sleeps, and you are paying the elastic premium for 24 hours a day. If you adopt this model, the first thing to audit is who is touching the database on a schedule. I covered the health-check side of that in a separate post on deep health checks; the same probe that makes monitoring honest can quietly defeat auto-suspend.

The key takeaway: scale-to-zero only saves money if the database actually reaches zero, so find every periodic connection before you assume it will.

How do I compute the break-even for my workload?

Plug in your provider's current numbers. The script below compares a provisioned instance against an elastic one at a given active-time fraction, and finds the fraction where they cross.

def monthly_cost(active_fraction, elastic_rate, provisioned_rate,
                 storage_gb=20, storage_rate=0.0, hours=730):
    """Rates are dollars per compute-hour. Replace with current provider numbers."""
    elastic = elastic_rate * hours * active_fraction + storage_gb * storage_rate
    provisioned = provisioned_rate * hours + storage_gb * storage_rate
    return elastic, provisioned


def break_even(elastic_rate, provisioned_rate):
    # Elastic is cheaper while active_fraction < provisioned_rate / elastic_rate
    return provisioned_rate / elastic_rate


if __name__ == "__main__":
    # Placeholder rates for illustration only: NOT real provider prices.
    ELASTIC, PROVISIONED = 0.16, 0.10
    print(f"break-even active fraction: {break_even(ELASTIC, PROVISIONED):.0%}")
    for frac in (0.05, 0.25, 0.50, 0.75, 1.00):
        e, p = monthly_cost(frac, ELASTIC, PROVISIONED)
        print(f"active {frac:>4.0%}  elastic ${e:7.2f}  provisioned ${p:7.2f}")
Enter fullscreen mode Exit fullscreen mode

With the made-up rates above, the elastic option is cheaper until the database is active about 62% of the month. The numbers are fake on purpose; the structure is the point. If your elastic rate is 1.6 times your provisioned rate, you need to be idle more than roughly 38% of the time to come out ahead. Real offerings also add minimum compute floors, storage that is billed even when compute is asleep, and per-project fees, so extend the function before trusting it.

The key takeaway: the break-even active fraction equals the provisioned hourly rate divided by the elastic hourly rate, and nothing else about the sticker price matters until you know it.

Which model fits which workload?

Workload Best-fit model Why Main drawback
Side project, a few visits a day Scale-to-zero Sleeps most of the month Cold-start latency on the first request
Staging and per-PR preview databases Scale-to-zero Dozens of mostly idle copies Branching and cleanup need discipline
Early-stage app with steady daily use Plan-based project Predictable monthly line item Overage charges and plan jumps are lumpy
Production with constant traffic, 24/7 Provisioned instance No elasticity premium, tunable parameters You pay for idle headroom and manage sizing
Spiky B2B app, busy in work hours only Scale-to-zero or plan-based Nights and weekends are free Autoscaling can lag behind a sudden burst

Preview environments are where scale-to-zero is hardest to beat. If you are creating a database per pull request, a provisioned instance per PR is absurd, and a branchable, suspend-on-idle database is the natural fit. I wrote about seeding those environments without cloning production data in an earlier post.

The key takeaway: match the billing model to the duty cycle of the workload, not to the size of the data.

What are the hidden costs that aren't compute?

Compute is rarely the surprise. These are:

  • Storage billed while compute sleeps. Suspended does not mean free.
  • Backups and point-in-time recovery. Retention windows are priced separately on most providers; longer windows cost more.
  • Multi-AZ or high availability. On RDS, a standby replica roughly doubles the compute line. Whether you need it is a real decision, not a default.
  • Connection limits and pooling. Small compute sizes have low connection caps, which pushes you toward a pooler. Serverless functions make this worse, as covered in the post on transaction-mode pooling.
  • Egress. Data leaving the provider's network is billed on most clouds, and cross-region traffic more so.

None of these appear in the "from $X per month" headline.

The key takeaway: price the full bundle (compute, storage, backups, HA, egress) at your expected duty cycle, because the headline number covers only the first item.

FAQ

Is scale-to-zero Postgres production-ready?
Yes for workloads that tolerate a cold start of up to a second or so on the first request after idle time, and no for latency-sensitive paths that can't. Measure your own cold-start time on your provider and region; don't trust a blog post, including this one.

Why is my scale-to-zero database never suspending?
Something is connecting more often than the idle timeout, usually a health check, cron job, monitoring probe, or connection pool with keepalive. Check the connection logs for recurring clients and lengthen or remove the periodic connection.

Is RDS cheaper than Neon or Supabase?
It depends on the duty cycle. RDS is typically cheaper per active hour for a database that is busy around the clock, while scale-to-zero and plan-based options win when the database is idle for much of the month.

Bottom line

If your database is idle most of the day, start with a scale-to-zero option such as Neon, and audit every scheduled connection so it can actually suspend. If you want a flat monthly bill bundled with auth and storage for an early product, Supabase is the plan-based choice, with the caveat that plan jumps and overages are lumpy. If your database is busy most of the month and you need tuned parameters or high availability, a provisioned Amazon RDS for PostgreSQL instance is usually the cheaper and more controllable home. Whichever you pick, run the break-even script with this month's real rates and re-run it when your traffic shape changes.

Related reading

Top comments (0)