Scaling Containers in AWS
Every AWS container service can scale. What separates them is what they scale, how fast, and how much of the mechanism you have to own. This page covers the scaling model of each; the choice between the orchestrators themselves is in AWS Container Services.
The control and complexity spectrum
Section titled “The control and complexity spectrum”The services form a spectrum. Moving along it, you give up control over the infrastructure and get back operational simplicity.
EKS on EC2 instances — high control, high complexity. The full Kubernetes platform, every knob exposed, your instances, your add-ons, your upgrade schedule.
ECS on EC2 instances — moderate control, moderate complexity. AWS’s opinionated scheduler on capacity you still own and patch, with AWS service integration handled for you.
Fargate (under either orchestrator) — lower control, low complexity. No instances at all. You size the task or pod; AWS finds somewhere to run it.
Amazon ECS Express Mode — minimal control, minimal complexity. One API call takes a container image and two IAM roles and provisions the whole stack: an ECS service on Fargate, an Application Load Balancer with target groups and health checks, auto-scaling policies, networking, and a URL. There is no charge for Express Mode itself, only for the resources it creates.
Where you should sit is usually decided by a single hard requirement — a GPU, a DaemonSet, a licensed AMI, a Kubernetes operator — rather than by preference. In the absence of one, sit at the simple end.
Scaling EKS
Section titled “Scaling EKS”Two layers scale independently, and both have to be configured.
Pods. The Horizontal Pod Autoscaler adds and removes pod replicas against CPU, memory or custom metrics. The Vertical Pod Autoscaler adjusts requests and limits on existing pods.
Nodes. Karpenter is now the mainstream choice: it watches for unschedulable pods and provisions right-sized instances directly from EC2, consolidating workloads and terminating nodes that are no longer needed. It is also what EKS Auto Mode uses under the covers — Auto Mode manages compute autoscaling, node AMIs and lifecycle, pod networking, load balancing and block storage as first-class parts of the cluster rather than as add-ons, with a maximum node lifetime of 21 days.
The older Cluster Autoscaler scales Auto Scaling groups instead of provisioning instances directly. It still works, but it constrains you to the instance types in the node group and its version must track the cluster’s Kubernetes minor version.
Strengths: the mature Kubernetes ecosystem, community support, familiarity for teams that already run Kubernetes, and near-unlimited customisation.
Costs: AWS integrations are controllers you install and upgrade; load balancer configuration is indirect; the operational surface is large; and both scaling layers are yours to tune.
Scaling ECS
Section titled “Scaling ECS”ECS Service Auto Scaling uses Application Auto Scaling to change a service’s desired task count on target tracking, step or scheduled policies. The three built-in target-tracking metrics — average CPU, average memory, and ALB requests per target — cover most services without any custom metric work.
If the tasks run on EC2 capacity, cluster capacity providers with managed scaling adjust the underlying Auto Scaling group to match task demand, so you are not scaling two things by hand. If they run on Fargate, there is no second layer.
Strengths: native ALB and NLB registration, IAM and CloudWatch integration with no controllers to install, and a much smaller thing to get wrong.
Costs: confined to what AWS ships, and not portable off AWS.
Both ECS and EKS support container instances, Fargate, AWS Outposts, AWS Local Zones and AWS Wavelength.
Fargate
Section titled “Fargate”Fargate is a compute engine rather than an orchestrator: it supplies right-sized, isolated capacity to ECS or EKS on demand.
How it scales. Per task or per pod, not per instance. When the service scales from 10 tasks to 14, four tasks’ worth of capacity appears; nothing rounds up to the next instance size and nothing is left half-empty. There is no fleet to patch, no AMI to rebuild and no host to secure.
What you give up. No access to the host, no DaemonSets on the EKS side, no privileged containers, no GPUs, and a fixed menu of CPU and memory combinations — from 0.25 vCPU with 512 MiB up to 16 vCPU with 120 GiB, and 32 vCPU at 60, 120 or 244 GiB on Linux.
Where it fits. Request/response services, scheduled and batch tasks, event handlers, and anything whose load varies enough that an owned fleet would sit idle. The comparison with owned instances comes down to two things: a higher price per vCPU-hour, against much higher utilisation and no fleet to operate.
AWS Batch
Section titled “AWS Batch”AWS Batch scales against a queue rather than against a metric. You submit jobs; Batch provisions compute environments to drain the queue and scales them back to zero when it is empty.
- Runs jobs on Amazon ECS, Amazon EKS, Fargate, EC2 instances or Amazon ECS Managed Instances
- Chooses CPU- or memory-optimised capacity from the resource requirements declared in the job definition
- Supports Spot capacity, which is where most of the cost saving comes from
- Suits work measured in job runs — rendering, simulation, ETL, model training — rather than uptime
The trade with Spot is timing: jobs may wait for capacity and may be interrupted, so job definitions need retry strategies and the work needs to be restartable.
AWS App Runner
Section titled “AWS App Runner”App Runner was the fully managed option for HTTP applications, scaling to zero from either a container image or source. AWS has closed App Runner to new customers. Existing customers can continue to use it and create new services, and AWS continues to invest in its security and availability, but no new features are planned.
For new work AWS directs you to Amazon ECS Express Mode, which keeps the operational simplicity while giving access to the wider ECS feature set. AWS publishes a migration path from App Runner to Express Mode using DNS weighted routing.
Choosing a service
Section titled “Choosing a service”Existing Kubernetes workloads. EKS, for minimal refactoring — but budget for the operational overhead, and consider EKS Auto Mode to reduce it.
New container deployments. ECS for the smallest AWS-integrated thing that works; Fargate underneath it unless a hardware or host requirement rules it out.
HTTP applications with minimal operational appetite. ECS Express Mode. Watch the cost as traffic grows: the managed options are cheap at low volume and expensive at high steady volume.
Batch processing. AWS Batch, with Spot capacity if the jobs are interruptible.
- Fargate wins on variable load, because you stop paying for idle instances.
- EC2 capacity with a Savings Plan or Spot wins on high, steady utilisation.
- Managed convenience is priced per unit of compute, so it inverts as volume grows — re-check the maths after a service has been running long enough to have a real utilisation figure.
- EKS charges per cluster-hour, which is an argument against a cluster per team.