Categories
DevOps

Self-Hosted vs Managed: When to Run Your Own Server

There’s a recurring debate in every developer Slack I’ve been part of: should we run our own servers or pay someone else to manage them? The question used to feel ideological – self-hosting was the principled choice, managed was for people who didn’t want to learn operations. These days I think about it differently. It’s a pure cost-of-attention calculation, and the answer changes based on your team size, traffic shape, and what you’re actually building.

I’ve run both. For a few years I managed bare-metal servers at a small company – enjoyed it, learned a lot, and would not recommend it for a product team that has any other choice. I’ve also watched teams burn weeks on infra problems that a managed service would have handled invisibly. Here’s how I think through the decision now.

What “managed” actually means

Managed services come in several tiers. At the PaaS end (Heroku, Render, Railway, Fly.io), you hand over a Dockerfile or a Git repo and the platform handles OS patching, node provisioning, rolling deploys, and basic scaling. You pay a premium per compute unit but get back dozens of hours you’d otherwise spend on configuration.

Managed databases (RDS, Neon, PlanetScale, Supabase) go further – they handle backups, replication, minor version upgrades, and connection pooling. Running Postgres in a container yourself is not hard, but running it in production with proper backup verification, failover, and monitoring is a different project.

At the IaaS end (EC2, Hetzner Cloud, DigitalOcean Droplets) you get raw VMs and own everything above the hypervisor. This isn’t “self-hosted” in the traditional sense – you’re still renting compute – but the operational burden is much closer to owning hardware than it is to using a PaaS.

The real cost of running your own infrastructure

People usually compare managed vs. self-hosted on the monthly invoice. That comparison misses most of the cost. Consider what running your own infrastructure actually requires:

OS and package updates need to happen on a schedule. Unpatched servers are a liability. If you’re running three VMs, that’s manageable with a cron job and some Ansible. If you’re running thirty, it’s someone’s job.

Backups need to exist and need to be tested. “We have backups” and “we have tested restores” are different statements. A managed database that runs daily snapshots and lets you restore to a point in time with two clicks is not a luxury – it’s risk management.

Incident response is yours when you own the infrastructure. At 2am, the on-call person debugging a disk-full PostgreSQL crash would rather be debugging your application than the infrastructure underneath it.

# example: simple ansible playbook to keep a fleet of Ubuntu servers updated
- name: Apply security patches
  hosts: all
  become: true
  tasks:
    - name: Run apt upgrade
      apt:
        upgrade: safe
        update_cache: true
        cache_valid_time: 3600

    - name: Remove unused packages
      apt:
        autoremove: true
        purge: true

This kind of automation is table stakes if you’re managing your own nodes. It’s not complicated, but it takes time to build and test.

When self-hosting wins

Cost at scale is the most common legitimate reason. If you’re running hundreds of compute-hours per day, the managed premium adds up to real money. At that point you also have an ops team, and the labor cost of running your own infrastructure is amortized over enough value that it makes sense.

Data residency and compliance requirements sometimes force the issue. Some contracts require data to stay in a specific jurisdiction, in an environment you control and can audit. A shared PaaS with multi-tenant underlying infrastructure may not satisfy those requirements.

Specific hardware needs push you off managed options. GPU workloads, high-memory single-node jobs, bare-metal for latency-sensitive networking – managed options exist but are limited, expensive, or both.

Some open-source software runs better self-hosted than it does on a managed equivalent. I’ve seen this with Elasticsearch clusters in particular – the managed versions add overhead and limit configuration in ways that matter at high query volumes.

When managed wins

Almost every other case. If you’re a team of one to five engineers building a product, your time is the scarcest resource. Every hour spent on infrastructure is an hour not spent on features or customers.

Early-stage products especially benefit from managed services because the traffic shape is unpredictable. A PaaS that scales to zero when there’s no traffic and up when there is costs nothing at low usage and doesn’t require you to provision capacity in advance.

Managed databases have become particularly good. Neon’s branching model (a separate DB branch per pull request, created automatically) is something you’d spend weeks building yourself. PlanetScale’s schema migration tooling eliminates the “migrate a production database with zero downtime” class of problem. These aren’t just convenience features – they change how you work.

A practical decision framework

I use a rough checklist:

– Is the monthly managed cost less than four hours of engineering time? Use managed, no discussion.
– Does a specific compliance requirement force self-hosting? Document it, then self-host intentionally with proper automation.
– Are you running more than 20 nodes? You should have infrastructure tooling (Terraform, Ansible, or a platform team) regardless of whether they’re managed or not.
– Is the thing you want to self-host something you could recover from a complete failure in under an hour? If not, reconsider.

The Hetzner Cloud documentation has useful pricing comparisons if you’re evaluating the cost side of this: hetzner.com/cloud. For managed Postgres specifically, Neon’s docs explain their branching model well: neon.tech/docs/introduction.

The answer to “should I self-host?” almost always comes down to: how much infrastructure headcount do you have, and what are you actually optimizing for? Most teams should default managed and revisit the question when the costs become genuinely significant.