Non-production ECS services idle on a repeating weekly pattern that can scale to zero off-hours
What does ZopNight detect here?
ZopNight studies CPU and memory for each non-production ECS service, finds the hours idle in the same slots every week and proposes a cron that sets the desired task count to zero during them. The saving is the service's measured monthly cost times the share of hours the cron removes, and fully idle services are left to other rules.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-046 |
| Category | schedule |
| Severity | medium |
| Metric | CPUUtilization, MemoryUtilization (AWS/ECS) |
| Threshold | repeating idle window, idle share < 95% |
| Source | ZopNight |
| Permissions used | ecs:ListServices · ecs:DescribeServices · cloudwatch:GetMetricData |
Where it applies
Tasks bill for as long as they run
On Fargate, the pricing page says charges cover the vCPU, memory and storage used from the time a task starts downloading its image until it stops, rounded up to the nearest second. An ECS service holds its desired count of tasks at all times, so a staging API set to three tasks runs three tasks through every night and weekend. On the EC2 launch type, those tasks keep container instances busy that could otherwise scale in.
Looking at a service’s week
aws ecs list-services --cluster dev-cluster
aws ecs describe-services --cluster dev-cluster --services api \ --query 'services[].[serviceName,desiredCount,runningCount,launchType]'
aws cloudwatch get-metric-statistics --namespace AWS/ECS --metric-name CPUUtilization \ --dimensions Name=ClusterName,Value=dev-cluster Name=ServiceName,Value=api \ --start-time 2026-09-04T00:00:00Z --end-time 2026-09-25T00:00:00Z \ --period 3600 --statistics AveragePlot the hourly averages by weekday; the same quiet block every week is the schedule candidate.
What the service needs for a finding
- It is an ECS service not named or tagged as production.
- ZopNight has built its weekly pattern. An hour is idle only when every metric it tracks for the service, CPU and memory among them, is below the idle line.
- The pattern yields a start and a stop time.
- The service has a measured monthly cost. ECS has no instance rate to look up, so ZopNight uses the service’s own recorded daily cost.
Services that are not scheduled
A service idle 95% or more of the week is a scale-to-zero case rather than a schedule, handled by Running ECS Service Idle, No Traffic. Services with no pattern, no cron window or no priced cost produce nothing, and the rule never uses a fixed nights-and-weekends guess. Existing cloud schedule tags do not block it, because ZopNight manages the schedule itself.
Removed hours times the service cost
saving = monthly service cost x share of running hours outside the cron windowWhere ZopNight has a per-running-hour rate for the service, it prices the removed hours at that rate, capped at the monthly cost.
Scheduling the service
- Review the suggested start and stop cron and the time zone in the recommendation.
- Apply it from ZopNight, which sets the service’s desired count on that schedule and restores it before the working day.
- To do it with AWS tooling instead, register the service with Application Auto Scaling and add scheduled actions that set minimum and maximum capacity to 0 in the evening and back in the morning:
aws application-autoscaling put-scheduled-action --service-namespace ecs \ --resource-id service/dev-cluster/api --scalable-dimension ecs:service:DesiredCount \ --scheduled-action-name api-night --schedule "cron(0 20 ? * MON-FRI *)" \ --scalable-target-action MinCapacity=0,MaxCapacity=0