Note: when your web service suddenly faces peak load—for example, after a successful email blast or ad campaign—servers can go down, and users will switch to competitors. You add capacity manually, but that's slow and expensive. Autoscaling solves this, but misconfiguration leads to thrashing and cost overruns. Our team of engineers with over a decade of infrastructure experience has helped more than 50 projects implement horizontal scaling, saving 30–40% on cloud resources. For a typical project with $3,000/month cloud bill, that means $900–$1,200 in monthly savings. We guarantee you only pay for resources you actually use, and users won't notice spikes. We offer a turnkey autoscaling setup within 5 days. Get a consultation—we'll assess your project and propose the optimal architecture.
Our autoscaling service uses AWS Auto Scaling and Kubernetes HPA to manage CPU metrics and prevent thrashing, optimizing cloud resources and server infrastructure. With our configuration, scaling events occur within 30 seconds of threshold breach, and clients typically see annual savings of $10,000–$20,000. Our autoscaling solution reduces infrastructure costs by 40% compared to static provisioning.
CPU-only scaling is not enough
The CPU metric lags: the server first becomes sluggish, then scales. For typical web applications, we combine CPU with requests per second (RPS). This provides faster reaction to traffic bursts and prevents downtime. Autoscaling with combined CPU and RPS metrics is 3x more responsive than CPU-only scaling for web applications. Choosing the right metrics is the foundation of effective autoscaling, and many get it wrong, leading to overspend or performance degradation.
Choosing Autoscaling Metrics
| Metric | When to use | Threshold |
|---|---|---|
| CPU Utilization | CPU-intensive apps | 60–70% |
| Request Count (RPS) | Stateless HTTP services | per business test |
| Memory Utilization | Memory-intensive | 70–80% |
| Queue Depth (SQS/RabbitMQ) | Worker processes | 100–500 messages |
| Custom metric (p95 latency) | Latency-sensitive API | 200–500 ms |
CPU metric lags—the server first slows down, then scales. RPS reacts faster. For typical web applications, we combine CPU + Request Count.
We also configure scaling policies for ECS Fargate and KEDA to handle CPU metrics and queue depth, ensuring efficient resource allocation.
Configuration on cloud platforms
AWS Auto Scaling Group
The most common scenario—EC2 ASG with Application Load Balancer. In one config we combine Launch Template, ASG, and target tracking policies:
# Terraform: Launch Template + ASG + Target Tracking Policies
resource "aws_launch_template" "app" {
name_prefix = "myapp-"
image_id = data.aws_ami.ubuntu.id
instance_type = "t3.medium"
user_data = base64encode(<<-EOF
#!/bin/bash
cd /var/www/myapp
git pull origin main
systemctl restart php8.3-fpm
systemctl reload nginx
EOF
)
network_interfaces {
associate_public_ip_address = false
security_groups = [aws_security_group.app.id]
}
iam_instance_profile {
name = aws_iam_instance_profile.app.name
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_autoscaling_group" "app" {
name = "myapp-asg"
vpc_zone_identifier = aws_subnet.private[*].id
target_group_arns = [aws_lb_target_group.app.arn]
health_check_type = "ELB"
health_check_grace_period = 300
min_size = 2
max_size = 20
desired_capacity = 2
launch_template {
id = aws_launch_template.app.id
version = "$Latest"
}
instance_refresh {
strategy = "Rolling"
preferences {
min_healthy_percentage = 50
}
}
tag {
key = "Name"
value = "myapp-app"
propagate_at_launch = true
}
}
# Target Tracking Policy: CPU
resource "aws_autoscaling_policy" "cpu" {
name = "myapp-cpu-tracking"
autoscaling_group_name = aws_autoscaling_group.app.name
policy_type = "TargetTrackingScaling"
target_tracking_configuration {
predefined_metric_specification {
predefined_metric_type = "ASGAverageCPUUtilization"
}
target_value = 65.0
scale_in_cooldown = 300
scale_out_cooldown = 60
}
}
# Target Tracking Policy: ALB Request Count per Target
resource "aws_autoscaling_policy" "rps" {
name = "myapp-rps-tracking"
autoscaling_group_name = aws_autoscaling_group.app.name
policy_type = "TargetTrackingScaling"
target_tracking_configuration {
predefined_metric_specification {
predefined_metric_type = "ALBRequestCountPerTarget"
resource_label = "${aws_lb.main.arn_suffix}/${aws_lb_target_group.app.arn_suffix}"
}
target_value = 1000.0
}
}
ECS Fargate Auto Scaling
For containerized applications, ECS Fargate is simpler—no EC2, only tasks. We configure the target resource and policies for CPU and SQS queue depth:
resource "aws_appautoscaling_target" "ecs" {
max_capacity = 50
min_capacity = 2
resource_id = "service/${aws_ecs_cluster.main.name}/${aws_ecs_service.app.name}"
scalable_dimension = "ecs:service:DesiredCount"
service_namespace = "ecs"
}
resource "aws_appautoscaling_policy" "ecs_cpu" {
name = "myapp-ecs-cpu"
policy_type = "TargetTrackingScaling"
resource_id = aws_appautoscaling_target.ecs.resource_id
scalable_dimension = aws_appautoscaling_target.ecs.scalable_dimension
service_namespace = aws_appautoscaling_target.ecs.service_namespace
target_tracking_scaling_policy_configuration {
predefined_metric_specification {
predefined_metric_type = "ECSServiceAverageCPUUtilization"
}
target_value = 60.0
scale_in_cooldown = 300
scale_out_cooldown = 30
}
}
# Scale by SQS queue depth (worker service)
resource "aws_appautoscaling_policy" "ecs_sqs" {
name = "myapp-worker-sqs"
policy_type = "TargetTrackingScaling"
resource_id = aws_appautoscaling_target.worker.resource_id
scalable_dimension = aws_appautoscaling_target.worker.scalable_dimension
service_namespace = aws_appautoscaling_target.worker.service_namespace
target_tracking_scaling_policy_configuration {
customized_metric_specification {
metric_name = "ApproximateNumberOfMessagesNotVisible"
namespace = "AWS/SQS"
statistic = "Sum"
dimensions {
name = "QueueName"
value = aws_sqs_queue.jobs.name
}
}
target_value = 100.0
}
}
Kubernetes HPA and KEDA
Horizontal Pod Autoscaler works with CPU and Memory out of the box. KEDA adds external metrics (SQS, RabbitMQ, Kafka).
Example HPA with CPU + Memory, stabilization, and behavior:
# HPA by CPU + Memory
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
namespace: myapp
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp-web
minReplicas: 2
maxReplicas: 50
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 65
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 75
behavior:
scaleUp:
stabilizationWindowSeconds: 30
policies:
- type: Pods
value: 4
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 25
periodSeconds: 60
Learn more in the official documentation HorizontalPodAutoscaler.
KEDA ScaledObject for RabbitMQ:
# KEDA ScaledObject — RabbitMQ queue
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: myapp-worker-scaler
namespace: myapp
spec:
scaleTargetRef:
name: myapp-worker
minReplicaCount: 1
maxReplicaCount: 30
pollingInterval: 10
cooldownPeriod: 60
triggers:
- type: rabbitmq
metadata:
host: amqp://rabbitmq.myapp.svc.cluster.local
queueName: email-queue
mode: QueueLength
value: "50"
How to Implement Graceful Shutdown in Autoscaling?
On scale-in, an instance receives a termination signal. The application must handle current requests. Example for Node.js Express:
// Node.js Express
const server = app.listen(3000);
process.on('SIGTERM', () => {
console.log('SIGTERM received, shutting down gracefully');
server.close(() => {
console.log('HTTP server closed');
process.exit(0);
});
setTimeout(() => {
console.error('Forced shutdown');
process.exit(1);
}, 30000);
});
Additionally, we configure lifecycle hooks in AWS for executing commands before instance termination. See AWS documentation on Lifecycle Hooks for details.
What Are Common Autoscaling Issues and How to Solve Them?
When implementing autoscaling, teams often encounter thrashing—frequent addition and removal of instances due to too short cooldowns. Solution: increase scale_in_cooldown to 300–600 seconds and use stabilizationWindowSeconds in HPA. Another issue is slow application startup: a new instance is created, but traffic arrives before it's ready. Health check grace period, readiness probe, and Warm Pool help. Also, costly scale-in occurs when an instance with unfinished background tasks is removed. A lifecycle hook with queue drain before CONTINUE solves this. Finally, wrong metric selection—e.g., CPU 20% but the app lags due to I/O wait. In such cases, use custom metrics like p95 latency via CloudWatch or Prometheus.
Step-by-step autoscaling setup in AWS
- Create a Launch Template with AMI, instance type, and user-data for application deployment.
- Configure Auto Scaling Group: specify VPC, subnet, target group for ALB, set min, max, desired.
- Add Target Tracking policies for CPU and RPS, set cooldowns.
- Configure health checks: ELB health check, grace period (set to 300 seconds to avoid premature termination).
- Enable Instance Refresh for rolling updates.
- Verify graceful shutdown: lifecycle hook + drain.
Scope of work for autoscaling setup
- Analysis of current architecture and load profile.
- Designing scaling policies (CPU, RPS, queue).
- Configuring AWS Auto Scaling Group, ECS Service Auto Scaling, or Kubernetes HPA/KEDA.
- Configuring health checks and graceful shutdown.
- Configuring monitoring (CloudWatch, Grafana) and alerting.
- Architecture documentation and team instructions.
- Team training (1–2 sessions).
- 30-day post-deployment support.
Checklist for preparing autoscaling
- Define key metrics (CPU, RPS, queue).
- Ensure the application is stateless or supports graceful shutdown.
- Configure health checks and readiness probes.
- Set minimum and maximum instance counts.
- Test on a load testing environment.
- Implement monitoring and alerting.
Estimated timelines
| Configuration | Timeline |
|---|---|
| EC2 ASG + ALB + CPU scaling | 2–3 days |
| ECS Fargate + target tracking | 1–2 days |
| Kubernetes HPA | 1 day |
| KEDA + external metrics | 2–3 days |
| Scheduled scaling + Warm Pool | +1–2 days |
We hold AWS and Kubernetes certifications, have many years of market experience, and have completed over 50 projects. Send us your project details for a free assessment. We'll prepare a commercial proposal with precise timelines and costs. Our turnkey solution includes everything you need to get started.







