Amazon EC2 Auto Scaling adjusts the number of EC2 instances in an Auto Scaling group (ASG). It can maintain a chosen capacity, react to measured demand, and replace instances that its configured health checks identify as unhealthy. Those actions help an application recover and handle changing load, but they do not make the application highly available by themselves.

Availability also depends on spare capacity in healthy Availability Zones, resilient dependencies, safe handling of state, and a tested way to release changes. This guide focuses on those boundaries for an EC2 service. For a practical group setup, launch template, warmup, and troubleshooting steps, see our EC2 Auto Scaling setup guide.

What EC2 Auto Scaling does for availability

An ASG manages EC2 instances toward a desired capacity. Ordinary scaling actions are limited by configured minimum and maximum values, but those limits do not ensure launches will succeed when quota, subnet IP space, permissions, or EC2 capacity are constrained. Dynamic or scheduled policies can change desired capacity, and predictive scaling can add capacity ahead of recurring forecast demand. The group can replace unhealthy instances when its health checks report a failure. It does not know whether a user journey is successful unless your health signals and monitoring represent that outcome. See AWS's EC2 Auto Scaling group guide for its capacity and health-check behavior.

Scaling out is not the same as surviving a failure

Scaling responds to capacity pressure or a chosen schedule; availability design keeps the service useful when an instance, zone, dependency, or release fails. An ASG spread across multiple Availability Zones can replace failed instances, but recovery takes time and AWS may be unable to launch the requested capacity. Keep enough healthy baseline capacity to serve critical traffic while replacement instances start, and verify that the app's data and dependencies are usable from the remaining zones.

A load balancer normally routes new requests to targets that pass its health checks; an ALB can fail open when every target in a target group is unhealthy. For the concrete network, HTTPS, target-group, and health-check setup, see our AWS Application Load Balancer setup guide. The ALB and ASG still depend on application readiness and healthy downstream services.

Build the availability envelope before choosing a policy

Distribute ready capacity across Availability Zones

Place an ASG in subnets from multiple Availability Zones and use a distribution strategy that balances instances across them. Check how that strategy behaves when a launch fails in one zone; balancing alone cannot guarantee that a replacement will start. Choose a minimum capacity that leaves enough healthy instances to serve the expected load after losing a zone. Set that floor using measured per-instance throughput and a failure scenario, not the assumption that the ASG will add replacement instances immediately. Check service quotas, subnet address space, instance-family capacity, and launch permissions that could prevent scaling out. AWS describes its Availability Zone distribution behavior.

Do not treat the Region as a single uniform pool. ALBs always have cross-zone balancing enabled at the load-balancer level, though it can be disabled for a target group. NLBs and GWLBs have it disabled by default, and a target group can override its load balancer's setting. Understand the chosen load balancer's behavior and ensure other zones can carry the requests directed to them; see AWS's cross-zone balancing documentation.

Keep dependencies and state available

Replacing an EC2 instance works only when a new instance can recover the state it needs. Keep durable state in an appropriate shared or replicated data service, and understand its failover, consistency, and recovery behavior. A read replica, cache, or multi-AZ placement can help a specific failure mode; none proves that writes, sessions, configuration, secrets, or downstream capacity are ready in every zone.

Test what happens when a dependency is slow, read-only, unreachable from one zone, or recovering. Decide whether the application should reject work, serve a defined degraded response, retry within a bounded deadline, or queue work for later. Auto Scaling cannot fix an overloaded database or make retries safe.

Choose a scaling method and a signal

Pick a metric that reflects useful work per instance and responds when capacity changes. Set targets from load tests and production observations, with enough headroom for traffic during instance startup. There is no universal CPU threshold or target value.

Dynamic target tracking for ongoing demand

Target tracking adjusts the group's capacity to maintain a chosen average utilization or throughput value. For a web tier behind an ALB, ALBRequestCountPerTarget is a predefined EC2 Auto Scaling target-tracking metric. It represents average ALB requests per target and requires the resource label that identifies the associated ALB target group. It can fit when each instance's sustainable request rate is a useful capacity measure; see AWS's target-tracking metric guidance.

ALB TargetResponseTime measures the time from forwarding a request to the target until the target starts sending response headers. AWS lists load-balancer request latency as unsuitable for target tracking because it can rise with utilization without changing proportionally. Treat response time as an outcome to monitor alongside errors and saturation; do not assume an arbitrary latency alarm will scale the group well. See the ALB metric definition and AWS's explanation of metrics that do not work for target tracking.

Scheduled scaling for known demand

Use a scheduled action when demand predictably rises at known times, such as before a regular business-hours peak. It sets desired capacity and can also set minimum or maximum capacity. After it runs, dynamic policies can continue adjusting capacity within the resulting limits. Schedules can get the fleet ready earlier than a reactive policy, but they need maintenance when business patterns or time zones change.

Predictive scaling for recurring patterns

Predictive scaling forecasts recurring demand from historical load metrics and can launch instances ahead of the expected increase. EC2 Auto Scaling needs at least 24 hours of history to start forecasting; AWS says forecasts work better with two full weeks. Begin in forecast-only mode and compare forecasts with real demand before enabling scale-out. Keep a dynamic policy for changes the forecast misses.

Queue workers: scale on backlog per worker

A raw SQS visible-message count does not show how much work each worker must handle. A more useful target is visible messages ÷ ASG instances in service, with a target based on acceptable queue delay and measured processing time. AWS shows this ratio using CloudWatch metric math for backlog per instance. Avoid treating each message as equal if processing cost varies widely.

The ratio has no defined value when the group has zero in-service instances. Make the zero-capacity path explicit: keep a minimum worker if the service needs continuous readiness, or add a separately tested scale-out action, such as a queue-depth step-scaling alarm, that can launch the first worker from zero. Do not assume the ratio itself can divide by zero and trigger capacity. For stateful or long-running work, make messages safe to retry and use a termination hook or instance protection strategy where needed to finish or hand off a job. See AWS's step-scaling guidance.

Health checks, warmup, and safe scale-in

Use health checks for the right decision

EC2 status checks are always used. You can also enable ELB health checks so the ASG replaces an instance the load balancer reports as unhealthy. Choose a target-group endpoint that reflects whether the instance can handle its assigned traffic. A health-check grace period gives a new in-service instance time to initialize before the ASG acts on additional health results; it is not a delay on EC2's detection that an instance has stopped running.

Set default instance warmup separately. Warmup controls when a new instance's early metrics count in scaling calculations and can prevent target tracking or step scaling from scaling in before the new instance's load stabilizes. Use measured startup and readiness data for both values. They are different settings with different jobs.

Let requests and work drain before termination

When the ASG terminates an instance behind a load balancer, it deregisters the target so new requests go elsewhere and allows existing connections to drain for the configured deregistration delay. Select a delay long enough for normal requests, streaming connections, or application shutdown, but do not assume it can finish work that outlasts that window.

Use an EC2 Auto Scaling termination lifecycle hook when the app needs time to complete work, save progress, or transfer state. Queue workers can use instance scale-in protection while a job is running and remove it when ready for termination. These mechanisms need bounded timeouts and monitoring; a hook is not an unconditional guarantee that an instance will stay alive.

Monitor capacity and customer outcomes together

Watch desired, pending, in-service, and healthy target counts alongside request rate, response time, application errors, saturation, launch failures, and queue age. An ASG can report desired capacity while instances are still pending or targets are not yet ready. Alarm on sustained loss of healthy capacity and failed launch activity, then trace whether the cause is startup, permissions, quotas, subnet IPs, health checks, or a downstream bottleneck.

Set a maximum capacity to limit how far the ASG can normally scale out, while leaving room for the failure and traffic scenarios you intend to support. A budget alarm notifies you about spending; it does not stop charges or cap them, and costs from load balancers, storage, networks, and monitoring may continue independently. Scale-in reduces EC2 instance cost only when remaining instances and dependencies can safely handle demand.

Roll out changes and prove recovery

Use instance refresh with checkpoints and rollback controls

Create a new numbered launch-template version with the change, and leave the Auto Scaling group's current configuration on its previous numbered version. Start the instance refresh with the new version as the desired configuration; if the refresh succeeds, the group adopts it. For rollback, AWS requires a desired configuration and a stable saved configuration to return to, and the group cannot use the launch template's $Latest or $Default version. Automatic rollback is disabled by default. Review AWS's instance refresh rollback prerequisites before enabling it.

Set a minimum healthy percentage that keeps enough capacity available, and allow new targets to pass health checks and finish warmup before continuing. Use checkpoints to pause for validation where appropriate. Enable automatic rollback only after its prerequisites are met, and attach CloudWatch alarms if they represent a clear stop condition. Test rollback in a controlled environment before relying on it.

An instance refresh can reduce deployment disruption, but it does not guarantee zero downtime. A bad image, incompatible schema change, failed dependency, or health check that misses a user-visible regression can still affect every new instance. Roll out in a controlled environment first and verify actual requests, errors, and capacity during the refresh.

Validate the failure cases that matter

Before relying on an availability design, test at least one instance replacement, a zone with reduced capacity, a burst that exercises the scaling policy, a slow or failing dependency, and a deployment that must roll back. Confirm what users see, how long capacity takes to recover, whether queued work is duplicated or lost, and how operators know the action succeeded. Use a staging environment or a controlled test window and define stop conditions before any fault exercise.

Operational checklist

  • Keep enough healthy capacity in the surviving Availability Zones while new instances launch.
  • Use a per-instance utilization or throughput signal. For ALB workloads, evaluate ALBRequestCountPerTarget; track response latency and error rate as separate outcomes.
  • Set health-check grace period and default instance warmup from measured startup behavior; account for dependencies and launch constraints.
  • Drain in-flight requests and jobs before scale-in, and make stateful work recoverable if termination happens early.
  • Test scale-out, replacement, instance refresh, rollback, and dependency failures before relying on them in production.