ECS Capacity Provider Not Scaling? Launch Type vs Strategy, "EMPTY CAPACITY PROVIDER", Scale-In, Base and Weight, and Service vs Cluster Auto Scaling

Logeshwaran
—

An ECS capacity provider tells a cluster where tasks get their compute: an EC2 Auto Scaling group (with managed scaling, ECS grows and shrinks the group for you) or Fargate / Fargate Spot. When it is not scaling, the usual causes are: the service or task was started with a launch type instead of a capacity provider strategy, so its waiting tasks never trigger scale-out; managed scaling is off; the Auto Scaling group's maximum size is already reached (or zero); new instances launch but never register with the cluster (wrong ECS_CLUSTER in user data, missing instance role, no route to ECS); the task needs more CPU or memory than any instance type in the group; or someone added their own scaling policy or removed the AmazonECSManaged tag. TaskFailedToStart: EMPTY CAPACITY PROVIDER means the cluster has no registered instances in that provider. Below: how managed scaling decides (the CapacityProviderReservation metric and target capacity), base and weight strategies, scale-in that never happens, service auto scaling vs cluster auto scaling, and setup with the CLI and Terraform.

Monday mornings are busy for the shop's ticketing API. Service auto scaling did its job and asked for eight tasks instead of four. Four ran. The other four sat waiting, and the EC2 Auto Scaling group behind the cluster did not add a single instance. In the staging cluster, a scheduled job failed the same morning with "EMPTY CAPACITY PROVIDER", even though Ethan could see an EC2 instance running in the console. Two clusters, two problems, one confusing idea at the center of both: the difference between asking for tasks and asking for machines.

⚡ Quick Answer

• Not scaling out? Use a capacity provider strategy, not a launch type, and check the group's max size. Every cause.

• EMPTY CAPACITY PROVIDER? Instances are not registering with the cluster. Fix.

• Never scales in? Target capacity, spread placement, or protected instances. Fix.

• Base and weight: base = guaranteed tasks first, weight = share after that. Strategy.

What it is · How scaling decides · Service vs cluster scaling · CLI and Terraform · Fargate Spot.

New to ECS or Auto Scaling? The cards below cover both in plain English, plus the cost of ECS on EC2 versus Fargate.

🧭 NEW HERE? READ THESE FIRST

New to ECS or EC2 Auto Scaling? These five pages give you the background this one builds on:

📌 Bookmark this; the not-scaling checklist and the strategy examples are the parts you will come back for.

What an ECS capacity provider is

An ECS cluster runs tasks (your containers) on capacity (compute). Our plain-English ECS guide covers clusters, services and tasks. A capacity provider is a named source of capacity that you attach to your cluster:

  • Auto Scaling group capacity provider: a group of EC2 instances you own. With managed scaling on, ECS changes the group's desired capacity to fit the tasks that need placing. With managed termination protection, ECS stops the group from terminating instances that still run tasks.
  • FARGATE and FARGATE_SPOT: built-in providers where AWS runs each task on its own capacity; Spot is cheaper and can be interrupted.
  • ECS Managed Instances: a newer option where AWS runs and patches the EC2 instances for you while you still choose instance characteristics.

A capacity provider strategy says how a service's or task's copies are spread across the cluster's providers, using base and weight. A cluster can also have a default strategy, used whenever a service or task does not name one.

The older alternative is a launch type (EC2 or FARGATE) on your service or task. It still works, but if you start tasks with a launch type, they are placed only on capacity you already have: they never cause your Auto Scaling group to grow. That one difference explains the shop's Monday morning.

Jake: "So the service asked for more tasks, but nobody asked for more machines?"

Ethan: "Right. The service still had the old launch type. The tasks waited for room that nothing was going to make."

Cluster, service, task and capacity provider: who does what

Four ECS words get mixed up constantly, and the scaling problems on this page are much easier once they are straight:

  • Task: one running copy of your containers, defined by a task definition (image, CPU, memory, ports). It is the unit that actually runs.
  • Service: a keeper of tasks. It holds a desired count ("always run four"), replaces tasks that die, connects them to a load balancer, and rolls out new versions. Service auto scaling changes its desired count.
  • Cluster: the grouping that services and tasks run in, together with the capacity that runs them. It holds no compute of its own; capacity providers bring it.
  • Capacity provider: where the compute comes from, an Auto Scaling group of EC2 instances, Fargate, or ECS Managed Instances.

"ECS cluster vs ECS service" questions usually come from expecting the cluster to scale on its own. It does not: the service decides how many tasks, and the capacity provider decides how much compute those tasks need. A cluster with services but no capacity provider on EC2 is a waiting room with no chairs added when people arrive.

How managed scaling decides when to add or remove instances

When you turn on managed scaling, ECS publishes a metric called CapacityProviderReservation to CloudWatch (namespace AWS/ECS/ManagedScaling) for each of your Auto Scaling group capacity providers:

CapacityProviderReservation = (instances needed) / (instances running) x 100

"Instances needed" counts the instances required for the tasks already running plus the tasks waiting to be placed through that provider. ECS also creates a target tracking scaling policy on your Auto Scaling group, plus a high and a low CloudWatch alarm, aiming to keep the metric at your target capacity:

  • Reservation above target: tasks need more room than you have; the alarm raises the group's desired capacity, new instances launch, register with the cluster, and waiting tasks start on them.
  • Reservation below target: there is spare room and at least one instance that could go; the alarm lowers desired capacity and the group terminates an instance.
  • Reservation equals target: nothing happens.

You set target capacity as a percentage from 1 to 100. At 100, ECS keeps your instances fully used and adds one only when a task cannot fit, so your new tasks wait (PROVISIONING) for a few minutes during scale-out. If you set it below 100, for example 80, ECS keeps spare room so your new tasks usually start at once, and you pay for that idle capacity.

You can also set, on the capacity provider: minimum and maximum scaling step size (how many instances can be added or removed at once), and the instance warm-up period (how long a new instance counts as "coming" before its metrics are trusted, 300 seconds by default). When ECS scales out from zero instances, it launches two.

Two rules keep this working for you: change these settings through your capacity provider rather than by editing the ECS-created scaling policy, and keep your own scaling policies away from the group's desired capacity.

Capacity provider vs a plain Auto Scaling policy

Before capacity providers, teams scaled ECS instance groups with ordinary Auto Scaling policies, usually on average CPU or memory reservation of the cluster. People still ask why that is not good enough. The difference is what each one can see:

  • A CPU-based group policy sees how busy the instances are. Tasks that cannot be placed use no CPU at all, so a cluster with ten tasks waiting can look idle and never scale out.
  • A reservation-based policy (cluster CPU or memory reservation) sees what running tasks have reserved, which is closer, but still blind to waiting tasks and to fragmentation: free memory spread thinly across instances, none big enough for the next task.
  • Managed scaling counts the instances needed for running and waiting tasks, placement constraints included, so it scales out because a task cannot fit, and scales in only when an instance can actually be emptied.

That is also why the two must not be mixed. An old CPU policy left on the group fights the ECS-created policy, and the group scales up and back down in a loop. When moving an existing cluster to a capacity provider, delete the old policies and scheduled actions that touch desired capacity first.

Capacity provider not scaling out: every cause

SymptomCauseFix
Tasks fail at once with RESOURCE:MEMORY or RESOURCE:CPU; no new instancesThe service or RunTask uses a launch type, not a capacity provider strategyUpdate the service to a capacity provider strategy (or set a cluster default and remove the launch type)
Tasks stuck in PROVISIONING, group not growingGroup's maximum size reached, or 0Raise the group's max size; ECS never changes min or max
Group desired capacity changes, instances never appearLaunch template problem, vCPU quota, or no capacity for that instance typeCheck the group's Activity history for the launch error
Instances launch but tasks still waitInstances do not register with this clusterECS_CLUSTER in user data, instance role, ECS-optimized AMI, network path
Some tasks never place, even after scale-outTask needs more CPU/memory than the instance type has, or a GPU, port or placement constraint no instance meetsLarger instance types in the group; check task size and constraints
Nothing reacts at allManaged scaling is off on the capacity providerTurn on managed scaling
Scaling stopped after a tooling changeThe AmazonECSManaged tag was removed from the groupRestore the tag; exclude it from tag clean-up tools
Group scales up and straight back downAnother scaling policy or a scheduled action fights ECS's policyRemove other policies changing desired capacity
awsvpc tasks wait with free CPU and memoryOut of ENIs on the instances (RESOURCE:ENI)Instance types with more ENIs, or ENI trunking
Capacity provider cannot be added to a second clusterWith managed scaling, a provider belongs to one clusterOne Auto Scaling group and provider per cluster

Work through them in this order, because each check is quick:

  1. How was the task started? aws ecs describe-services --cluster shop --services ticket-api --query "services[].[launchType,capacityProviderStrategy]". If launchType is EC2, that is your answer.
  2. Is managed scaling on? aws ecs describe-capacity-providers --capacity-providers shop-asg-cp --query "capacityProviders[].autoScalingGroupProvider.managedScaling".
  3. What does the metric say? In CloudWatch, AWS/ECS/ManagedScaling, CapacityProviderReservation for your cluster and provider. Above target with no new instances points at the group; equal to target with tasks waiting points at the task (size or constraints).
  4. What did the group do? EC2 console, Auto Scaling groups, your group, Activity tab: launch failures (quota, capacity, launch template) show here with the reason. Our guides to InsufficientInstanceCapacity and vCPU limits cover the two most common launch failures.
  5. Did instances register? aws ecs list-container-instances --cluster shop. Running EC2 instances that are missing from this list are the EMPTY CAPACITY PROVIDER case below.
  6. Why is the task not placed? aws ecs describe-tasks on a waiting task, or the service's Events tab, which says things like "was unable to place a task because no container instance met all of its requirements" and names the missing resource.

For the shop, step 1 found it: the ticketing service was created years ago with launchType: EC2. Ethan switched it to a capacity provider strategy with a forced new deployment, and the next spike added two instances within five minutes.

How long scale-out takes, and how to make it faster

Even when everything works, scale-out on EC2 is not instant. The minutes go roughly like this: ECS publishes the reservation metric each minute, the high alarm needs a few data points above target before it acts, the group launches an instance, the instance boots and the ECS agent registers, and finally the task pulls its container image and starts. Three to six minutes from "tasks waiting" to "tasks running" is normal; longer usually means a slow image pull or a slow boot.

The levers, from cheapest to most involved:

  • Keep spare room with a target capacity below 100. New tasks start immediately on existing instances while ECS adds more in the background.
  • Shrink image pulls. Smaller images, pulled from ECR in the same Region, start faster; an ECR pull through cache for public base images avoids slow pulls from the internet.
  • Use a warm pool. EC2 Auto Scaling warm pools keep pre-initialized, stopped instances ready to start, which removes most of the boot time. The ECS agent needs ECS_WARM_POOLS_CHECK=true in its configuration so instances in the warm pool do not register with the cluster too early.
  • Scale the service earlier, with scheduled actions before known busy periods, so the capacity provider starts adding instances before users arrive.

Fargate skips the instance part entirely, which is why tasks there usually start within a minute or two; the trade-off is per-task pricing and fewer instance-level options.

Placement strategies and constraints that block tasks

Sometimes there is room in the cluster, just not room the task is allowed to use. Placement rules on the service decide where tasks may go:

  • Strategies choose among valid instances: binpack fills instances before using new ones (best for cost and scale-in), spread distributes across Availability Zones or instances (best for resilience), random does what it says.
  • Constraints rule instances out: distinctInstance allows one task per instance, and memberOf expressions restrict tasks to instances with certain attributes, such as an instance type or a custom attribute.

A constraint that no instance in the group can meet leaves tasks waiting forever, and managed scaling cannot help, because adding more of the same instances does not satisfy it. The service's Events message names the constraint that failed. The common combination for production is spread across Availability Zones first, then binpack on memory, which keeps resilience and still leaves instances empty enough to scale in.

"EMPTY CAPACITY PROVIDER" and "NO ACTIVE INSTANCES"

If you see one of these task failure reasons, read it from your cluster's point of view:

  • TaskFailedToStart: EMPTY CAPACITY PROVIDER: there are no instances in your cluster for this provider. Either the Auto Scaling group really has zero instances (and managed scaling is off, so nothing will add one), or the instances exist but are not registered with the cluster.
  • TaskFailedToStart: NO ACTIVE INSTANCES: the provider has instances, but none is active (for example all are draining or their agents are disconnected).

"I can see the instance running" with EMPTY CAPACITY PROVIDER means registration failed. An EC2 instance joins an ECS cluster when the ECS agent on it starts and calls ECS. Check these, in order:

  1. The cluster name in user data. The launch template's user data must set the cluster: echo ECS_CLUSTER=shop-staging >> /etc/ecs/ecs.config. Without it, the agent joins the cluster named default, which is exactly what happened in the shop's staging cluster after someone copied a launch template from production and edited the wrong line.
  2. An ECS-optimized AMI (or the agent installed yourself). A plain Amazon Linux or Ubuntu image has no agent.
  3. The instance role. The instance profile needs the AmazonEC2ContainerServiceforEC2Role managed policy (or equivalent) so the agent can register.
  4. A network path to ECS. Instances in private subnets need a NAT gateway or interface VPC endpoints for ecs, ecs-agent and ecs-telemetry (plus ECR and S3 endpoints to pull images).
  5. The agent log, if all of that looks right: connect with Session Manager and read /var/log/ecs/ecs-agent.log; registration errors are spelled out there.

If the group simply has zero instances and you expect managed scaling to start one, confirm managed scaling is on and the task uses a capacity provider strategy; ECS then scales from zero by launching two instances.

Capacity provider not scaling in

The opposite complaint, a group that grows but never shrinks, has its own short list:

  • Target capacity below 100 keeps spare room on purpose. If you set 80%, a cluster that needs four instances' worth of your tasks runs five. That is your setting working, not failing.
  • Spread placement leaves no empty instance. ECS only scales in when at least one instance can be emptied. A spread placement strategy across instances puts a task on every instance, so none is ever empty. Use binpack (on memory or CPU) as the first placement strategy, and if you also spread across Availability Zones, put binpack first when target capacity is below 100.
  • Managed termination protection is doing its job. With it on, instances running non-daemon tasks are protected from scale-in. They become unprotected only when their tasks finish or move. Long-running tasks scattered across instances can keep every instance protected.
  • Daemon services and long tasks. A task that never ends (a worker, a scheduled job that hangs) pins its instance. Find which instance runs what with aws ecs list-tasks --cluster shop --container-instance ARN.
  • The group's minimum size. ECS never goes below the group's min, whatever the metric says.

Managed draining, on by default for new Auto Scaling group capacity providers, makes ECS move tasks off an instance before the group terminates it, so scale-in does not kill running tasks abruptly. If you turned it off, scale-in can stop tasks mid-request.

Jake: "So it was keeping a spare machine because we told it to?"

Ethan: "At 80% target, yes. We pay for one idle instance so Monday morning starts in seconds instead of minutes. That's a choice, not a bug."

Capacity provider strategies: base and weight

In a strategy, you list your capacity providers with two numbers each:

  • base: the minimum number of tasks to run on this provider before weights apply. Only one provider in a strategy can have a base above zero.
  • weight: the relative share of the remaining tasks. A provider with weight 0 gets no tasks beyond its base.

Worked example: a service with 10 tasks and the strategy FARGATE base=2 weight=1, FARGATE_SPOT weight=3. The first 2 tasks go to Fargate (the base). The remaining 8 are split 1:3, so 2 more on Fargate and 6 on Fargate Spot. Result: 4 on regular Fargate, 6 on Spot, so even if every Spot task is interrupted, 4 keep serving.

Jake: "So base is the floor, and weight is how we split everything above it?"

Ethan: "Yes. Two tasks we can always count on, and the rest goes mostly to the cheap seats."

aws ecs update-service --cluster shop --service ticket-api \
  --capacity-provider-strategy capacityProvider=FARGATE,base=2,weight=1 capacityProvider=FARGATE_SPOT,weight=3 \
  --force-new-deployment

Two rules: a strategy can contain either Auto Scaling group providers or Fargate providers, not both; and all providers named must already be associated with the cluster. For EC2, the same pattern works with an On-Demand group and a Spot group as two capacity providers: base on On-Demand for the guaranteed minimum, weight toward Spot for the rest. Our guide to Spot interruptions covers handling the two-minute warning.

Service auto scaling vs cluster auto scaling

Two different things scale in an ECS-on-EC2 setup, and confusing them causes most "it's not scaling" reports:

Service auto scalingCluster auto scaling (capacity provider)
What it changesThe service's desired number of tasksThe number of EC2 instances in the Auto Scaling group
Driven byCPU, memory, request count or custom metrics (Application Auto Scaling)CapacityProviderReservation: do the tasks fit?
Configured onThe serviceThe capacity provider
Needed on Fargate?YesNo; Fargate supplies capacity per task
Typical failureWrong metric or limits; desired count never risesDesired count rises, tasks wait, no instances added

A quick way to tell which half is failing: if the service's desired count never rises during a spike, look at service auto scaling (its metric, limits and alarms). If the desired count rises but the running count lags behind with tasks in PROVISIONING, look at the capacity provider. The service's Events tab and its Desired and Running counts in the console show which side stalled in a few seconds.

Setting up ECS service auto scaling, step by step

Service auto scaling runs through Application Auto Scaling, and it takes two calls: register the service as something that can scale, then attach a policy. A target tracking policy on average CPU is the usual start:

# 1. Allow the service's desired count to move between 2 and 12
aws application-autoscaling register-scalable-target \
  --service-namespace ecs \
  --scalable-dimension ecs:service:DesiredCount \
  --resource-id service/shop/ticket-api \
  --min-capacity 2 --max-capacity 12

# 2. Keep average CPU across the service's tasks near 60%
aws application-autoscaling put-scaling-policy \
  --service-namespace ecs \
  --scalable-dimension ecs:service:DesiredCount \
  --resource-id service/shop/ticket-api \
  --policy-name cpu60 --policy-type TargetTrackingScaling \
  --target-tracking-scaling-policy-configuration '{
    "TargetValue": 60.0,
    "PredefinedMetricSpecification": {"PredefinedMetricType": "ECSServiceAverageCPUUtilization"},
    "ScaleOutCooldown": 60, "ScaleInCooldown": 300 }'

Three choices shape how it behaves:

  • The metric. ECSServiceAverageCPUUtilization and ECSServiceAverageMemoryUtilization work for most services. For web APIs behind an Application Load Balancer, ALBRequestCountPerTarget (requests per task) often reacts faster, because traffic rises before CPU does; it needs a resource label naming the load balancer and target group.
  • The cooldowns. A short scale-out cooldown and a longer scale-in cooldown add tasks quickly and remove them cautiously, which avoids flapping when traffic is spiky.
  • The limits. The minimum is your floor even at 3 a.m.; the maximum is your cost ceiling. On EC2, the capacity provider's group maximum has to be large enough to hold the service maximum, or the extra tasks will wait.

Scheduled scaling adds the predictable part: a scheduled action raising the minimum to six at 8:45 on weekdays gets capacity in place before the Monday rush instead of reacting to it. In the console, all of this is on the service's Service auto scaling settings, and Terraform uses aws_appautoscaling_target and aws_appautoscaling_policy.

They work as a chain: service auto scaling decides "we need eight tasks"; the capacity provider decides "eight tasks need three instances"; the Auto Scaling group launches them. If you only set up the first, tasks wait for room. If you only set up the second, the cluster is sized for a task count that never changes. Our Auto Scaling explainer covers the Application Auto Scaling policies used on the service side.

Setting it up: console, CLI and Terraform

In the console, creating a new cluster with EC2 capacity creates the Auto Scaling group and capacity provider for you. For an existing group, open the cluster, choose Infrastructure, Create capacity provider, pick the group, turn on managed scaling with a target capacity, and decide on termination protection.

With the CLI:

# Scale-in protection on new instances is required for managed termination protection
aws autoscaling update-auto-scaling-group --auto-scaling-group-name shop-ecs-asg \
  --new-instances-protected-from-scale-in

aws ecs create-capacity-provider --name shop-asg-cp \
  --auto-scaling-group-provider "autoScalingGroupArn=arn:aws:autoscaling:us-east-1:111122223333:autoScalingGroup:1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d:autoScalingGroupName/shop-ecs-asg,managedScaling={status=ENABLED,targetCapacity=90,minimumScalingStepSize=1,maximumScalingStepSize=4,instanceWarmupPeriod=180},managedTerminationProtection=ENABLED"

# This call REPLACES the cluster's provider list: include every provider you keep
aws ecs put-cluster-capacity-providers --cluster shop \
  --capacity-providers shop-asg-cp \
  --default-capacity-provider-strategy capacityProvider=shop-asg-cp,weight=1

The person creating the provider needs autoscaling:CreateOrUpdateTags, because ECS tags the group with AmazonECSManaged. ECS uses its service-linked role, AWSServiceRoleForECS, to manage the group afterwards.

Terraform:

resource "aws_ecs_capacity_provider" "asg" {
  name = "shop-asg-cp"
  auto_scaling_group_provider {
    auto_scaling_group_arn         = aws_autoscaling_group.ecs.arn
    managed_termination_protection = "ENABLED"
    managed_scaling {
      status                    = "ENABLED"
      target_capacity           = 90
      minimum_scaling_step_size = 1
      maximum_scaling_step_size = 4
      instance_warmup_period    = 180
    }
  }
}

resource "aws_ecs_cluster_capacity_providers" "shop" {
  cluster_name       = aws_ecs_cluster.shop.name
  capacity_providers = [aws_ecs_capacity_provider.asg.name]
  default_capacity_provider_strategy {
    capacity_provider = aws_ecs_capacity_provider.asg.name
    weight            = 1
  }
}

On the aws_autoscaling_group, set protect_from_scale_in = true (needed for managed termination protection) and add lifecycle { ignore_changes = [desired_capacity] }, because ECS changes desired capacity and Terraform would otherwise try to set it back on every apply. Keep the AmazonECSManaged tag in the group's tags too, so Terraform does not remove it.

Moving a service from a launch type to a strategy: update the service with --capacity-provider-strategy and --force-new-deployment, as in the base-and-weight example. In Terraform, replace launch_type with a capacity_provider_strategy block on the aws_ecs_service.

Several instance types and Spot inside one group

One Auto Scaling group can hold several instance types, and a mix of On-Demand and Spot, through a mixed instances policy. The capacity provider sees it as one pool. This is the simplest way to cut cost and dodge "insufficient capacity" for a single instance type:

  • Pick types of similar size. If the group holds both 2-vCPU and 8-vCPU instances, ECS's estimate of how many instances a set of tasks needs becomes less exact, and you get either waiting tasks or idle room. Types with the same vCPU and memory, from different families or generations, behave best.
  • Let the group choose Spot pools wisely. The price-capacity-optimized allocation strategy picks the Spot pools least likely to be interrupted, and capacity rebalancing replaces Spot instances that receive a rebalance notice before they are reclaimed.
  • Keep an On-Demand floor. The policy's On-Demand base capacity guarantees a number of On-Demand instances no matter what happens to Spot.

The alternative is the two-provider pattern from the strategy section: one group for On-Demand, one for Spot, with base and weight deciding where tasks go. Two groups give clearer control over which tasks may run on Spot; one mixed group is simpler to run. Small clusters usually start with the mixed group.

ECS Managed Instances: EC2 capacity without managing instances

ECS Managed Instances is the newest capacity provider type, between EC2 and Fargate. AWS provisions, configures, patches and replaces the EC2 instances in your account, choosing types that fit your tasks or following attributes you set (CPU architecture, minimum memory, GPU and so on), while your tasks still get the flexibility of EC2: GPUs, larger sizes, several tasks per instance.

For the scaling problems on this page, the attraction is that there is no Auto Scaling group to misconfigure: no launch template with the wrong cluster name, no maximum size to forget, no AMI to keep current. You pay for two things: the EC2 instances at normal prices, where Savings Plans, Reserved Instances and Spot still apply, plus a management fee per instance, billed per second. In July 2026 AWS cut that fee for GPU instance families, by 35% for G-series and 60% for P-series and Trainium, which makes it more attractive for GPU work than it was at launch.

For a small team like Jake's, the honest comparison is Fargate for simple services, Managed Instances when tasks need EC2 features, and a self-managed group only when you need something neither offers.

Limits and quotas that quietly stop scaling

When everything on the checklist looks right and scaling still stops at a ceiling, the ceiling is often a quota rather than a setting:

  • EC2 vCPU quotas per Region and instance family limit how many instances the group can launch; the group's Activity history shows the failure. Our vCPU limit guide covers requesting more.
  • Fargate quotas count vCPUs of running Fargate and Fargate Spot tasks per Region, separately. A burst that needs more simply leaves tasks waiting.
  • ECS service quotas cap things such as tasks per service, services per cluster and container instances per cluster. They are high, but a busy batch platform can meet them.
  • Subnet IP addresses. With awsvpc networking every task takes an IP address from the subnet, so a small subnet runs out long before any AWS quota does.

The Service Quotas console lists current values and usage for ECS, Fargate and EC2 in one place, and CloudWatch alarms on quota usage warn you at, say, 80% before the next spike hits the wall.

What capacity providers cost, and the price of spare room

Capacity providers and managed scaling are free; you pay for the compute they create. The settings on this page mostly decide how much of it sits idle:

  • Target capacity is a direct cost dial. At 100, almost nothing is idle but new tasks wait. At 80, roughly a fifth of your instance capacity is spare by design. Pick the lowest number your users will not notice, and revisit it once you have a few weeks of metrics.
  • Scale-in behavior matters as much as scale-out. A cluster that grows on Monday and never shrinks (spread placement, long-running tasks) pays Monday prices all week.
  • Spot, as a second capacity provider or in a mixed group, can cut instance costs by a large fraction for tasks that tolerate interruption. Keep an On-Demand base for anything that must stay up.
  • Savings Plans cover a steady baseline of EC2 or Fargate usage at a discount, whichever capacity provider runs it, which suits the floor set by your service minimums.

For the shop, moving from a fixed eight-instance cluster to managed scaling at target 90 with binpack cut the monthly instance bill by about a third: most of the week the cluster runs four or five instances, and Monday mornings briefly run seven.

Jake: "So we were paying for Monday morning all week?"

Ethan: "Seven days of Monday. Now it's Monday on Monday and a smaller cluster the rest of the time."

Watching for the next scaling problem

The shop found its Monday problem from user complaints. Two signals would have found it first:

  • Waiting tasks. With CloudWatch Container Insights turned on for the cluster, services report running and pending task counts. An alarm on pending tasks above zero for more than ten minutes catches every "not scaling out" cause on this page, whatever the reason.
  • Task failures to start. ECS sends task state change events to EventBridge, and a stopped task's reason carries messages such as EMPTY CAPACITY PROVIDER or RESOURCE:MEMORY. A rule matching those reasons and sending them to an SNS topic turns a silent failure into an email within a minute.

Add the CapacityProviderReservation metric to the same dashboard, and you can see at a glance whether the cluster is short of room, about right, or carrying too much spare capacity, which is the whole story of this page on one graph.

Checklist for a new ECS cluster on EC2

  1. Launch template with an ECS-optimized AMI, the right ECS_CLUSTER in user data, and an instance role with the ECS policy.
  2. Auto Scaling group with sensible min and max, scale-in protection for new instances, and no other scaling policies.
  3. Capacity provider with managed scaling (target 90 to 100), managed termination protection and managed draining.
  4. The provider attached to the cluster as the default strategy, with every service using a strategy rather than a launch type.
  5. Service auto scaling on each service, with limits that fit inside the group's maximum.
  6. Placement: spread across Availability Zones, then binpack.
  7. Alarms on the reservation metric and on tasks waiting in PROVISIONING for too long.

Seven items, and every failure described on this page is one of them skipped.

Keep the checklist with the cluster's infrastructure code, and review it whenever someone copies a launch template, adds a service by hand, or changes the group's limits. Those three moments are where every one of the shop's scaling problems started, and none of them looked risky at the time.

Fargate and Fargate Spot capacity providers

With Fargate you manage no instances, so there is no cluster scaling for you to debug: each of your tasks gets its own capacity. To use the providers, you associate them with your cluster and name them in a strategy:

aws ecs put-cluster-capacity-providers --cluster shop \
  --capacity-providers FARGATE FARGATE_SPOT \
  --default-capacity-provider-strategy capacityProvider=FARGATE,base=1,weight=1 capacityProvider=FARGATE_SPOT,weight=3

What can still go wrong: Fargate Spot capacity is not always available, and Spot tasks get a two-minute warning (a SIGTERM) before interruption, so your containers should shut down cleanly. The service replaces interrupted tasks automatically. For the cost trade-off between EC2 capacity and Fargate, our ECS on EC2 vs Fargate cost guide runs the numbers. Tasks that start and then die are a different problem; our guides to failed health checks and exit code 137 cover the common ones.

Frequently asked questions

What is an ECS capacity provider?

A named source of compute for an ECS cluster: an EC2 Auto Scaling group that ECS can scale, or the built-in FARGATE and FARGATE_SPOT providers.

Why is my ECS capacity provider not scaling out?

Usually the service uses a launch type instead of a capacity provider strategy, managed scaling is off, the group's max size is reached, or new instances do not register with the cluster.

What does EMPTY CAPACITY PROVIDER mean in ECS?

The cluster has no registered instances for that capacity provider: the group is empty, or its instances never joined the cluster.

What is CapacityProviderReservation?

The metric ECS uses for managed scaling: instances needed divided by instances running, times 100. ECS scales the group to keep it at your target capacity.

What target capacity should I use?

100 keeps instances fully used but new tasks wait during scale-out; a lower value such as 80 to 90 keeps spare room so tasks start at once.

What is the difference between base and weight?

Base is the minimum number of tasks placed on a provider first; weight is the relative share of the remaining tasks.

What is the difference between a capacity provider and a launch type?

A launch type places tasks only on existing capacity; a capacity provider strategy can trigger managed scaling and split tasks across providers.

Do I need both service auto scaling and a capacity provider?

On EC2, yes: service auto scaling changes the number of tasks, and the capacity provider adds instances so those tasks fit.

Why is my ECS cluster not scaling in?

Target capacity below 100 keeps spare room, spread placement leaves no empty instance, or managed termination protection protects instances still running tasks.

What is managed termination protection?

An option that stops the Auto Scaling group from terminating instances that still run non-daemon tasks. It requires scale-in protection on new instances.

Why are my instances not registering with the ECS cluster?

Missing ECS_CLUSTER in user data, an AMI without the ECS agent, an instance role without ECS permissions, or no network path to ECS.

Can I mix Fargate and EC2 capacity providers in one strategy?

No. A strategy contains either Auto Scaling group providers or Fargate providers.

Can a capacity provider be used by more than one cluster?

Not with managed scaling on; then it belongs to one cluster. Without managed scaling it can be associated with several.

How do I switch an ECS service from a launch type to a capacity provider?

Run update-service with --capacity-provider-strategy and --force-new-deployment.

Why do my tasks stay in PROVISIONING?

They are waiting for capacity from the provider. If no instances arrive, check the group's max size, its launch activity and instance registration.

Does put-cluster-capacity-providers keep existing providers?

No. It replaces the cluster's whole list, so include every provider you want to keep.

How do I set up ECS service auto scaling?

Register the service with application-autoscaling register-scalable-target (ecs:service:DesiredCount), then add a target tracking policy such as ECSServiceAverageCPUUtilization at 60%.

What is the difference between an ECS cluster and an ECS service?

A service keeps a desired number of tasks running; a cluster groups services and tasks with the capacity providers that supply their compute.

Why not just scale the Auto Scaling group on CPU?

Waiting tasks use no CPU, so a CPU policy cannot see them. Managed scaling counts running and waiting tasks.

Can one ECS Auto Scaling group mix instance types and Spot?

Yes, with a mixed instances policy. Keep instance types of similar size so ECS estimates capacity accurately.

What is ECS Managed Instances?

A capacity provider where AWS provisions and patches EC2 instances for your tasks. You pay EC2 prices plus a per-instance management fee.

Which quotas can stop ECS from scaling?

EC2 vCPU quotas, Fargate vCPU quotas, ECS service quotas, and free IP addresses in the subnets used by awsvpc tasks.

How do I get alerted when ECS tasks cannot start?

Alarm on pending tasks with Container Insights, and add an EventBridge rule for task state changes whose stopped reason mentions capacity or resources.

Is ECS Managed Instances cheaper than Fargate?

It depends on the workload. You pay EC2 prices plus a management fee, which can beat Fargate for large or GPU tasks packed several per instance.

What does ECS_WARM_POOLS_CHECK do?

It makes the ECS agent wait until an instance leaves the Auto Scaling warm pool before registering, so warm instances do not join the cluster early.

Do ECS capacity providers cost extra?

No. You pay for the EC2 instances or Fargate tasks they run. Target capacity below 100 adds idle capacity you pay for.

What should a new ECS cluster on EC2 include?

A correct launch template, an Auto Scaling group with no other policies, a managed-scaling capacity provider as the default strategy, and service auto scaling.

How long does ECS take to scale out on EC2?

Usually three to six minutes from waiting tasks to running tasks: metric, alarm, instance launch, agent registration, image pull.

How do I make ECS scale out faster?

Keep spare room with a target capacity below 100, use smaller images, add an EC2 warm pool, and schedule scale-ups before known peaks.

Why can't ECS place my task when there is free capacity?

A placement constraint such as distinctInstance or a memberOf expression rules out the instances. The service's Events tab names it.

Which placement strategy helps scale-in?

binpack, which fills instances before using new ones, so some instances become empty and can be removed.

Which metric is best for ECS service auto scaling?

CPU or memory for most services; ALBRequestCountPerTarget for web APIs behind a load balancer, since requests rise before CPU.

How do I set up an ECS capacity provider in Terraform?

Use aws_ecs_capacity_provider with managed_scaling, aws_ecs_cluster_capacity_providers, and ignore desired_capacity changes on the Auto Scaling group.

For readers preparing for an AWS certification

We have been covering AWS certifications alongside our fixes, so here is a short extra for readers studying for one. If you only came for the fix, you already have it; feel free to skip this part.

Exams that test this topic: CloudOps Engineer – Associate (SOA-C03) • Developer – Associate (DVA-C03 from December 1, 2026) • Solutions Architect – Associate (SAA-C03).

Here are the exam-style questions this topic tends to raise, with the reasoning you need to answer them:

1. ECS service auto scaling raises the desired task count, but the EC2 Auto Scaling group never adds instances. What is a likely cause?

The service uses a launch type instead of a capacity provider strategy, so waiting tasks do not trigger managed scaling.

2. Which metric does ECS managed scaling use to size an Auto Scaling group capacity provider?

CapacityProviderReservation, kept at the configured target capacity.

3. A task fails with TaskFailedToStart: EMPTY CAPACITY PROVIDER although EC2 instances are running. What should you check?

Whether the instances registered with the cluster: ECS_CLUSTER in user data, the ECS agent, the instance role and network access to ECS.

4. A service must always run 2 tasks on Fargate and place the rest mostly on Fargate Spot. How?

A capacity provider strategy with FARGATE base=2 and a higher weight on FARGATE_SPOT.

5. What does managed termination protection require on the Auto Scaling group?

Instance scale-in protection on new instances, with managed scaling turned on.

6. Why might an ECS cluster on EC2 never scale in?

Spread placement leaves no empty instance, target capacity below 100 keeps spare room, or protected instances still run tasks.

7. What is the difference between ECS service auto scaling and cluster auto scaling?

Service auto scaling changes the number of tasks; cluster auto scaling (capacity providers) changes the number of EC2 instances.

Exam codes and dates change often. Our AWS certification changes page keeps track of what is current.

πŸ“š ALSO READ

Where to go next, from failing health checks to EC2 capacity limits:

📌 Bookmark this; the not-scaling checklist and the strategy examples are the parts you will come back for.

The next Monday, the ticketing service asked for eight tasks at 9:02, the capacity provider added two instances by 9:06, and all eight tasks were running before the morning queue built up. Staging's scheduled job runs again too, on an instance that now registers with the right cluster. Jake wrote the lesson on the team board in two lines: "Service scaling = how many tasks. Capacity provider = how many machines. You need both."

📌 If you keep one line from this page

Use a capacity provider strategy (not a launch type) so waiting tasks trigger managed scaling, keep the Auto Scaling group's max size above what you need, make sure new instances register with the right cluster, and pair it with service auto scaling.

EMPTY CAPACITY PROVIDER = no registered instances · binpack for scale-in · base first, then weight.

Revision note. Written October 19, 2026. Asking for more tasks and asking for more machines are two different requests; a capacity provider is what connects them.

Related