Skip to main content
Logo
Overview

Cloudflare Containers vs AWS Fargate vs Fly.io in 2026

April 29, 2026
11 min read

Containers Got Weird Again in 2026

For about five years the answer to “where do I run this Docker image?” was boring. ECS Fargate if you were on AWS. GKE Autopilot or Cloud Run if you were on Google. Fly.io if you wanted something that felt closer to Heroku. Render or Railway if you wanted Heroku itself.

That settled landscape cracked open this year. Cloudflare Containers reached general availability on the Workers platform with millisecond billing and a routing model that bolts containers directly onto a Worker. AWS shipped Fargate on Graviton4 and pushed harder on Spot tasks. Fly.io kept evolving Machines v2 with faster boot times and better regional control. Suddenly the question isn’t “which managed Kubernetes do I tolerate” — it’s “what kind of platform do I actually want this to be.”

I’ve shipped production workloads on all three of these in the last six months. The answer depends on the shape of your traffic in ways the marketing pages will not tell you.

Three Different Mental Models for the Same Container

These platforms all run OCI images. They share almost nothing else.

Cloudflare Containers: A Container Hanging Off a Worker

Cloudflare’s model is unusual. You don’t deploy a container as a standalone service. You deploy a Worker, and the Worker can spin up a container instance per request, per session, or per durable object. The container lives inside Cloudflare’s network, billed by the millisecond while it runs and stopped between requests.

The upside is that everything Workers does — global anycast routing, smart placement, KV, R2, D1, Durable Objects — is right there. Egress on the Cloudflare backbone is free. Cold start is roughly a few hundred milliseconds for a small image because the platform aggressively pre-warms locations near your traffic.

The catch is the model. There’s no notion of “twelve replicas in us-east-1 behind an ALB.” You don’t get to pick a region. You don’t get a long-running daemon that holds in-memory state across requests. You write code that assumes the container could disappear when idle, which it will.

AWS ECS Fargate: Tasks That Stay Where You Put Them

Fargate is the boring, reliable, occasionally infuriating workhorse. You define a task with vCPU and memory. ECS schedules it onto AWS-managed capacity inside your VPC. It runs forever, or until you scale it down. You pay per vCPU-hour and per GB-hour, rounded to the second after a one-minute minimum.

This is the default for a reason. You get real VPC networking, IAM roles per task, Service Connect for service-to-service traffic, ALB or NLB for ingress, CloudWatch for everything, and the rest of the AWS surface area. ARM via Graviton4 is meaningfully cheaper than x86 — Graviton tasks run roughly 20% lower than equivalent x86, and benchmarks I’ve run show comparable or better performance on most JVM, Go, and Node workloads.

The pain is operational. Task definitions are JSON. CloudFormation or CDK is the path of least resistance for serious work. Spot Fargate exists but reclaim semantics are blunt. And the bill for a single always-on task at 1 vCPU and 2GB will surprise you the first time.

Fly.io: Firecracker MicroVMs You Can Pin Anywhere

Fly’s pitch is that every “machine” is a Firecracker microVM that boots in under a second, and you control exactly where it runs. You write a fly.toml, push your image, and tell Fly which regions you want replicas in. Anycast handles routing the user to the nearest one.

You get persistent volumes (real block storage, not S3-with-a-mount), private networking via WireGuard, and the ability to scale to zero on a per-machine basis. The platform is meaningfully more opinionated than Fargate but less constrained than Cloudflare — it sits in the middle on flexibility.

Fly’s reliability story has had bumps. They’ve been transparent about it, which I appreciate, but if you’re running anything where a regional outage materially hurts you, build your topology to assume one region can vanish. That’s true everywhere, but it’s especially true here.

What These Cost for Three Real Workloads

The pricing models look comparable on paper. They are not comparable in practice. The shape of your traffic determines who wins by an order of magnitude.

Workload 1: A Bursty Webhook Handler

Imagine a service that processes Stripe webhooks. Traffic is spiky, mostly clustered around business hours, with peaks at maybe 50 requests per second during checkout-heavy periods. Average daily compute might be 30 minutes of actual CPU work spread across 24 hours.

On Cloudflare Containers, you pay only when the container is running. If the work takes 200ms per request and you process 100K webhooks a month, you’re billed for roughly 5.5 hours of container time across the month. Even with a 1 vCPU / 1GB container, this comes out cheap — a handful of dollars in compute, plus negligible Workers invocation cost. Free egress closes the deal.

On Fargate, the same workload running 24/7 on a 0.25 vCPU / 0.5GB task burns roughly 180 vCPU-hours and 360 GB-hours a month. You’re paying for capacity that’s idle 99% of the time. Total around $10-12 a month, plus NAT Gateway costs if your VPC needs egress, which adds another chunk. Spot can cut that in half but you eat reclaim risk on a webhook handler, which is fine until it isn’t.

On Fly.io, you can scale to zero between requests, but cold start latency for a bursty handler matters more than it does for steady traffic. A small machine that wakes on demand, runs for 200ms, then idles down can compete with Cloudflare on raw cost. The catch is that “scaled to zero” still has a cold start, and webhooks are unforgiving about latency.

For bursty workloads, Cloudflare Containers is built exactly for this and it shows.

Workload 2: A 24/7 Public API

A REST API serving traffic continuously, 200 requests per second average, peaks around 800/s during business hours. You want at least three replicas across two regions for redundancy.

On Fargate, this is the home turf. Three tasks at 1 vCPU / 2GB each, in two regions, with Service Connect and an ALB. You’re looking at roughly $200-280 a month in compute on Graviton4, plus ALB hours, plus data transfer. The bill is predictable, the operational story is well-trodden, and you can reach for ECS Service Auto Scaling without inventing anything.

On Fly.io, the equivalent is six machines (three per region) at similar specs. Pricing is in the same ballpark, often a bit lower on raw compute, and Anycast routing is included rather than billed as an ALB. The catch is volume management if you have any persistent state — Fly volumes are pinned to a single machine, so you’re either running stateless or accepting a multi-region replication problem.

On Cloudflare Containers, this is where the model gets awkward. You can do it. But you’re paying for high-utilization compute on a platform whose billing model is optimized for low-utilization compute. Run the math and a 24/7 API at meaningful traffic costs more on Cloudflare than on Fargate Graviton4, before you even count the architectural friction of routing every request through a Worker.

For continuous APIs at scale, Fargate or Fly. Cloudflare is the wrong tool.

Workload 3: Cron-Driven Batch Jobs

A nightly job that pulls data from somewhere, transforms it, writes it to a warehouse. Runs for 15 minutes, once a day. Maybe a few of these.

This is where Cloudflare Containers is unfairly good. Workers Cron triggers spin up the container, the job runs, the container shuts down. You’re billed for 15 minutes a day, which is laughably cheap, and there’s no infrastructure to maintain.

Fargate can do this with EventBridge → ECS RunTask, which is fine, but you’re stitching together three services to do what Cloudflare does with one. Cost is comparable for the actual compute window but the operational overhead is real.

Fly.io has scheduled machines but the ergonomics aren’t as clean as either alternative for pure cron work.

Cold Start, Latency, and What “Edge” Actually Means

There’s a lot of marketing language about “edge containers.” Most of it is misleading.

Cloudflare Containers do run inside Cloudflare’s PoPs, but they don’t run in every PoP. The platform decides where to instantiate based on traffic patterns. Your container in response to a request from Tokyo might end up in a Tokyo PoP, or it might end up in a Singapore PoP, or it might end up wherever Cloudflare has spare capacity. You don’t control this. For most workloads that’s fine. For workloads with strict latency budgets to specific regions, it isn’t.

Fly.io’s anycast model is more honest about regional pinning. You declare which regions you want, traffic gets routed to the nearest healthy machine, and you can verify it. Cold start for a small Fly machine is around half a second to a couple seconds depending on image size and region warmth. Not edge-fast, but predictable.

Fargate cold starts are measured in tens of seconds for a fresh task, though that mostly matters during scale-out events, not steady-state traffic. ECS Service Auto Scaling can pre-provision capacity to absorb spikes, which is what most people actually do.

The honest summary: only Cloudflare runs your container at the network edge, and the trade-off is loss of regional control. The other two run in regions you pick, and that’s usually what you actually want.

The Limits That Will Bite You

Spec sheets lie by omission. Here are the constraints I’ve actually hit.

GPU support. Fargate has no GPU option — you go to ECS on EC2 or to SageMaker. Fly.io has GPU machines available in select regions. Cloudflare Containers don’t currently expose GPUs. If you need to run an inference container, the choice narrows fast.

Persistent storage. Fargate gives you EFS mounts, which are network-attached and behave like NFS. Fly gives you real block storage volumes pinned to a machine. Cloudflare Containers are ephemeral — persistent state goes to R2, KV, D1, or Durable Objects, which is a paradigm shift, not a tweak.

Image size. All three have practical limits, but Cloudflare’s matters most because cold start scales with image pull. Keep images under a few hundred megabytes if you can. Distroless or scratch base images pay off here in a way they don’t elsewhere.

Egress bandwidth and cost. Fargate egress through a NAT Gateway is expensive and frequently the largest line item nobody noticed. Fly’s egress pricing is reasonable, with generous free tiers in most regions. Cloudflare Containers get the network backbone for free, which is genuinely a big deal at scale.

Memory and vCPU caps. Fargate goes up to 16 vCPU and 120GB. Fly machines scale similarly. Cloudflare Containers are capped lower per instance — check the current limits before committing if you need beefy single-instance compute.

DX: The Day-to-Day Experience

This is the part that determines whether you’ll still be happy in eight months.

Cloudflare uses Wrangler. You define your container in a wrangler.toml, push with wrangler deploy, and the same CLI handles your Worker, your KV namespaces, your R2 buckets, and everything else. It’s tightly integrated and pleasant when you’re already on the platform. If you’re not, the learning curve is real because the model is genuinely novel.

Fargate uses whatever you’re already using to manage AWS. AWS Copilot CLI is the most ergonomic option for greenfield work — copilot init, copilot deploy, and you’re running. Beyond hello-world, you’ll probably want CDK or Terraform. Task definitions in raw JSON are a known unpleasantness.

Fly.io uses flyctl. fly launch from a Dockerfile-bearing directory will get you running in under five minutes. The fly.toml format is small enough to fit in your head. This is, in my opinion, the best DX of the three for a developer working alone or on a small team.

What I’d Actually Pick

For a bursty webhook handler or low-traffic internal service, Cloudflare Containers is the right answer in 2026. The billing model maps to the workload, the network is fast, and there’s no infrastructure to babysit.

For a 24/7 API serving real traffic in a company that needs VPC integration, IAM, compliance audits, or tight AWS service coupling, Fargate. The boring choice. The right choice when “boring” is what you actually want.

For a latency-sensitive multi-region service where you care about exactly where your code runs and want fast iteration, Fly.io. Especially for solo devs and small teams who don’t want to spend half their week reading AWS docs.

For cron and batch, lean toward Cloudflare unless you’re already deep in AWS, in which case EventBridge + Fargate is fine.

The thing nobody says out loud: most teams running a single service should pick whichever platform their next service will also live on. The cost of running heterogeneous infra is paid every day in context-switching, and it dwarfs whatever you save on a per-vCPU-hour basis.

If you’ve been on Fargate for years and the bill is creeping up, try moving one bursty service to Cloudflare Containers and see what happens. If you’re starting from zero today, give yourself an afternoon with fly launch and another afternoon with wrangler deploy before you commit. The platforms are close enough on price that DX should win the argument, and DX is a thing you have to feel.