You have a container. It runs on your laptop with a single docker run, it passes its tests, and it is ready for production. Then you open the AWS console to deploy it and the questions start. Which EC2 instance type? How many of them? Which AMI? Who patches the operating system next month? What happens when the cluster runs out of room at 2 a.m.?
None of those questions are about your application. They are about the machines your application happens to need. AWS Fargate exists to make those questions go away.
The Problem: Containers Still Need Machines
Containers changed how we package software, but they did not remove servers. A container is just a process with some isolation around it. It still has to run on a kernel, on a host, somewhere.
Orchestrators like Amazon ECS (Elastic Container Service) and Amazon EKS (Elastic Kubernetes Service) decide where containers run, restart them when they crash, and wire them into load balancers. In their classic form, though, they place containers onto a fleet of EC2 instances that you own. The orchestrator manages the containers. You manage the fleet.
Managing the fleet is real work. You pick instance sizes and hope your mix of containers packs neatly onto them. You patch the OS and upgrade the container agent. You scale the fleet itself, separately from the containers, and you keep spare capacity around so new containers have somewhere to land. That spare capacity costs money whether anything uses it or not.
This is undifferentiated heavy lifting: effort every team pays for but no customer ever notices. Fargate moves that effort to AWS.
What Fargate Actually Is
Fargate is a serverless compute engine for containers. It is not an orchestrator of its own. It sits underneath ECS or EKS as a place for them to run containers, instead of your own EC2 instances.
The deal is simple. You describe what a container needs: how much CPU, how much memory, which image, which network. Fargate finds the compute, runs the container on it, and takes the capacity back when the container stops. There are no instances in your account to look at, SSH into, or patch.
A useful comparison: with EC2 you rent a whole apartment and furnish it yourself. With Fargate you book a hotel room of a specific size for exactly as long as you need it. Housekeeping, plumbing, and the building are someone else's problem.
Notice what stays with you. Your code, your image, your resource sizing, and your scaling rules are still yours. Fargate removes the host layer, not the thinking about your application.
How It Works
The building blocks
Fargate is most often used with ECS, so it helps to know a little ECS vocabulary. A task definition is a blueprint: which container images to run and what they need. A task is one running copy of that blueprint, much like a pod in Kubernetes. A service keeps a desired number of tasks running and replaces any that fail.
A cluster is a logical grouping of services and tasks. With Fargate, a cluster contains no machines at all; it is just a namespace. When you launch a task, you choose a launch type or capacity provider, and choosing FARGATE is the switch that tells ECS to use AWS-managed compute instead of your instances.
A task definition
Here is a minimal task definition for a small API, in JSON:
{
"family": "orders-api",
"requiresCompatibilities": ["FARGATE"],
"networkMode": "awsvpc",
"cpu": "512",
"memory": "1024",
"runtimePlatform": {
"cpuArchitecture": "ARM64",
"operatingSystemFamily": "LINUX"
},
"executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"containerDefinitions": [
{
"name": "api",
"image": "123456789012.dkr.ecr.us-east-1.amazonaws.com/orders-api:1.4.2",
"essential": true,
"portMappings": [{ "containerPort": 8080 }],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/orders-api",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "api"
}
}
}
]
}
Most of this is ordinary container configuration. A handful of fields matter specifically for Fargate. requiresCompatibilities declares the definition is meant for Fargate, so ECS validates it against Fargate's rules up front.
cpu and memory are set at the task level and are mandatory. They are expressed in CPU units (1,024 units is one vCPU) and MiB, so this task asks for half a vCPU and 1 GB of memory. Fargate only accepts certain pairings: 0.25 vCPU with 0.5 to 2 GB, 1 vCPU with 2 to 8 GB, and so on up to 16 vCPU with up to 120 GB.
networkMode must be awsvpc, which gives each task its own network interface. runtimePlatform selects the CPU architecture; ARM64 runs the task on Graviton processors, which cost less per hour than x86 at the same size. The executionRoleArn is the IAM role Fargate uses on your behalf to pull the image and ship logs to CloudWatch.
To run three copies of it as a service, using the AWS CLI:
aws ecs create-service \
--cluster prod \
--service-name orders-api \
--task-definition orders-api \
--desired-count 3 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[subnet-0a1b2c],securityGroups=[sg-0d4e5f],assignPublicIp=DISABLED}"
There is no instance ID anywhere in that command. You name a subnet and a security group, and Fargate takes it from there.
What happens when a task starts
Behind that command, a sequence unfolds that you never see directly but that explains most of Fargate's behavior.
The important step is the third one. Every Fargate task runs in its own isolated environment, sized to exactly what the task definition asked for. AWS has said publicly that Fargate uses Firecracker, the lightweight virtualization technology it built for Lambda and Fargate, so each task gets its own kernel. Tasks never share a kernel with another customer's workload, or even with your own other tasks. That is a stronger isolation boundary than many containers sharing one EC2 host.
Because a fresh environment is provisioned per task, startup is slower than dropping a container onto an instance that is already running. Expect tens of seconds, driven largely by image size. Smaller images start faster.
Networking: every task is a first-class citizen
With awsvpc mode, each task gets its own elastic network interface (ENI) in a subnet you choose, with its own private IP address. Security groups attach to the task itself, not to a host shared by many containers. From the VPC's point of view, a Fargate task looks much like a small EC2 instance.
This design has one consequence that catches nearly everyone once. The task has to reach Amazon ECR to pull its image. In a private subnet with no route out, the pull fails and the task stops with a CannotPullContainerError. The fix is a NAT gateway, or VPC endpoints for ECR, S3, and CloudWatch Logs. In a public subnet, the task instead needs assignPublicIp=ENABLED.
Each ENI also uses an IP address. A busy service in a small subnet can run out of addresses before it runs out of anything else.
Storage
Each task gets 20 GiB of ephemeral storage by default, expandable to 200 GiB. It is scratch space and disappears when the task stops. For data that must survive restarts, mount Amazon EFS, or better, keep state in a managed service such as S3 or a database.
Paying for It
Fargate bills for the vCPU and memory a task requests, per second, with a one-minute minimum. How much of that the application actually uses does not matter. Ask for 2 vCPU and use 10 percent of it, and you still pay for 2 vCPU.
In US East (N. Virginia), Linux on x86 costs about $0.04048 per vCPU-hour and $0.004445 per GB-hour. The task above, at 0.5 vCPU and 1 GB, running around the clock for a 730-hour month comes to roughly (0.5 × $0.04048 + 1 × $0.004445) × 730, or about $18 per month. Rates change and vary by region, so check the current AWS pricing page before budgeting.
Per unit of compute, Fargate costs more than EC2. The fairer comparison, though, is against EC2 as teams actually run it. A fleet that sits half empty so there is room to scale, or that packs containers badly, wastes capacity you still pay for. Fargate has no idle instances, so its higher unit price often comes out even or ahead for spiky or modest workloads.
Two levers bring the price down. Fargate Spot runs tasks on spare AWS capacity at up to about 70 percent off, in exchange for AWS being able to reclaim them with a two-minute warning. Graviton tasks are cheaper than x86 at the same size, and Compute Savings Plans apply to Fargate as well.
Also budget for what surrounds the tasks: load balancers, NAT gateway data processing, public IPv4 addresses, and log ingestion. For small services, these can exceed the Fargate bill itself.
Where Fargate Sits in the Compute Spectrum
AWS offers several ways to run code, and they trade control for convenience. Fargate sits deliberately in the middle.
Compared with Lambda, Fargate runs a normal, long-lived container: any language, any web framework, no 15-minute execution limit, and no need to restructure your code around events. Compared with ECS or EKS on EC2, it gives up host access in exchange for having no hosts to manage.
Variants and Limits
Fargate does not behave identically everywhere it appears, and it does not suit every workload.
- Fargate on ECS is the most complete integration. It supports Fargate Spot, Graviton, Windows containers, and the full range of task sizes.
- Fargate on EKS runs Kubernetes pods instead of ECS tasks and differs enough to get its own subsection below. Fargate Spot and Graviton are currently ECS-only.
- No host-level access. Privileged containers, host networking, and custom kernel settings are not available. Anything that needs to reach below the container is ruled out.
- No GPUs. GPU-based machine learning training or inference needs EC2-backed capacity.
- Large, steady fleets running at high utilization all day are usually cheaper on well-packed EC2 instances with reserved pricing.
Fargate on EKS
On EKS, you tell Kubernetes which pods belong on Fargate with a Fargate profile. A profile lists namespaces, optionally narrowed by labels, and any new pod that matches is scheduled onto Fargate instead of your node groups. Pods that match no profile stay on EC2 nodes, so one cluster can mix both.
Each Fargate pod runs in its own microVM, and Kubernetes sees that microVM as a node. Run kubectl get nodes and you will find one fargate- node per pod. Fargate sizes each one from the pod's resource requests, plus a small memory overhead for the Kubernetes components running alongside it, so a pod with no requests gets the smallest size.
Because no node is shared, DaemonSets never run on Fargate. Log shipping uses a built-in Fluent Bit router configured through the aws-logging ConfigMap, and monitoring agents run as sidecar containers instead. Fargate pods must also run in private subnets.
Where You'll Encounter It
The most common Fargate workload is a web API or website behind an Application Load Balancer. The ECS service keeps a set number of tasks running, registers each one with the load balancer, and scales the count on CPU or request rate.
Background workers are the second big category. Tasks pull jobs from an SQS queue, and the service scales with queue depth, all the way down to zero when there is nothing to do. Scheduled jobs are a third: an EventBridge schedule starts a task every night for a report or a data export, and you pay only for the minutes it runs.
You will also meet Fargate indirectly. Many infrastructure-as-code templates and deployment tools default to it, and some CI systems use Fargate tasks as disposable build runners. A clean, isolated environment per job, discarded afterward, is exactly what Fargate provides.
Summary
Fargate does not change what a container is or how ECS and EKS orchestrate it. It changes where containers run. Instead of a fleet of EC2 instances you size, patch, and scale, each task gets its own isolated slice of compute that exists only while the task does.
The trade is straightforward. You give up host access and pay more per vCPU; in return, the thing you manage shrinks from a server to a task definition. For most web services, workers, and scheduled jobs, that is the right trade. When you need GPUs or privileged access, or you run a large and steady fleet, EC2 is still there.
If you remember one thing, make it this: with Fargate, capacity planning becomes two numbers in a task definition.
Part of the Explained series — concepts in tech, clearly.