One Postgres Box Under Every App I Run
Why I run one self-hosted Postgres box under an entire portfolio instead of a managed database per app, and how shared Postgres cuts cost and lock-in at once.
Every app I run connects to the same Postgres box. Not a managed database per product, not a cluster per team, one self-hosted Postgres instance with schemas carved out for each venture. It is the single highest-leverage infrastructure decision I have made, because the managed-database-per-app pattern is where cloud bills quietly go to die and where lock-in sinks its deepest hook. Here is why one box wins for a portfolio operator.
The claim is narrow and I will defend it: for a fleet of small-to-medium apps run by one operator, a single owned Postgres server beats a fleet of managed databases on cost, on control, and on how fast you can ship the next thing.
Why managed database per app is the expensive default
Managed Postgres feels responsible. Each app gets its own isolated database, its own backups, its own dashboard. Then you look at the bill.
Every managed database carries a floor: a minimum monthly cost whether the app has one user or a thousand. Twenty apps, twenty floors, and most of those apps are nearly idle most of the time. You are paying full price for capacity that sits unused because the billing unit is "a database," not "the queries you actually run." This is the exact mechanism behind a bill that climbs faster than your traffic, which I traced in why your cloud bill keeps climbing.
Then there is the operational sprawl: twenty dashboards, twenty upgrade schedules, twenty sets of credentials. Convenience per app becomes overhead per app once you have enough apps.
How one shared Postgres box actually works
The design is boring, which is the point. One well-sized VPS runs Postgres. Each application gets its own database or its own schema and its own role, so the apps are isolated from each other at the permission level even though they share the machine. A quiet app costs nothing extra; a busy one uses the headroom.
I run pgvector on the same instance, so any app that needs embeddings for search or retrieval gets them without a separate vector service on the bill. One connection string per app, pointed at one box. When I ship a new product, provisioning its database is a single command, not a new managed resource with its own billing relationship. That is the compounding I keep chasing, and it is the same argument I make in own your database instead of renting a managed one.
Is one box a single point of failure
This is the honest objection, so I will meet it head-on. Yes, one box is one box. If it goes down, everything on it is down. That risk is real and you manage it with the same discipline you would owe any critical system.
Backups leave the box on a schedule, encrypted, to storage on a different provider, and I test the restore monthly. I keep the box patched and I keep enough headroom that no single app can starve the others. For a portfolio of my size and traffic, that is the right trade: the operational simplicity and cost of one instance outweigh the marginal reliability of twenty isolated ones, especially since twenty managed databases are twenty things that can also break. When an app genuinely outgrows the shared box, it graduates to its own, and that is a good problem to have. The reliability question deserves a full answer, which I gave in is self-hosting reliable enough.
The lock-in you avoid by owning the database
The cost savings get the attention. The lock-in avoidance is what actually matters long term.
A managed database is not just storage; it is storage tangled into a vendor's backups, their networking, their proprietary extensions, their export limits. Leaving means a migration, which is why so many teams never leave even as the bill grows. Standard Postgres on a box I control has no such gravity. Moving it is a dump and a restore onto another box. Nothing about my data is trapped in a format only one company can read, which is the exit test I put every dependency through in what no vendor lock-in actually requires.
Build the platform once
The reason this works is that the database is not per-app infrastructure; it is portfolio infrastructure. I built it once and every venture inherits it. New app, new schema, done. That is the whole philosophy of owning your stack: pay the setup cost a single time and let every future product ride on it for free.
I packaged this shared-database pattern, along with the deploys and backups around it, into my hosting stack HostSSH, because the single Postgres box under a fleet of apps is not a hack. It is the correct architecture for anyone running more than a couple of products who does not want the database bill to grow faster than the business does.
One box. Many apps. Owned outright. For a portfolio operator, that is not a compromise. It is the plan.