Managed vs self-hosted: what managed actually removes

What it is

The decision to run a piece of infrastructure yourself or to buy it as a service, and the useful framing is not "build versus buy" but which specific operational obligations transfer and which only move.

WHAT MANAGED GENUINELY REMOVES
  patching the OS and the software
  provisioning and replacing failed hardware
  the backup mechanism (though not the restore test)
  version upgrade mechanics
  being paged at 3am for a node failure
  the expertise needed to run it competently

WHAT MANAGED ONLY MOVES
  capacity planning              -> now it is instance-class
                                    selection and it still
                                    needs doing
  cost management                -> now it is a bill instead
                                    of a fleet, and it grows
                                    faster
  performance tuning             -> fewer knobs, and the
                                    ones left still matter
  the upgrade DECISION           -> they force it eventually,
                                    on their schedule
  debugging                      -> harder, because you
                                    cannot see inside

WHAT MANAGED ADDS
  a hard dependency on a vendor's availability
  a pricing model you do not control
  a feature lag behind the open-source version
  limits you cannot raise
  an exit cost proportional to how well it worked

Commonly confused with a cost comparison. The instance bill is almost always higher for managed and it is almost never the deciding number, because the comparison that matters includes the engineer-time and the on-call load, which are larger and harder to see.

Also commonly confused with "managed is less work". It is less of one kind of work and more of another: you stop patching and start negotiating limits, working around a missing feature, and explaining to an incident review why you cannot see inside the thing that failed.

The problem it solves

The decision is usually made on the sticker price, which is the least informative number available.

"Managed Kafka is $4,200 a month. Three brokers on EC2 is
 $1,400. Self-hosting saves us $2,800 a month."

WHAT IS MISSING
  Setup, tuning and hardening:        ~3 engineer-weeks
  Ongoing operations:                 ~15% of one engineer
  On-call: Kafka pages are rare and
    they are also 2am and they need
    someone who understands ISR and
    unclean leader election
  Upgrade cycles:                     ~1 engineer-week per
                                       major version
  The bus factor: one person knows it

  At a loaded cost of roughly $200k a year, 15% of an
  engineer is $30k, which is $2,500 a month, and that is
  before the setup, the upgrades and the on-call.

  *** The $2,800 monthly "saving" is roughly zero, and it
      is negative once you price the risk of the one person
      who knows it leaving. ***

And the direction reverses at scale. At forty brokers the managed premium is a large absolute number and a dedicated platform team is genuinely cheaper, which is why the answer changes with size rather than being a matter of philosophy.

Mechanics

The questions that decide it

1. IS IT DIFFERENTIATING?
   Does running this well make our product better in a way
   customers notice? For almost all infrastructure the
   answer is no, and that is the strongest argument for
   managed.

2. WHAT IS THE TEAM'S EXISTING COMPETENCE?
   Running one more thing you already understand is cheap.
   Running the first of a new kind is expensive, and the
   expense is mostly invisible until an incident.

3. WHAT IS THE SCALE?
   Managed premiums are roughly proportional. At small
   scale the premium is less than an engineer; at large
   scale it is several.

4. WHAT ARE THE LIMITS?
   Every managed service has them, and they are the thing
   that bites. Read them BEFORE adopting, not when you hit
   one.

5. WHAT IS THE EXIT COST?
   Proportional to data volume and to how deeply the
   service's specifics are embedded in your code.

6. WHO GETS PAGED, AND CAN THEY FIX IT?
   With managed, your on-call gets paged and can only
   escalate. That is sometimes better and it is a different
   incident experience, and it must be acceptable.

Question 1 is the framing that resolves most cases. Running Postgres well does not make your product better; running your ranking model well does. Spend the operational capacity where it differentiates, which is the actual argument rather than a cost one.

The limits, which are the part people skip

Every managed service has limits that are invisible until you hit them, and hitting one late is expensive.

EXAMPLES OF THE SHAPE
  connection limits scaled to instance size, which is why
    a serverless workload needs a connection proxy
  maximum storage per instance, which caps growth
  IOPS tied to volume size rather than purchasable
    separately
  a maximum message or item size
  partition or shard count limits
  a maximum number of replicas or read endpoints
  no access to extensions, plugins or custom builds
  no superuser, so some operations are impossible
  maintenance windows you cannot fully control
  a version support window that forces upgrades

THE DISCIPLINE
  Before adopting, read the service limits page and check
  each one against your projected numbers at 3x current
  scale. It takes an hour. Hitting one at scale is a
  migration.

The specific trap: "no superuser" and "no custom extensions" are the ones that surprise Postgres teams, because they are not limits on capacity, they are limits on what is possible at all, and they are found when someone needs an extension eighteen months in.

The exit cost, which grows with success

EXIT COST = data volume x egress cost
          + engineering time to migrate
          + the coupling you accumulated

THE COUPLING IS THE LARGE TERM
  Using DynamoDB as a key-value store: portable.
  Using DynamoDB with single-table design, GSIs, streams
    and transactions: the data model IS DynamoDB, and
    moving means redesigning.

  Using managed Postgres: highly portable, because it is
    Postgres.
  Using a proprietary managed database's specific query
    language and features: not portable at all.

The rule that follows: prefer managed services that run an open-source thing you could run yourself. Managed Postgres, managed Kafka, managed Kubernetes and managed Redis all have an exit, because the exit is "run it yourself or move to another provider's managed version of the same thing". A proprietary service with no open equivalent has no exit that is not a rewrite.

And the counter-position worth acknowledging: sometimes the proprietary service is dramatically better and the lock-in is worth it. DynamoDB, Spanner and BigQuery have no open equivalent that does what they do, and refusing them on portability grounds means giving up real capability for an exit you will probably never take. The honest version is to be deliberate: name the lock-in, estimate the exit cost, and decide, rather than either ignoring it or treating it as disqualifying.

The debugging asymmetry

SELF-HOSTED, something is slow
  ssh in, run perf, read the logs, check the config,
  attach a profiler, read the source.

MANAGED, something is slow
  read the metrics they expose
  open a support ticket
  wait

  You cannot see inside. For a subtle performance problem
  that is a genuine handicap, and it is worst exactly when
  it matters most.

This is the strongest technical argument for self-hosting, and it is worth weighing honestly rather than dismissing. The counter: most teams do not actually do the deep debugging they imagine they would. The ability to ssh in is worth a lot to a team with a specialist and almost nothing to a team that would have opened a support ticket with the vendor of the open-source distribution anyway.

The cost curve

Managed premium is roughly 1.5x to 3x the raw compute,
depending on service and provider.

SMALL SCALE (one to three nodes)
  premium ≈ $2k-6k/year
  one engineer at 15% ≈ $30k/year
  -> MANAGED WINS DECISIVELY

MID SCALE (ten to twenty nodes)
  premium ≈ $30k-100k/year
  a part-time platform engineer ≈ $60k-100k/year
  -> ROUGHLY EVEN, and the tiebreakers are competence,
     differentiation and risk

LARGE SCALE (fifty-plus nodes)
  premium ≈ $300k+/year
  a two-person platform team ≈ $400k/year and they can
  operate several systems
  -> SELF-HOSTED CAN WIN, and only if the team genuinely
     exists and stays

The crossover is not a single number, and the mistake in both directions is treating it as one. Small teams self-host to save money that does not exist; large organisations stay on managed long past the point where a platform team is cheaper, because the migration is never the quarter's priority.

A worked example: three decisions, three answers

A 40-ENGINEER COMPANY, reviewing its infrastructure.

POSTGRES (primary datastore, 340 GB)
  Differentiating?  No.
  Competence?       Two engineers know Postgres well.
  Scale?            One primary, two replicas.
  Limits?           Checked: connection limit at their
                    instance class is 5,000, they use ~200.
                    Extensions they need are supported.
  Exit?             Low. It is Postgres.
  -> MANAGED. The premium is about $9k/year and the two
     engineers' Postgres time is worth far more spent on
     schema and query design than on patching.

KAFKA (12 brokers, 200 MB/s)
  Differentiating?  No, and this is the one people argue
                    about.
  Competence?       One engineer knows it deeply. Bus
                    factor of one.
  Scale?            Mid. Managed premium ~$70k/year.
  Limits?           Partition count limits would bind
                    within two years at current growth.
  -> SELF-HOSTED, CONDITIONALLY. The premium is real at
     this scale AND the partition limit would force a
     migration anyway. But the bus factor of one is the
     actual risk, so the decision came with a commitment
     to train a second engineer within a quarter, and the
     decision would have been managed without it.

THE VECTOR DATABASE (new, 50M vectors)
  Differentiating?  The retrieval quality is. The
                    OPERATION of the index is not.
  Competence?       Nobody has run one in production.
  Scale?            Single-digit nodes.
  Limits?           Unknown, because nobody has hit them.
  -> MANAGED, DEFINITELY. This is the first of a new kind,
     the team has no expertise, and the operational
     learning would come out of the time available for the
     retrieval quality work that actually differentiates.

THE PATTERN
  Three answers, and the deciding factor was different each
  time: existing competence for Postgres, scale plus an
  approaching limit for Kafka, and "first of a new kind"
  for the vector store.

And the finding worth naming: the Kafka decision was conditional on a hiring or training commitment, which is the honest way to make it. A self-hosting decision that depends on one person and does not address that is a decision to accept an unmanaged risk.

Production evidence

Cloud provider pricing pages and the corresponding self-managed instance costs are the basis for the 1.5x to 3x premium range, and the ratio varies enough by service that it should be computed rather than assumed.

AWS's, GCP's and Azure's published service limits pages exist because limits are the most common source of adoption surprise, and reading them before adoption is the cheapest risk reduction available in this decision.

Dropbox's migration off S3 to Magic Pocket is the canonical large-scale reversal: at exabyte scale the managed premium justified building custom storage, and their published account is explicit that it made no sense at smaller scale.

37signals' published move off cloud and the counter-arguments to it are useful precisely because both sides publish numbers, and the disagreement is mostly about how to price engineer time and risk rather than about the compute bill.

The RDS Proxy and equivalent connection-pooling services exist because connection limits scaled to instance size is a real constraint that surprises teams, which is a concrete instance of the limits problem.

Kubernetes' managed offerings (EKS, GKE, AKS) are near-universal even at companies with strong platform teams, which is evidence that the "differentiating?" question resolves this for most infrastructure regardless of scale.

The debate

The case for managed by default: infrastructure operation is almost never differentiating, the engineer time is worth more than the premium at most scales, and the on-call reduction is real. The premium buys back the scarcest resource you have.

The case for self-hosting: at scale the premium is several engineers' worth, you keep the ability to debug and tune, you avoid limits you cannot raise, and you avoid a dependency on a vendor's availability and pricing decisions.

The case for a platform team: at sufficient size a small team operating several systems is cheaper than the premiums on all of them combined, and it builds capability that compounds.

My position: managed by default, self-host when scale makes the premium exceed a dedicated person, and always check the limits before adopting.

The framing that resolves most cases is question one: does running this well make the product better in a way customers notice? For Postgres, Kafka, Kubernetes and Redis the answer is no, and that is a stronger argument than any cost comparison, because it says where the operational capacity should go rather than what it costs.

The number that decides it is not the sticker price. A "$2,800 a month saving" from self-hosting Kafka is roughly zero once you price 15 percent of an engineer, and it is negative once you price the bus factor. The comparison has to include setup, ongoing operations, upgrade cycles and on-call, and those are larger and harder to see than the instance bill.

The discipline I would insist on regardless of the answer is reading the service limits page before adopting and checking each one against three times current scale. It takes an hour, and hitting a limit at scale is a migration. In the worked example the partition-count limit was part of what decided Kafka, and it was found by looking rather than by hitting it.

On lock-in, the rule I would apply is prefer managed services that run an open thing you could run yourself, because the exit is then "run it yourself or move providers" rather than a rewrite. And the honest caveat: sometimes the proprietary service is dramatically better and no open equivalent exists, and refusing it on portability grounds gives up real capability for an exit you will probably never take. Name the lock-in, estimate the exit, and decide deliberately rather than treating portability as automatically decisive.

Where I would push back on a self-hosting proposal: if it depends on one person, the decision has an unmanaged risk in it. In the Kafka case the answer was self-host conditional on training a second engineer within a quarter, and without that commitment the answer would have flipped. That conditionality is the honest way to make the decision rather than a hedge.

Follow-up Q&A

"How do you decide managed versus self-hosted?" Six questions, and the first resolves most cases: does running this well make the product better in a way customers notice? For Postgres, Kafka or Kubernetes the answer is no, so the operational capacity should go where it does differentiate. Then existing competence, scale, the service limits, the exit cost, and who gets paged and whether they can actually fix it.

"What's wrong with the cost comparison people usually make?" It uses the sticker price, which is the least informative number. Managed Kafka at $4,200 a month against three EC2 brokers at $1,400 looks like a $2,800 saving, and it omits three engineer-weeks of setup, about fifteen percent of an engineer ongoing, a week per major upgrade, and 2am pages that need someone who understands ISR and unclean leader election. Fifteen percent of an engineer is roughly $2,500 a month, so the saving is about zero before you price the bus factor.

"So when does self-hosting win?" At scale, where the premium becomes several engineers' worth. Roughly: at one to three nodes the premium is a few thousand a year against thirty thousand for fifteen percent of an engineer, so managed wins decisively. At ten to twenty nodes it is roughly even and the tiebreakers are competence and risk. At fifty-plus the premium exceeds a two-person platform team who can operate several systems, and self-hosting can win, but only if that team genuinely exists and stays.

"What does managed actually remove, and what does it only move?" It genuinely removes patching, hardware replacement, the backup mechanism, upgrade mechanics, node-failure pages and the expertise to run it. It only moves capacity planning, which becomes instance-class selection, cost management, which becomes a bill that grows faster than a fleet, performance tuning, which has fewer knobs that still matter, and the upgrade decision, which they force on their schedule instead of yours. And it adds a vendor availability dependency, a pricing model you do not control, and limits you cannot raise.

"What's the thing people skip?" Reading the service limits page before adopting. Connection limits scaled to instance size, maximum storage, IOPS tied to volume size, partition counts, no superuser, no custom extensions. It takes an hour to check each against three times your current scale, and hitting one at scale is a migration. The ones that surprise Postgres teams are the no-superuser and no-custom-extension limits, because those are not capacity limits, they are limits on what is possible at all.

"How do you think about lock-in?" Prefer managed services that run an open thing you could run yourself, because the exit is then "run it yourself or move providers" rather than a rewrite. Managed Postgres, Kafka, Kubernetes and Redis all have that property. And the honest caveat is that sometimes the proprietary service is dramatically better with no open equivalent, and refusing it on portability grounds gives up real capability for an exit you will probably never take. Name the lock-in, estimate the exit cost, and decide deliberately.

"What's the strongest argument for self-hosting?" Debugging. Self-hosted, you can ssh in, run perf, attach a profiler and read the source. Managed, you read the metrics they expose, open a ticket and wait, and that is worst exactly when it matters most. The honest counter is that most teams do not actually do the deep debugging they imagine they would: that ability is worth a lot to a team with a specialist and almost nothing to a team that would have filed a support ticket anyway.

"Walk me through a real decision." In one 40-engineer company, three decisions with three different deciding factors. Postgres went managed because it is not differentiating and the two engineers who know it well are worth more on schema and query design than on patching. Kafka went self-hosted at twelve brokers because the premium was around $70k a year and a partition-count limit would have forced a migration anyway, but the decision was conditional on training a second engineer within a quarter, because the bus factor of one was the real risk. And the vector database went managed because it is the first of a new kind, nobody has run one, and the operational learning would come out of the retrieval-quality work that actually differentiates.

"When would you reverse a managed decision?" When the premium exceeds a dedicated person and that person exists, or when a limit you cannot raise starts binding. Dropbox's move off S3 is the canonical case: at exabyte scale the premium justified building custom storage, and their own account says it would have made no sense smaller. The failure mode in the other direction is real too: organisations stay on managed long past the crossover because the migration is never the quarter's priority.

Common misconceptions

"Managed is more expensive." The instance bill is. The comparison including engineer time, on-call and upgrade cycles usually is not, until real scale.

"Managed means no operational work." It means less of one kind and more of another: negotiating limits, working around a missing feature, and explaining why you cannot see inside the thing that failed.

"Self-hosting gives you control." It gives you control and an obligation. The control is worth a lot to a team with a specialist and little to one that would have filed a support ticket anyway.

"Avoid lock-in at all costs." Sometimes the proprietary service is dramatically better with no open equivalent, and refusing it buys an exit you will never take. Price it and decide.

"The crossover is a number." It depends on competence, differentiation and whether the platform team genuinely exists. Teams get it wrong in both directions.

Interview delivery note

Reframe from cost to differentiation, because it resolves most cases in one question: "The question I'd ask first is whether running this well makes the product better in a way customers notice. For Postgres or Kafka or Kubernetes it doesn't, so the operational capacity should go where it does. That's a stronger argument than any cost comparison because it says where the capacity should go rather than what it costs."

Then correct the cost comparison people actually make: "And the sticker price is the least informative number. Managed Kafka at $4,200 against $1,400 of EC2 looks like a $2,800 saving, and it omits three engineer-weeks of setup, fifteen percent of an engineer ongoing, a week per major upgrade, and 2am pages needing someone who understands unclean leader election. Fifteen percent of an engineer is about $2,500 a month, so the saving is roughly zero before you price the bus factor."

Give the scale curve, because it stops the answer being ideological: "It reverses with scale. One to three nodes, managed wins decisively. Ten to twenty, roughly even. Fifty-plus, the premium exceeds a two-person platform team who can run several systems, and self-hosting can win, if that team genuinely exists and stays."

Volunteer the thing people skip: "And I'd read the service limits page before adopting and check each against three times current scale. It takes an hour, and hitting one at scale is a migration. The ones that surprise people aren't capacity limits, they're no-superuser and no-custom-extensions, which are limits on what's possible at all."

Close on the conditionality, because it is the honest form of the answer: "and if a self-hosting decision depends on one person, I'd make it conditional. In one case we self-hosted Kafka and committed to training a second engineer within a quarter, and without that the answer would have flipped. A decision that leaves an unmanaged bus factor isn't really a decision."

Further reading

  • The AWS, GCP and Azure service limits documentation for whatever you are considering, read before adoption rather than after.
  • Dropbox Engineering's Magic Pocket write-ups, for the large-scale reversal and its explicit scale caveat.
  • 37signals' published cloud-exit numbers and the responses to them, for a disagreement conducted in figures.
  • Cloud cost architecture, for the cost half of this decision in more detail.