Managed Databases vs Self-Hosted: Deciding as a Developer
The engine is the same either way, so the real choice is who owns backups, patching, failover and pooling. This article splits the work task by task, shows when self-hosting is the better engineering call, and lists the minimum bar for running a database yourself.

You Are Not Choosing a Database, You Are Choosing Who Gets Paged
PostgreSQL is PostgreSQL. The engine you get from a managed service and the engine you install with apt install postgresql are the same software, usually within a version or two of each other. So the comparison is never about capability.
What actually differs is the list of jobs that must happen around the engine, and who is responsible when one of them fails at an inconvenient hour. Backups that restore. A minor version patch for a disclosed vulnerability. A failover when the underlying host disappears. Connection limits when the application pool misbehaves.
A managed service sells you those jobs. Self-hosting keeps them, along with the money and the control. This article lays out the split honestly, including the cases where running it yourself is the better engineering decision rather than merely the cheaper one.
The Responsibility Split, Task by Task
Provider marketing tends to say "fully managed" and leave it there. The useful version is a list.
| Task | Managed service | Self-hosted on a VM |
|---|---|---|
| Install and initial configuration | Provider | You |
| Operating system patching | Provider | You |
| Engine minor version patching | Provider, in a maintenance window you choose | You |
| Major version upgrade | You trigger it, provider runs it | You, with pg_upgrade and a rehearsal |
| Automated backups | Provider, with point-in-time recovery | You, usually WAL archiving plus base backups |
| Verifying that backups restore | You | You |
| Replication and failover | Provider, if you pay for a standby | You, with tooling such as repmgr or Patroni |
| Performance tuning of queries | You | You |
| Server parameter tuning | Partly, through a parameter group | You, with full access to every setting |
| Connection pooling | Often included or offered alongside | You, typically PgBouncer |
| Monitoring and alerting | Provider dashboards, plus whatever you add | You |
Two rows deserve attention. Verifying restores is yours in both columns, and it is the single most commonly skipped task in the entire list. A managed service takes snapshots reliably; it does not confirm that your application starts against one.
The failover row is the honest cost driver. Managed high availability generally means a second instance you pay for. Comparing a single managed node against a single self-hosted node is fair; comparing a highly available managed cluster against one VM is not.
What You Actually Get From a Managed Service
The offerings are broadly similar across providers: Amazon RDS and Aurora, Azure Database for PostgreSQL and MySQL, Google Cloud SQL, DigitalOcean Managed Databases, Vultr Managed Databases and the Akamai and Linode equivalents. Feature depth differs, the shape does not.
Point-in-time recovery is the headline feature and the one hardest to replicate casually. Restoring to an arbitrary second before a bad migration, rather than to last night's dump, is worth a great deal the first time somebody runs an UPDATE without a WHERE clause. The point-in-time recovery article explains the mechanism.
Private networking is the second. Every serious managed service can be reached only from inside your private network or from an allowed list of addresses, so the database never has a public listener at all.
The trade is access. Managed instances do not give you a shell, and they restrict the superuser role, which means some extensions are unavailable, some parameters are fixed, and anything that expects to read the server filesystem will not work. Check the supported extension list before committing if your schema depends on something unusual. The RDS PostgreSQL documentation and the DigitalOcean managed PostgreSQL documentation both publish theirs.
When Running It Yourself Is the Right Call
Cost is the obvious reason and the least interesting one. These are the cases where self-hosting is defensible on technical grounds.
You need the machine, not just the engine
Custom extensions, a specific build, background jobs that read local files, or a replica feeding a search index can all require filesystem and superuser access that no managed service will grant.
The provider has no managed offering
Not every cloud sells one. Hetzner, for instance, offers servers and volumes but no managed relational database service, so a stack hosted there runs its own PostgreSQL by definition. A Hetzner account is a common choice precisely because the raw compute and memory are generous, which suits a database that would otherwise sit on an expensive managed tier.
Colocation with the application matters
A database on the same private network as the application, in the same zone, avoids a network hop and any cross-zone transfer accounting. For latency sensitive workloads this is measurable in a way that instance size is not.
You already have the discipline
If your team already runs configuration management, monitoring and restore drills for other services, adding a database is an increment rather than a new category of work. If none of those exist yet, a managed service buys you time to build them.
The Minimum Bar for Self-Hosting
If you take it on, take all of it on. A half-configured database is worse than a managed one because it looks fine until the day it does not.
- Bind to a private address only, and reach it over the provider private network rather than the public interface. Never leave port 5432 open to the internet.
- Configure continuous archiving so you can recover to a point in time, not only to the last dump. The PostgreSQL continuous archiving chapter is the reference.
- Ship backups off the machine. A snapshot on the same volume as the data protects against nothing that matters, as the backup strategies article argues.
- Restore into a scratch instance on a schedule and check that the application starts. Put a calendar entry on it.
- Put PgBouncer in front if the application opens connections per request, because the engine allocates a process per connection and will run out of memory before it runs out of clients.
- Monitor disk free space, replication lag, connection count and the age of the oldest transaction. Alert on the first two before they become incidents.
- Tune the obvious parameters for the machine size rather than accepting packaging defaults, which assume a very small host.
- Decide the upgrade path for the next major version before you need it. The PostgreSQL on a cloud server walkthrough covers installation and tuning in order.
A Short Decision Path
Start with the blast radius. If losing an hour of data would end the business, buy point-in-time recovery from someone whose full-time job is keeping it working, and spend your effort elsewhere.
If the workload is a side project, an internal tool or a staging environment, self-hosting is fine and educational. The failure mode is an evening of inconvenience rather than a customer incident.
In between, consider the hybrid that many teams land on: managed for the primary transactional store, self-hosted for caches, queues, analytics copies and anything you can rebuild from source data. That keeps the irreplaceable thing insured and the replaceable things cheap. Developer clouds make the second half easy, and a Linode account or similar provides both a managed option and plain instances in one place, a split the DigitalOcean and Linode comparison examines.
Whichever way you go, write down the recovery procedure and the expected recovery time. The decision is only as good as the document somebody follows at two in the morning.
Frequently Asked
Can I move from managed to self-hosted later, or the other way?
Yes, and logical replication makes it close to seamless for PostgreSQL and MySQL. Set the new server up as a subscriber, let it catch up, then switch the application connection string during a short pause. Test the cutover on a copy first, because permissions and extensions rarely transfer cleanly on the first attempt.
Does a managed database remove the need for my own backups?
It removes the need to take them, not the need to think about them. Retention windows are finite, and an account level problem affects the database and its snapshots together. Many teams keep a periodic logical dump in object storage at a different provider for exactly that reason.
Is a database in a container on my application server a reasonable middle ground?
For development and staging, yes. For production it combines the operational burden of self-hosting with the resource contention of sharing a host, and volume mistakes during container upgrades are a common way to lose data. If you self-host in production, give the database its own machine.
How much cheaper is self-hosting really?
Per unit of compute and storage, noticeably. Counted properly, the gap narrows once you include the standby instance, the backup storage, the monitoring stack and the engineering hours spent on upgrades and incidents. Compare total responsibility, not the line item.
Questions about a cloud account?
Ask about products, variants, availability or purchasing on either channel.


