AWSAmazon ECSContainers

aws_ecs_service cost estimation

A long-running ECS service. Cost depends on launch type: EC2 (pay for nodes), Fargate (pay per task vCPU/memory), or Fargate Spot.

An aws_ecs_service runs and maintains a desired count of ECS task instances. The service resource itself is free; cost comes from the compute used to run the tasks.

ECS supports three launch types with very different cost profiles:

EC2 launch type: tasks run on EC2 instances you manage (registered to an ECS cluster). You pay regular EC2 prices for the instances plus EBS for any volumes. Higher operational burden but lowest cost per unit of compute. Right when you can keep node utilization high.

Fargate launch type: AWS provisions per-task compute. You pay per task by requested vCPU and memory. Per-vCPU-hour rates are higher than equivalent on-demand EC2, but you only pay for what tasks actually use. Right for unpredictable, low-utilization, or simple workloads.

Fargate Spot: same as Fargate but with up-to-70%-off pricing for fault-tolerant workloads. Tasks can be interrupted with 2-minute notice. Excellent for batch jobs and stateless services.

The service's desired_count determines how many tasks run continuously. A service with desired_count = 5 and a Fargate task definition requesting 1 vCPU + 2 GB memory pays 5 × (1 vCPU + 2 GB) continuously.

Additional costs for ECS services typically include: load balancers (each Service usually has an aws_lb), CloudWatch logs (each task logs separately), and any persistent storage attached to tasks (rare).

c3x reads the linked task definition's cpu and memory and the desired_count. For autoscaling services, average count comes from c3x-usage.yml.

Terraform example

A minimal but realistic configuration that C3X can estimate.

resource "aws_ecs_cluster" "main" {
  name = "production"
}

resource "aws_ecs_task_definition" "api" {
  family                   = "api"
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  cpu                      = 1024
  memory                   = 2048
  execution_role_arn       = aws_iam_role.ecs_execution.arn

  container_definitions = jsonencode([{
    name      = "api"
    image     = "my-org/api:v1.2.3"
    essential = true
    portMappings = [{
      containerPort = 8080
    }]
  }])
}

resource "aws_ecs_service" "api" {
  name            = "api"
  cluster         = aws_ecs_cluster.main.id
  task_definition = aws_ecs_task_definition.api.arn
  desired_count   = 3
  launch_type     = "FARGATE"

  network_configuration {
    subnets         = aws_subnet.private[*].id
    security_groups = [aws_security_group.tasks.id]
  }
}

Pricing dimensions

What you actually pay for when you provision aws_ecs_service.

DimensionUnitWhat's being charged
Fargate vCPU-hoursper vCPU-hourPer-task vCPU as specified in the task definition. Billed continuously while tasks run.
$0.04048/vCPU-hour in us-east-1
Fargate memory-hoursper GB-hourPer-task memory as specified in the task definition.
$0.004445/GB-hour
Fargate Spotper vCPU-hour and per GB-hourSame dimensions as Fargate but discounted up to 70% with interruption risk.
EC2 launch typeper instance hourTasks run on EC2 instances. Standard EC2 pricing applies. Costs estimated via aws_instance.

Optimization tips

Common ways to reduce aws_ecs_service cost without changing the workload.

Use Fargate Spot for stateless and batch tasks

70%

Spot is 70% cheaper than regular Fargate. Right for stateless workers, async job processors, CI runners, and any task that tolerates 2-minute eviction warnings.

Use Compute Savings Plans for steady Fargate workloads

27-52%

Fargate is covered by Compute Savings Plans. A 1-year commitment cuts Fargate prices by 27%, 3-year by 52%. Better than reserved instances for variable task definitions.

Right-size CPU and memory requests

30-75% on overprovisioned tasks

Fargate bills by requested CPU and memory. A task requesting 2 vCPU + 4 GB but actually using 0.5 vCPU + 1 GB pays 4x what it needs. Profile and shrink.

EC2 launch type for high-utilization steady workloads

40-60% on high-utilization workloads

If you can keep a cluster of nodes >70% utilized, EC2 launch type with reserved instances is significantly cheaper than Fargate. Crossover is workload-dependent.

FAQ

Fargate or EC2 launch type, which is cheaper?

Depends on utilization. EC2 launch type is cheaper per vCPU-hour but you pay for the whole instance regardless of how many tasks fit. Fargate is cheaper if your tasks don't fit cleanly into instance sizes or if you have spiky workloads. Crossover is typically around 50-70% sustained utilization.

Does c3x estimate Fargate based on task definition CPU/memory?

Yes. c3x reads the linked aws_ecs_task_definition's cpu and memory values, applies Fargate's rounding rules (CPU rounded to nearest 0.25 vCPU, memory to nearest 1 GB), and multiplies by desired_count.

What about ECS on EC2 Spot?

EC2 launch type with Spot capacity providers offers ~70% savings on the underlying instances. The ECS service still pays for the EC2 instances, just at Spot prices. Configure via capacity_provider_strategy.

Are load balancers included in ECS estimates?

No. Load balancers are separate resources (aws_lb) estimated independently. Most ECS services use an ALB or NLB. c3x estimates the ALB at its own page-line item.

Related resources

Estimate this resource in your own Terraform

Free, open source, no API key. C3X parses your Terraform and shows line-item cost for every resource, including aws_ecs_service.