DatabasesJuly 27, 202611 min read

Self-Hosted vs Managed PostgreSQL: The Real Cost of Ownership

The €5 VPS looks cheaper than the €14 managed plan — until you price the hours. A line-by-line cost of ownership for self-hosting Postgres versus managed, the risk nobody puts on the invoice, and when self-hosting actually wins.

RThe Runsite Team

Open your provider's pricing page and the comparison looks settled before you've finished reading it. A small VPS you could run Postgres on yourself is five euros a month. A managed PostgreSQL plan with similar specs is fourteen. Nearly three times the price for a database you already know how to install. `apt install postgresql` is free, after all, and you've done it a dozen times.

That top-line number is real, and it's also the wrong number to decide on. The monthly bill for a database was never the expensive part of running one. The expensive part doesn't show up on any invoice: it's the hours you spend keeping it alive, and the cost of the one night it isn't. This is an attempt to put those two hidden numbers on the table next to the visible one, so the comparison is honest. If you want the concept of what "managed" even covers, managed PostgreSQL for developers walks that boundary; this piece is about what each side of it costs.

The two bills: sticker price and everything else

Every piece of infrastructure has two prices. The first is the sticker price: the line item on your monthly bill, the compute and storage you pay for whether or not anything goes wrong. It's easy to compare because it's a single number, which is exactly why it dominates the decision and exactly why it misleads.

The second price is the total cost of ownership, and it's the one that actually empties the account. For a database, TCO is the sticker price plus two things that never appear on the invoice: the engineering time it takes to operate, and the expected cost of the failures you're now responsible for. Self-hosting trades a lower first number for a higher, lumpier second one. Managed does the reverse. The whole decision is which trade fits you, and you can't see it until both numbers are written down.

The self-hosted ledger, line by line

So write the second number down. Here's the operational work a database needs over a year when you own the whole server, with a rough sense of how often each job lands and how long it takes. The hours are illustrative, not a quote (your numbers depend on your experience and how much goes wrong), but the shape holds across most teams.

Setup and hardening (once, then again per environment)

A fresh Postgres install ships with defaults tuned for a laptop, listening with settings you wouldn't run in production. Getting it ready means sizing memory parameters to the box, turning on TLS, creating roles that aren't the superuser, and locking down `pg_hba.conf` so the open internet can't reach it. Done carefully, that's the better part of a day the first time, and a chunk of one again for staging, for the replica, and for the rebuild after you outgrow the first box.

Patching and minor upgrades (a few times a year)

PostgreSQL ships minor releases regularly, and some of them close real security holes. Applying one is rarely dramatic, but it's a maintenance window you plan, a change you test, and a release you have to actually notice came out. Skip the noticing and you're quietly running a version with a known vulnerability in it.

The annual major-version upgrade (once a year, and it's the big one)

Postgres puts out a new major version every year, and old ones fall out of support on a schedule. Upgrading across a major version by hand is the fiddly one: often a dump-and-restore or a logical-replication dance, with downtime to plan and a rollback to rehearse. It's the maintenance most likely to slip quarter after quarter until you're stranded two versions back with no more security fixes coming. When you finally do it, it eats a day or more of focused, nervous work.

Backups you've actually restored (setup, then ongoing proof)

Configuring a nightly `pg_dump` is an hour. A backup you can trust is a different thing. You want copies stored somewhere other than the disk that might die, and continuous WAL archiving so you can rewind to a moment rather than to last midnight. Then the part everyone skips: a restore you've actually run, because a backup you've never restored is a hope, not a backup. That's the setup cost of doing point-in-time recovery yourself, plus the recurring cost of proving it still works. If you want a portable copy on top, automating backups to S3 is its own small pipeline to build and watch.

Monitoring and alerting (build once, tend forever)

You can't fix what you can't see, so production needs eyes on connection counts, slow queries, memory pressure, disk headroom, and replication lag. Self-hosted, that's an exporter, a dashboard, and alert rules you assemble and then keep working as things change. Without it, the first sign of trouble is the outage itself.

Pooling, replication, and the rest (as you grow)

Traffic grows and the single box stops being enough. Now you're standing up a connection pooler so the app stops hitting the connection ceiling, and maybe a read replica with the replication lag to watch that comes with it. Each is another moving part you deploy, tune, and keep alive. The failure mode when you don't is a concrete one: `too many clients already` in the logs while the site throws 500s.

The jobHow oftenRough hours / yearThe details
Setup & hardeningOnce per environment6–10Tuning, TLS, roles, pg_hba
Minor patchesA few times a year3–6Test, schedule, apply
Major upgradeYearly6–12Dump/restore or logical replication
Backups + tested restoreSetup + ongoing6–10WAL, PITR, restore drills
Monitoring & alertsBuild + maintain4–8Exporter, dashboard, rules
Pooling / replicationAs you scale4–10PgBouncer, read replicas
Illustrative, not a quote — but the total lands somewhere in the tens of hours a year for most single-database teams, before anything actually breaks.

The cost nobody puts on the invoice

Add those up and you've still only counted the good years. The line that's hardest to see, and the one that most often decides the whole thing, is risk: the cost of the failures that self-hosting moves onto you. It doesn't arrive every month. It arrives once, at the worst possible time, and it can be larger than years of the sticker-price difference put together.

The honest way to price a risk is expected cost: how bad it would be, times how likely it is. Run down the list and the numbers get uncomfortable.

  • The backup you never tested. Configured, running, green in the dashboard, and no good, because the one time you reach for it you find the restore doesn't work. Impact: potentially the whole database. Probability: far higher than anyone admits, because untested restores fail all the time.
  • The patch you didn't apply. A known vulnerability in a version you meant to upgrade off months ago. Impact: a breach and everything that follows it. Probability: climbs the longer the upgrade slips.
  • The disk that filled up. Postgres doesn't degrade gracefully when its volume is full; it stops accepting writes. Impact: a hard outage in the middle of the day. Probability: near certain, eventually, without headroom or autoscaling watching it.
  • The 2am page. Connections exhausted, replication broken, a query storm — whatever it is, it's yours to fix now, not in the morning. Impact: the incident, plus the lost sleep, plus the next day gone. Probability: recurring.

Why the risk line dominates

A few euros a month of sticker-price savings is a rounding error next to one bad restore. If self-hosting saves you €100 a year and raises your chance of an unrecoverable data-loss event by even a couple of percent, the expected cost of that single risk can swallow the saving many times over. The saving is certain and small; the risk is uncertain and large. That asymmetry is the whole argument.

Putting a number on your own time

The way to make this concrete is to price your own hours, because that's the currency self-hosting actually spends. Take what an hour of your time is worth — not just salary, but the loaded cost, and more honestly still, what that hour would earn spent on the product instead. Multiply by the hours a year the ledger above will cost you. Add a rough expected cost for the risk. That total is the real price of the cheap VPS.

text
Yearly cost of self-hosting =
    sticker price (VPS)
  + (hours per year  x  your loaded hourly cost)
  + (risk impact  x  probability)

Yearly cost of managed =
    sticker price (plan)

Put real numbers in and the result is usually lopsided. Say the ledger runs 30 hours a year and your time is worth €60 an hour, loaded. That's €1,800 of engineering attention spent on plumbing, before a single incident, to save the €100-ish a year the VPS is cheaper on sticker. The database was never the thing you were being paid to build, and those 30 hours came out of the thing you were.

A three-year comparison

Stretch it over the life of an actual project and the gap widens, because the sticker-price saving is linear while the time and risk keep compounding. Here's the same small database run both ways for three years, with the managed side priced at a real plan (Runsite's Standard at €14 a month as of writing, which includes pooling, point-in-time recovery, and backups you don't operate) and the self-hosted side on a typical small VPS around €8 a month. The figures are illustrative; plug in your own.

Cost lineSelf-host on a VPSManaged (Standard plan)
Sticker, 3 years~€290 (≈€8/mo)~€500 (€14/mo)
Setup & hardening6–10 hrsMinutes
Patching & upgrades~9–18 hrs / yearIncluded
Backups + tested restore~6–10 hrs / yearIncluded, 1-click restore
Monitoring & pooling~8–18 hrs / yearIncluded
Your time over 3 years~75–150 hrs~0
That time at €60/hr~€4,500–9,000€0
Risk exposureYoursThe provider's
The ~€210 the VPS saves on sticker over three years is bought with 75–150 hours of your time and the full weight of every failure. The visible line is the small one.

The point isn't the exact figures, which will move with your rates and your luck. It's the direction: the number that decides the comparison is the one that isn't printed on either pricing page.

When self-hosting actually wins

None of this makes managed the right call every time, and a comparison that only ran one way wouldn't be worth trusting. Self-hosting genuinely wins in a few specific situations, and if you're in one of them you probably already know it.

  • You need something no provider offers. A particular extension, a kernel-level tweak, a custom build, or a version outside the supported range. If your workload depends on it, managed's tidy boundary becomes a wall, and owning the box is the only way through.
  • You already employ people who run databases. At a certain scale you have a platform or SRE team keeping databases alive as their actual job. The operational hours are already staffed, so the ledger above is mostly sunk cost, and raw compute at volume can beat per-instance managed pricing.
  • You have a hard cost floor only raw compute can meet. Some businesses genuinely need the cheapest possible per-unit infrastructure and have the in-house skill to run it safely. If the margin math forces it and the expertise is real, self-hosting is a defensible answer.

The break-even is really about which resource is scarcest. If engineering attention is your bottleneck (the usual case for a small team shipping a product), managed wins, because it converts a lumpy, attention-heavy cost into a flat line item. If cheap compute at scale is the bottleneck and operational skill is abundant, self-hosting wins. Most small teams sit firmly in the first camp, and if you're unsure which one you're in, you're almost certainly in it. The same ledger applies to the layer that deploys your code rather than the one that stores your data, and it comes out differently there, which is the subject of self-hosted PaaS versus managed.

How Runsite handles it

For a concrete version of the managed side of that trade, managed PostgreSQL on Runsite prices the operations in rather than leaving them on your ledger. Every line the self-hosted column charges you hours for is already handled: a PostgreSQL 16 database provisioned and tuned in seconds, daily backups with point-in-time recovery from continuous WAL archiving, PgBouncer pooling built in on port 6432, one-click vertical scaling with storage autoscaling so the disk grows before it fills, and a monitoring dashboard for connections, queries, memory, and replication lag out of the box.

The plans map to that ledger directly. The free tier is a 1 GB database with daily backups you can start on without a card and runs for 30 days, Standard at €14 a month adds point-in-time recovery and pooling, and read replicas arrive on the larger plans when read traffic makes them worth it. Because the platform is EU-native, the database, its WAL archive, and every backup stay in a Frankfurt, Germany region with a signed GDPR DPA on every plan, so the operational work moves off your plate without your data moving anywhere it shouldn't. What you're paying for isn't the compute, since a VPS sells that cheaper. It's the tens of hours a year and the risk exposure that never make it onto the invoice.

The short version

The sticker price is the easy number to compare and the wrong one to decide on. Self-hosting Postgres wins on the monthly bill and loses on total cost of ownership, because it moves two invisible costs onto you: the tens of hours a year it takes to operate a database well, and the expected cost of the failures you're now on the hook for. Price your own time, price the risk honestly, and for most small teams the managed plan comes in cheaper than the cheap VPS. Self-hosting still wins when you need something no provider offers, already staff people to run databases, or have a hard compute floor — real cases, just not the common one. Spin up a managed database on the free tier and the operations are priced in before you write a line of SQL.

FAQ

Frequently Asked Questions

Common questions about this service.

On the monthly bill, self-hosting is usually cheaper — a small VPS you run Postgres on yourself can be a few times cheaper than a comparable managed plan. On total cost of ownership, managed usually wins. Self-hosting adds two costs that never appear on the invoice: the engineering hours to set up, patch, upgrade, back up, monitor, and pool the database (tens of hours a year for most teams), and the expected cost of the failures you're now responsible for, like an untested backup or a missed security patch. Price those in and the cheaper sticker price is often the more expensive option.

Total cost of ownership (TCO) is the full cost of running a database over its life, not just the monthly bill. It's the sticker price for compute and storage, plus the engineering time to operate it — provisioning, patching, major-version upgrades, backups with tested restores, monitoring, and connection pooling — plus the risk-adjusted cost of the failures the operator is responsible for. Managed hosting raises the sticker price and shrinks the other two; self-hosting does the reverse.

For a single production database, plan on tens of hours a year once you count everything: initial setup and hardening, a few minor patches, the annual major-version upgrade, backups with restores you actually test, monitoring and alerting, and a pooler once traffic grows. The exact figure depends on your experience and how much goes wrong, but it's rarely the near-zero people assume when they compare it to a managed plan on price alone. That time comes out of building your product.

Self-hosting makes sense in three main cases: you need an extension, kernel tweak, or version no managed provider offers; you already employ a platform or SRE team that runs databases as their job, so the operational hours are already staffed; or you have a hard cost floor that only raw compute at scale can meet, along with the in-house skill to run it safely. Outside those, where engineering attention is the scarce resource — the usual situation for a small team shipping a product — managed almost always wins on total cost.

Your app deserves to be online

Free to start. Deploy in under a minute. No credit card needed.