# Running ECS Service Idle. No Traffic

> Flags running ECS services with no load balancer traffic and idle CPU and memory for 30 days; saving is the full run-rate.

Source: https://zop.dev/integrations/aws/recommendations/running-ecs-service-idle-no-traffic

---

## Running tasks bill for their CPU and memory, traffic or not

With [AWS Fargate](https://aws.amazon.com/fargate/pricing/) you pay for the vCPU, memory and
storage your tasks consume while they run. On the EC2 launch type the tasks occupy container
instances you pay for by the hour. Either way, a service with a desired count of two keeps two
tasks alive around the clock, even if no request has reached it in weeks.

This is the running counterpart to
<a href="https://zop.dev/integrations/aws/recommendations/ecs-idle-service">ECS Idle Service</a>, which covers
services already scaled to zero.

## Confirming a service gets no requests

Find the service's target group, then look at `RequestCountPerTarget`. The
[ALB metrics reference](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-cloudwatch-metrics.html)
says this metric takes the `TargetGroup` dimension on its own and is the target group's requests
divided by its healthy targets:

```bash
aws ecs describe-services --cluster my-cluster --services my-service \
  --query 'services[].[desiredCount,runningCount,loadBalancers[].targetGroupArn]'

aws cloudwatch get-metric-statistics \
  --namespace AWS/ApplicationELB --metric-name RequestCountPerTarget \
  --dimensions Name=TargetGroup,Value=targetgroup/my-tg/0123456789abcdef \
  --start-time 2026-08-26T00:00:00Z --end-time 2026-09-25T00:00:00Z \
  --period 86400 --statistics Sum
```

Check the service's `CPUUtilization` and `MemoryUtilization` in `AWS/ECS` as well.

## No traffic and no background work

The service must have a desired count and a running count of at least 1. Its request series must
cover 30 days and stay at or below 1 on both average and peak. Then comes the compute gate, which
exists because plenty of services take no HTTP traffic yet do real work: queue consumers, workers,
scheduled batch jobs. Over the same 30 days, CPU must average no more than 5% and peak no higher
than 20%, and memory must average no more than 20% and peak no higher than 40%. Finally the service
needs a priced cost.

## Services this check cannot see

A worker with no load balancer has no request series, and a service behind a Network Load Balancer
has no request count to read, so neither produces a finding. Missing CPU or memory data, less than
30 days of any series, or no price also means silence. The check never uses tags or names to decide
a service is idle.

## Saving the full run-rate

```text
saving = measured monthly cost of the service's running tasks
cost after fix = 0 (scaled to zero or deleted)
```

## Scaling down a service nobody calls

1. Confirm in the target group metrics that no client reaches it, and ask the owning team about
   internal or scheduled callers.
2. Scale it to zero: `aws ecs update-service --cluster my-cluster --service my-service --desired-count 0`.
3. If it is abandoned, delete it with `aws ecs delete-service --cluster my-cluster --service my-service --force`.
4. Remove the listener rule and target group that pointed at it.

**Note**
Scaling to zero keeps the service definition, so it can be restored by setting the desired
count back.
