The most surprising thing about mixing On-Demand and Spot capacity in ECS is that you can often achieve significant cost savings without sacrificing reliability, even with a substantial portion of your workload on Spot.

Let’s see this in action. Imagine you have an ECS service running a web application. Your desired count is 10 tasks. You’ve configured your ECS Capacity Provider Strategy to use a mix of On-Demand and Spot.

{
  "capacityProviderStrategy": [
    {
      "capacityProvider": "my-on-demand-capacity-provider",
      "weight": 1,
      "base": 1
    },
    {
      "capacityProvider": "my-spot-capacity-provider",
      "weight": 3,
      "base": 0
    }
  ]
}

Here, my-on-demand-capacity-provider has a weight of 1 and a base of 1. This means ECS will always try to maintain at least 1 On-Demand instance for this service. my-spot-capacity-provider has a weight of 3 and a base of 0. The weights dictate the proportion of capacity ECS will try to provision from each provider after the base requirements are met. With a 1:3 ratio, for every 1 On-Demand instance ECS provisions (beyond the base), it will attempt to provision 3 Spot instances. If your desired count is 10 tasks and you have 1 On-Demand instance provisioned (the base), ECS will then try to provision 9 more tasks. It will allocate these 9 tasks proportionally based on the weights, aiming for roughly 2 On-Demand and 7 Spot instances. The base ensures that even if the weights suggest zero instances for a provider, a minimum number will still be launched.

This strategy solves the problem of balancing cost optimization with application availability. On-Demand instances provide a stable, predictable baseline, ensuring your core services are always running. Spot instances, on the other hand, offer massive cost savings (up to 90% off On-Demand prices) but can be interrupted with short notice. By combining them, you get the best of both worlds: a guaranteed minimum capacity and the ability to leverage cheap, interruptible capacity for the bulk of your workload.

Internally, ECS uses the capacityProviderStrategy to inform its Auto Scaling logic. When your service needs more tasks, ECS looks at the strategy. It first satisfies any base requirements from the specified capacity providers. Then, it calculates the total desired capacity (sum of base + any additional capacity needed). It then distributes this total desired capacity among the providers based on their weight. The weight is a relative value; ECS normalizes these weights to determine the proportion. So, with weights 1 and 3, the total weight is 4. On-Demand gets 1/4 of the additional capacity, and Spot gets 3/4. The base values are absolute minimums. If your base for On-Demand is 1 and base for Spot is 0, and you need 10 tasks, ECS will first ensure 1 On-Demand instance is running. Then it needs 9 more. It allocates these 9 based on weights: 1/4 of 9 (approx 2) to On-Demand, and 3/4 of 9 (approx 7) to Spot. This results in approximately 3 On-Demand and 7 Spot instances.

The key levers you control are the weight and base for each capacity provider. The weight dictates the proportion of capacity ECS will attempt to provision from each provider after the base is met. A higher weight means ECS will try to provision more capacity from that provider. The base is the minimum number of instances ECS will ensure are provisioned from that provider for the service. Setting a base of 0 means ECS is not obligated to provision any instances from that provider if the weights don’t dictate it.

When your Spot instances get interrupted, ECS will automatically try to re-provision those tasks onto available Spot capacity. If Spot capacity is scarce or unavailable, and you have On-Demand capacity available (either from the base or provisioned due to weights), ECS will attempt to place the interrupted tasks there. This is where the base for On-Demand becomes critical for resilience.

The base value is applied per service. If you have multiple services using the same capacity provider strategy, each service will independently try to meet its base requirement. This means if you have 5 services each with a base of 1 On-Demand instance, you’ll have at least 5 On-Demand instances running, even if your total workload is small.

The next concept you’ll run into is how to dynamically adjust these weights and bases based on fluctuating Spot prices and your application’s tolerance for interruption.

Want structured learning?

Take the full Ecs course →