Skip to main content

Cloudflare Containers vs a €4 Hetzner Box: What a Container Next to Your Worker Actually Costs

16 min readDora NodaDora Noda
Share

Cloudflare will run your container next to your Worker. Hetzner will rent you the whole box for €3.79. One bill scales with every 10 milliseconds your code is awake. The other stays flat even if you push 20 terabytes. The right pick is not about which logo is cheaper. It is about how many hours a day your container actually needs to be awake.

That single variable — duty cycle — decides the money. A preview app that handles a few deploy previews and then sleeps pays about $5 to $8.50 a month on Cloudflare Containers (the $5 Workers Paid base plus a few dollars of active compute) and idles for free. The same workload on the cheapest Hetzner CX23 or CAX11 still costs €3.79 to €3.99 whether it slept or not. Flip the workload to always-on, saturated 24/7, and Cloudflare's per-GB-hour and per-vCPU-second meters add up to $9.50 to $24.70 for a small basic container, while the Hetzner box is still €3.99 with 20 TB of traffic already included. Edge latency versus cost predictability is not a slogan. It is a duty-cycle breakeven you can compute on a napkin.

This post does that napkin math line by line, then shows why the architecture behind each price explains the number.


The headline numbers, before the tables

If you skim nothing else, take these three rows:

  • Bursty preview or internal tool (~5 hours active per day, ~150 wall-hours a month): Cloudflare lite (256 MiB, 1/16 vCPU) is about $6.20–$8.50 all-in; basic (1 GiB, 1/4 vCPU) about $6.20–$8.50 as well after the included allowances. Hetzner CAX11/CX23 is €3.79–€3.99 flat. Cloudflare wins on handling zero — scale-to-zero means you pay nothing while the preview sleeps; Hetzner wins on floor price if the preview exists at all.
  • Steady small service (~360 active hours, half the month): Cloudflare basic at 20% CPU-active lands near $10–$13, at 100% CPU-active near $16–$18. Hetzner is still €3.99–€7.99 depending on Intel vs ARM vs AMD line.
  • Always-on, saturated (730 hours, no sleep): Cloudflare basic is $13.80 (CPU 20% active) to $24.70 (CPU 100% active); lite is $6.90–$9.60. Hetzner CAX11 is €3.79, CX23 €3.99, CPX22 €7.99 — each with 20 TB included and no per-request meter.

Egress barely moves the Cloudflare number for most apps — 1 TB in North America and Europe is included, then $0.025 per GB. But that is the point: Cloudflare solves a latency problem a regional Hetzner fleet is not built to chase, while a Hetzner box solves a cost-predictability problem Cloudflare's meter never will. The rest of this post proves both halves with receipts.


What Cloudflare Containers actually is

Cloudflare Containers entered public beta in 2026, announced on the Cloudflare Blog as "Containers are available in public beta for simple, global, and programmable compute." It is not a separate product you buy. It is a primitive you attach to a Worker.

You write a normal Worker. That Worker can start a container, send it HTTP, run commands inside it, and let it sleep when idle. Cloudflare builds the image, schedules it across its global network, and places it near the user without you managing a cluster, a registry, or an autoscaler. Each container has its own Durable Object under the hood, and inbound requests flow through the Worker.

Billing reflects that design. Containers are billed per 10 milliseconds while actively running, not while sleeping. Memory and disk are charged on provisioned size, CPU only on active execution time:

  • Base: Workers Paid plan is $5 per month.
  • Included: 25 GiB-hours of memory, 375 vCPU-minutes, and 200 GB-hours of disk per month.
  • Overages: $0.0000025 per GiB-second of memory, $0.00002 per vCPU-second, and $0.00000007 per GB-second of disk.
  • Sleep: charges stop after the instance goes to sleep, which happens automatically after a sleepAfter timeout you configure. Scale-to-zero is the default posture, not a mode you opt into.

Instance types set the provisioned envelope:

InstancevCPUMemoryDisk
lite1/16256 MiB2 GB
basic1/41 GiB4 GB
standard-11/24 GiB8 GB
standard-216 GiB12 GB
standard-328 GiB16 GB
standard-4412 GiB20 GB

Egress is priced by where the bytes leave Cloudflare's network: North America and Europe $0.025 per GB with 1 TB included, Oceania/Korea/Taiwan $0.05 per GB with 500 GB included, everywhere else $0.04 per GB with 500 GB included. Workers requests themselves are included (10 million on Paid, then $0.30 per million), and the container's Durable Object is billed separately at Durable Objects rates, though for most single-container services the DO cost is pennies.

The consequence is simple: an idle container costs zero above the $5 base. A saturated container pays for every GiB-hour it held open and every vCPU-second it burned.


What a flat-rate Hetzner box actually is

Hetzner Cloud is KVM on AMD EPYC or Ampere Altra hardware with NVMe RAID10, a 99.9% SLA, and — the line that matters for this comparison — 20 TB of traffic included on every Cloud server in a European or US location. Pricing is per machine per month, not per second. You provision a server type, it exists, you pay the same whether it served one request or ten million.

The catch in 2026 is that "Hetzner pricing" stopped being one number. Hetzner raised prices twice:

  • April 1, 2026: a broad adjustment of 30 to 37% across cloud servers, storage, and dedicated servers, citing drastic IT-sector cost increases, especially DRAM and flash driven by AI demand.
  • June 15, 2026: a second round that landed hardest on dedicated and AMD shared lines. The cost-optimized Intel CX and ARM CAX lines rose a comparatively mild 33 to 38%, while CPX (shared AMD) and CCX (dedicated vCPU) jumped 107 to 204% on top of already-hiked April prices, depending on size.

The hike also renamed the old catalog. The CLI now rejects cx22, cx32, and cx42 as deprecated; the replacements are cx23, cx33, cx43 (Intel) and cax11 through cax41 (ARM). Any HetznerMachineTemplate that hardcodes cx22 will fail at apply.

Post-hike, post-rename street prices for the node-pool candidates a Cluster API fleet would actually use:

ServervCPU / RAM / DiskTrafficPrice (per month)
CAX11 (ARM, Ampere Altra)2 vCPU / 4 GB / 40 GB20 TB~€3.79
CX23 (Intel shared)2 vCPU / 4 GB / 40 GB20 TB~€3.99
CPX22 (AMD shared)3 vCPU / 4 GB / 80 GB20 TB~€7.99
CCX13 (dedicated AMD)2 dedicated cores / 8 GB / 80 GB20 TB~€14.86

Those are the official Hetzner Cloud rates you validate against api.hetzner.cloud/v1/server_types. There is no per-request, per-GB-second, or per-vCPU-second line to watch after the box is running. There is also no global edge. Your fleet lives in Nuremberg, Falkenstein, Helsinki, Ashburn, Hillsboro, or Singapore — you choose the region, you own the latency tradeoff, you own the failover plan. A declarative Cluster API fleet (CAPH) makes that ownership manageable — MachineDeployment scale-up, rolling upgrades, and health remediation are one reconciliation loop — but it does not make the machine appear in 300 cities. That is the architectural difference pretending to be a pricing difference.


The recompute: three workloads, line by line

To keep the comparison honest, the same three duty cycles are priced on both platforms. All Cloudflare math includes the $5 Workers Paid base, the included allowances (25 GiB-hours, 375 vCPU-minutes, 200 GB-hours), and 100 GB of egress in North America/Europe (well inside the 1 TB free band). Hetzner math is the flat box price; egress is already inside the 20 TB include, so it adds zero up to that ceiling.

Assumptions stated up front:

  • Container size for the comparison: basic (1 GiB, 1/4 vCPU, 4 GB disk) is the closest to a CX23/CAX11 for a small service. lite (256 MiB, 1/16 vCPU, 2 GB disk) is shown as the minimal Cloudflare envelope where it matters.
  • CPU-active fraction: Cloudflare bills CPU only when code executes. A web app waiting on a database does not burn vCPU-seconds. Two bounds are shown: 20% active (typical I/O-bound service) and 100% active (CPU-saturated, worst case).
  • Wall-hours are running hours. Thanks to scale-to-zero, a container only bills wall-hours while it is not sleeping, so 150 wall-hours means the container was actively instantiated for 150 hours that month.
WorkloadWall-hours billedCloudflare basic (20% CPU)Cloudflare basic (100% CPU)Cloudflare lite (100% CPU)Hetzner CAX11 / CX23
A — Bursty preview/internal: ~5 hrs active per day (150 hrs/mo), ~500k requests150 hrs~$6.22 (mem $1.13 + cpu $0.09 + disk $0.10 + $5 base)~$8.48 (mem $1.13 + cpu $2.25 + disk $0.10 + $5)~$6.30€3.79 / €3.99 flat
B — Steady small service: half the month active (360 hrs/mo), ~3M requests360 hrs~$10.60 (mem $3.02 + cpu $0.60 + disk $0.35 + $5)~$17.90 (mem $3.02 + cpu $7.88 + disk $0.35 + $5)~$7.80€3.79 / €3.99 flat
C — Always-on saturated: 24/7 (730 hrs/mo), ~10M requests730 hrs~$13.80 (mem $6.35 + cpu $2.18 + disk $0.69 + $5)~$24.70 (mem $6.35 + cpu $12.69 + disk $0.69 + $5)~$9.60€3.79 / €3.99 flat

Egress note: Under 1 TB per month in NA/EU, Cloudflare egress adds $0. Here the gap is pure compute. If you serve 5 TB globally, Cloudflare adds roughly $100 at $0.025 per GB beyond the included 1 TB; Hetzner still adds $0 up to 20 TB, then about $1.19 per TB beyond. A bandwidth-heavy, image-or-video-serving app is the worst fit for any per-GB meter and the best fit for a flat box.

What the rows mean

  • Row A proves why scale-to-zero exists. A preview environment that exists for 10 developers, builds a few times a day, and sleeps overnight costs less on Cloudflare than leaving a Hetzner box warm 730 hours for 150 hours of use. But the absolute cheapest "box that exists" is still Hetzner if you need that preview address to never cold-start.

  • Row B is the breakeven band. At half duty cycle the flat box starts to pull ahead unless your CPU-active fraction is genuinely low. A service that spends most of its wall time waiting on Postgres (20% CPU-active) is near parity with a CX23; a service that hashes, compresses, or renders on the CPU (approaching 100% CPU-active) pays almost the full vCPU-second meter and loses by €10+ to the flat box.

  • Row C is not close. An always-on service that cannot sleep pays the entire provisioned wall time. Even the smallest lite container billed 730 hours ($9.60 at 100% CPU) costs more than twice a CAX11, and a basic at full CPU saturation costs roughly six times a CX23. That delta funds the operational cost of owning the box many times over.

Sensitivity to one variable moves the answer: CPU-active fraction. Memory and disk scale with wall hours and instance size; they are predictable and bounded by the instance table. CPU is the meter that can swing a monthly bill by $10 on the same container in the same month simply because traffic got more compute-heavy. Hetzner has no equivalent meter — a 100% CPU-saturated core and a 5% idle core cost the same flat line.


Architecture that no price table captures

Dollars per GiB-hour settle the invoice. They do not settle the architecture. This is the half of the comparison teams get wrong by staring only at the meter.

Global placement versus regional ownership. Cloudflare schedules your container near the user, across hundreds of cities, behind the same anycast that already terminates your Worker. No MachineDeployment per region, no cross-region WireGuard mesh to maintain. Hetzner's fleet lives where Hetzner has data centers. You can run multi-location CAPH pools (Nuremberg + Helsinki + Ashburn) and own your failover, but you are still regional. If the product problem is tail latency to a globally distributed user base, "container next to a Worker" is the shortest path. If the problem is cost per steady request, regional ownership wins and you can add a CDN in front of the Hetzner origin instead of paying the container meter to chase every edge.

Cold start versus always-warm. Cloudflare Containers sleep. Waking takes seconds — fast enough for a backend that a Worker fronts with a loading response, too slow for a synchronous user-facing page without a strategy. You tune sleepAfter, keep a minimum instance warm, or accept that the first request after idle pays a cold-start tax no Hetzner box ever charges. Hetzner boxes never sleep. They also never scale to zero; you pay for the idle hours you slept through.

Bandwidth and storage coupling. Cloudflare separates them deliberately: 1 TB egress included in NA/EU, disk billed per GB-second, Durable Objects and R2 billed wherever state lives. That is good hygiene for a platform, but it means a stateful, bandwidth-heavy app assembles its price across three product pages. Hetzner couples 20 TB of traffic into the machine price and gives you a local NVMe volume that does not bill per read. An app that stores session state or caches large assets next to its origin is simpler to reason about on a flat box, and impossible to move to Cloudflare without rethinking where state lives.

Operational weight. Cloudflare eliminates the control plane you would otherwise operate: no Cluster API controllers, no HetznerMachineTemplate lifecycle, no node autoscaler, no etcd. You push an image; Cloudflare runs it. The tradeoff is that the container is not a Kubernetes pod. There is no Helm chart to install a sidecar, no persistent volume claim that survives the container's sleep without explicit work. A Hetzner fleet gives you the full Kubernetes API and every operator pattern that assumes it; it also gives you the ownership burden of upgrades, capacity planning, and — since 2026 — handling "no capacity in this location" when Hetzner's own available inventory runs tight.

Sovereignty and failure domain. A container on Cloudflare runs wherever Cloudflare places it for latency, which is the opposite of a data-location guarantee. You can pin some behavior, but the default is global. A Hetzner fleet runs in jurisdictions you explicitly chose. For teams that need to show an EU-only data path or a single-tenant failure domain that never correlates with someone else's hyperscaler outage, owned hardware is a compliance feature, not just a cost one.


Which problem are you actually solving?

The honest answer is almost always "one of these two":

Choose Cloudflare Containers when the problem is latency to a dispersed user base, spiky or preview-shaped traffic, or never paying for idle.

  • Your app is stateless or state lives in Durable Objects, KV, or R2 and the container is a render or compile sandbox.
  • Traffic is bursty — deploy previews, webhook handlers that scale on a deploy event, agent sandboxes that wake, work, and sleep.
  • You care more about global time-to-first-byte than about per-month bill variance, and the app fits in lite or basic with most wall hours spent sleeping.

Choose a flat-rate Hetzner fleet when the problem is cost predictability at steady traffic, bandwidth that matters, or owning the failure domain.

  • Your app is always-on or long-lived: queues, workers, Postgres-backed APIs that hold connections open.
  • Bandwidth dominates the bill (user uploads, image transforms, video packaging) and 20 TB included removes a whole forecasting dimension.
  • You need Kubernetes-native operators, persistent volumes that do not disappear when the container sleeps, or a data-residency story that starts with "this machine is in Falkenstein."

The pattern that ages best for most teams is both, at a boundary: Workers and Containers at the edge for global ingress, auth, and stateless rendering, with a Hetzner-backed origin behind it for Postgres, queues, and anything whose per-request cost you want to turn into a flat line. Cloudflare plus owned hardware is not a contradiction. It is a deliberate placement decision about which side of the latency versus predictability tradeoff each workload belongs on.


Closing

Cloudflare Containers in public beta does something genuinely new: it lets a Workers project attach a real container without leaving the Workers platform, billed down to the 10-millisecond slice and allowed to sleep to zero. That is the most honest "pay for what you use" story Cloudflare has shipped. Hetzner's 2026 repricing, including the painful CCX and CPX hikes and the quieter CX/CAX increases that replaced cx22 with cx23, did not change the other story: a small EU box with 20 TB included still costs the same next month as it did this month, no meter to watch.

Public beta pricing will move. Hetzner's capacity and catalog already have. Whatever the next adjustment looks like, the decision framework in this post will still hold: compute the duty cycle first, decide whether the app's state can sleep, then pick the platform whose price shape matches the workload's life shape. The cheapest container is not the one with the lowest rate per GiB-second. It is the one whose idle hours you do not have to buy.

Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. A flat Hetzner fleet under Cluster API with a Render-compatible API is the "own the box, keep the PaaS UX" answer to the exact tradeoff this post computed — try your spiky edge work on Containers and your steady origin on owned hardware, from the same git push. Star the repo on GitHub or deploy your first app today.

Related articles

Run this on infrastructure you own

bex is the open-source, AI-native Render alternative — push a git repo and get a running HTTPS service on your own machines.

Get started with bex