ECS Auto Scaling for Startups: How to Stop Paying for Idle Containers (And Stop Dropping Requests)
ECS auto scaling automatically adjusts how many containers (tasks) your service runs based on actual traffic. When load goes up, ECS adds tasks. When traffic drops, it removes them. You pay for what you use, and you don't have to pre-provision for peak traffic all the time.
If you've been running a fixed number of containers โ say, always 3 tasks โ you've been doing one of two things: overpaying during quiet periods, or dropping requests during traffic spikes. Auto scaling fixes both.
Why This Matters More Than You Think
Here's the failure mode that hits most startups moving from Railway to AWS: Railway scales automatically for you, behind the scenes. You move to ECS, you spin up 2โ3 tasks, and that's it. Static. Your app handles 10x normal traffic on a Tuesday for some reason, your tasks max out, latency spikes, requests start timing out. Nobody told you you needed to configure auto scaling separately.
This isn't a flaw in ECS โ it's deliberate. ECS gives you full control. Auto scaling is opt-in, which means you have to set it up. The upside: when you do set it up correctly, you get very predictable scaling behavior that you can tune to your actual traffic pattern. The downside: there are three different scaling methods and a bunch of CloudWatch configuration to get through before anything works.
This guide explains what each method actually does and when to use it. At the end, I'll show you how NoahOps handles all of this without you writing AWS CLI commands.
What ECS Auto Scaling Actually Does
ECS uses a service called Application Auto Scaling to manage task count. You define a minimum and maximum task count for your service, then create scaling policies that add or remove tasks based on metrics. ECS never goes below your minimum or above your maximum.
The metrics come from CloudWatch. ECS and ALB automatically publish metrics like CPU utilization, memory utilization, and request count per target. You create policies that say "if this metric crosses this threshold, change task count by this amount."
There are three types of scaling policies:
- Target tracking โ you pick a target value for a metric, and auto scaling figures out how many tasks you need to maintain that target
- Step scaling โ you define specific thresholds with specific scaling actions for each
- Scheduled scaling โ you pre-set capacity changes on a time schedule
Most startups should start with target tracking. It's the simplest to configure and handles the majority of normal traffic patterns well.
Target Tracking: The Right Default
Target tracking is the closest thing ECS has to "set it and forget it." You pick a metric and a target value. Auto scaling continuously compares the current metric value to your target and adds or removes tasks to maintain it.
The three built-in metrics that work well for target tracking:
CPU utilization โ most common. Set a target of 60โ70%. If your service averages above that, ECS adds a task. If it's well below, ECS removes one (after a cooldown period). Works for most API services and background workers.
Memory utilization โ use this for memory-intensive services (image processing, ML inference, data transformation). Similar logic to CPU.
ALB request count per target โ often the best metric for web-facing services. This measures requests per task, not per service. If you're handling 1,000 requests per minute across 2 tasks (500 each), and you set a target of 400 requests per task, ECS will scale to 3 tasks. This scales based on actual work, not just resource consumption.
The key parameters in a target tracking policy:
- Scale-out cooldown โ how long to wait after scaling out before scaling out again. Keep this short (30โ60 seconds) so you respond quickly to traffic spikes.
- Scale-in cooldown โ how long to wait before removing tasks. Keep this longer (300 seconds or more) to avoid oscillation where you add and remove tasks repeatedly.
Step Scaling: When You Need More Control
Step scaling lets you define different scaling responses at different thresholds. For example:
- CPU between 70โ90%: add 2 tasks
- CPU above 90%: add 4 tasks
- CPU below 30% (for 5 minutes): remove 1 task
This is useful if your traffic spikes suddenly and aggressively โ like a flash sale, a newsletter drop, or a scheduled batch job. Target tracking is reactive by design; it catches up smoothly but doesn't always add capacity fast enough for sudden spikes. Step scaling lets you be more aggressive at high thresholds.
Step scaling requires you to create CloudWatch alarms manually and link them to the scaling policy. More configuration, more control. For most startups, target tracking is sufficient unless you've observed that smooth scaling is costing you requests during sudden spikes.
Scheduled Scaling: For Predictable Traffic Patterns
If your traffic is predictable โ business hours are high, overnight is low, Monday morning is always a spike โ scheduled scaling lets you pre-position capacity before traffic actually arrives. This is faster than reactive scaling because you're not waiting for a metric to breach a threshold.
Scheduled scaling works alongside target tracking. You set the minimum and maximum capacity for a time window, and target tracking handles fine-grained adjustment within that window.
Examples of when scheduled scaling makes sense:
- Your product is B2B, used 9amโ6pm weekdays. Scale up to 5 tasks at 8:45am. Scale down to 2 at 6:15pm.
- You send a weekly email newsletter every Thursday at noon. Pre-scale at 11:45am to handle the traffic burst.
- You run nightly batch processing. Scale up worker tasks at 11pm, scale down at 3am.
The Setup You Actually Need
A minimal production auto scaling setup for a web API on ECS Fargate looks like this:
- Register the service as a scalable target (set min and max task count)
- Create a target tracking policy on CPU utilization at 60%
- Create a second target tracking policy on ALB request count per target
- If you have predictable traffic patterns, add scheduled scaling for peak windows
When you have two target tracking policies, ECS scales out if either policy says to scale out. It only scales in when both policies say it's safe to scale in. That's the right behavior โ aggressive on scale-out, conservative on scale-in.
Monitoring It
Once auto scaling is configured, watch your service events and CloudWatch alarms to confirm scaling activity is happening when you expect it. Things to track:
- Scaling activity log (are tasks being added/removed as expected?)
- Your minimum and maximum task counts (are they set appropriately?)
- Cooldown behavior (are you oscillating, or is scaling smooth?)
- Cost trend after enabling auto scaling (you should see a reduction in idle periods)
If tasks are scaling out and then immediately scaling back in, your scale-in cooldown is too short. If you're not scaling out fast enough during traffic spikes, reduce your scale-out cooldown or lower your CPU target threshold.
What NoahOps Does Here
This is where the manual AWS setup gets replaced. When you create a service on NoahOps, auto scaling is configured as part of the deployment โ not as a separate step you have to remember. You set your minimum and maximum task count in the NoahOps dashboard. NoahOps creates the target tracking policies, registers the scalable target, and connects CloudWatch alarms automatically.
If you want to adjust thresholds, you do it from the NoahOps interface. No AWS CLI. No IAM policies to debug. No CloudWatch alarm configuration to untangle.
Noah AI also understands auto scaling in plain English. You can tell it "scale between 2 and 10 tasks, target 60% CPU" and it translates that into the correct Application Auto Scaling configuration against your ECS service. Or if something's wrong โ requests are timing out, tasks are oscillating โ you can describe what's happening and Noah AI walks you through the likely cause.
The underlying AWS resources are created in your account. You can see them in the AWS console if you want to. You own them. NoahOps just removes the configuration overhead.
Frequently Asked Questions
Does auto scaling work on Fargate? Yes. Fargate supports Application Auto Scaling on task count. You don't manage the underlying EC2 instances โ you just scale tasks, and Fargate provisions compute capacity for each one. This is simpler than EC2 auto scaling, which requires you to also manage the cluster capacity.
What's the minimum task count I should set? At least 2 for anything production. A single task is a single point of failure. If it crashes or needs to restart, your service goes down until a new task is healthy. With 2 tasks minimum, you always have at least one healthy task running.
Can I run auto scaling on a Fargate Spot service? Yes, and it works well. Fargate Spot is up to 70% cheaper than standard Fargate. The tradeoff: Spot tasks can be interrupted with 2 minutes notice. For services that can handle occasional task restarts gracefully, Spot + auto scaling is a good cost optimization. Don't run databases or stateful services on Spot.
Will auto scaling help my costs? Usually yes, if your traffic is variable. If you currently run 5 tasks 24/7 but your actual traffic only needs 5 tasks for 4 hours a day, auto scaling should bring your average task count down significantly. The savings scale with how uneven your traffic pattern is.
How long does it take for a new Fargate task to be ready? Typically 30โ60 seconds for a new Fargate task to spin up, pass health checks, and start receiving traffic. This is the lag between "auto scaling decides to add a task" and "that task is actually handling requests." For sudden traffic spikes, scheduled scaling or lower scale-out thresholds can compensate.
Request a free demo at noahops.com to see how NoahOps configures ECS auto scaling for your service โ no AWS console required.