In April 2026, Healthchecks.io published a short migration note that hit 195 points on HN: they moved object storage off a managed cloud bucket onto infrastructure they run themselves. No new product, no funding announcement — just a bill that got smaller and a system they now own.
For teams running a self-hosted PaaS on Hetzner hardware, the post is more useful as a decision framework than as a tutorial. The trade is always the same: you take on replication, backup, and capacity planning, and you delete per-GB storage and egress line items.
What Healthchecks.io actually moved
- From: managed object storage (pay-per-GB stored + per-GB egress)
- To: self-hosted S3-compatible store on owned disks (Hetzner NVMe or dedicated storage boxes)
- Why now: egress on a monitoring service is not bursty — it's constant, and the managed bucket was charging for every check artifact pulled by workers.
The write-up's punchline was not “self-hosted is cheaper if you squint.” It was “self-hosted is cheaper at steady state, and the steady state is where a PaaS lives.”
The math that matters
| Line item | Managed bucket | Self-hosted (MinIO/Garage on Hetzner) |
|---|---|---|
| Storage | $0.015–0.023/GB/mo | NVMe already in fleet + replication factor |
| Egress | $0.01–0.09/GB (or free to CDN only) | $0 on private network, flat transit on Hetzner |
| Operations | Included | You run the daemon, upgrades, and monitoring |
| Durability | Provider SLA | Your replication + backup policy |
Break-even is not a fixed number. For a 2 TB artifact store with 4 TB/mo egress, managed cost is ~$70–120/mo before API operation charges. A single Hetzner CPX31 with 160 GB NVMe plus a second replica is already in the fleet for the PaaS control plane — the marginal disk cost is near zero.
When to bring the bucket home
Bring it home when:
- Egress is >2× stored data per month (build artifacts, image layers, backups)
- The store is co-located with the consumers (same data center, same private network)
- You already operate Postgres/Redis on the fleet — one more stateful set is not a new discipline
Keep it managed when:
- Access is global and latency-sensitive without a CDN
- Your team has no on-call for storage (managed bucket's pager is someone else's problem)
- Data residency is not a constraint and egress is <1× stored
The PaaS placement
On a self-hosted PaaS, object storage is just another tenant workload: a StatefulSet with hostPath or dedicated volumes, fronted by the same ingress and TLS automation as any app. The same Hetzner fleet that runs the apps runs the store that serves them, on the same private network, with no egress meter between them.
Healthchecks.io's move is a reminder that “S3” is an API, not a vendor. If your PaaS already speaks S3 to store buildpacks, the cheapest S3 endpoint is the one on the next rack.
Checklist before you switch
- Pick the store: MinIO (mature), Garage (lightweight), SeaweedFS (scale-out). All speak S3.
- Size for 3× replication, not 1× capacity.
- Put it behind the same backup and alerting as your Postgres.
- Measure egress for 30 days, then price both options with real numbers — not the provider's calculator defaults.



