☁️ AWS · Solutions Architect

Scalability & High Availability

A structured summary of Load Balancer, Auto Scaling Group, SSL/TLS, and scaling strategies on AWS — with core takeaways, practical steps, memorable quotes, and concept explanations.

🎯

Core Takeaways

The most important conclusions of this topic — each with a brief explanation.

1

Scalability and High Availability are two different problems

Scalability = ability to handle larger load. High Availability = ability to avoid downtime. A system that scales very well can still go down completely if it runs in only one AZ.

2

Vertical Scaling has a physical ceiling

Increasing CPU/RAM for one machine is the fastest way, but it is limited by hardware, usually requires downtime, and does not solve high availability.

3

Horizontal Scaling is nearly unlimited — but needs stateless apps

Adding many small instances is much cheaper than one huge instance. Conditions: the app must not store local state, and a Load Balancer must sit in front.

4

High Availability = running in parallel across ≥ 2 Availability Zones

True HA means surviving the failure of an entire datacenter. Placing 2 instances in the same AZ is not HA.

5

A Load Balancer is the "single entry point" of the system

The LB hides the backend architecture, lets you replace or add instances without clients knowing, and is where SSL terminates and WAF is attached.

6

Use ELB instead of building your own Load Balancer

ELB is managed by AWS: it automatically scales with traffic, patches security, and integrates with Auto Scaling Group, CloudWatch, and ACM — no LB servers to operate.

7

Health Check is the heart of a Load Balancer

Without health checks, the LB keeps sending traffic to dead instances. Health checks must reflect the actual ability to serve, not just whether the port is open.

8

The Load Balancer's Security Group is the access control layer

The LB is open to the Internet (0.0.0.0/0 on 80/443), while EC2 only allows traffic from the LB's Security Group. Never expose EC2 directly to the Internet.

9

Three Load Balancer types, three different OSI layers

ALB = Layer 7 (HTTP/HTTPS, path/host routing). NLB = Layer 4 (TCP/UDP, ultra-low latency, static IP). GWLB = Layer 3 (inserts security appliances into the traffic flow).

10

Sticky Sessions are convenient but break load balancing

Session affinity keeps clients tied to one instance — it easily causes imbalance and harms scaling. Prefer externalizing sessions (ElastiCache, DynamoDB).

11

Cross-Zone Load Balancing distributes evenly — but costs

ALB is enabled by default and free. NLB/GWLB are off by default; enabling them incurs cross-AZ data transfer charges.

12

SSL Termination + SNI is the standard combo for multi-domain

The LB holds certificates and decrypts, offloading CPU from the backend. SNI allows multiple certificates on the same listener 443, serving multiple domains.

13

Connection Draining protects in-flight requests

When an instance is removed from the LB (scale-in or deploy), the LB stops sending new requests but waits for current requests to finish — avoiding 502/504 errors for users.

14

ASG is the tool to achieve both Scalability and High Availability

ASG automatically increases/decreases instance count based on load, and detects and replaces failed instances — spreading instances across multiple subnets in multiple AZs.

15

Cooldown prevents "flapping"

After each scaling action, the system waits for metrics to stabilize (default 300s) before evaluating again. Without cooldown, ASG will repeatedly scale up and down, wasting resources.

🛠️

Practical Methods

A 12-step process from choosing a Load Balancer to configuring Auto Scaling — with ready-to-run code examples.

Step 1 — Determine traffic type and choose Load Balancer type

HTTP/HTTPS with path/host routing → ALB. TCP/UDP, ultra-low latency or static IP → NLB. Need to insert a firewall/appliance → GWLB.

# Check available Load Balancer types in the region
aws elbv2 describe-load-balancer-types --query "LoadBalancerTypes[].LoadBalancerType"

Step 2 — Create a Target Group and configure Health Check

Health check must point to an endpoint that reflects real app health (e.g., /health), not just check the port.

aws elbv2 create-target-group \
  --name tg-app-http \
  --protocol HTTP --port 80 \
  --vpc-id vpc-0abc123 \
  --health-check-path /health \
  --health-check-interval-seconds 15 \
  --health-check-timeout-seconds 5 \
  --healthy-threshold-count 2 \
  --unhealthy-threshold-count 3

Step 3 — Create an Application Load Balancer and Listener

Place the ALB in public subnets in at least 2 AZs for HA. Listener 80 can redirect to 443.

aws elbv2 create-load-balancer \
  --name alb-web \
  --type application \
  --scheme internet-facing \
  --subnets subnet-pub-a subnet-pub-b \
  --security-groups sg-0alb123

# Listener 443 with ACM certificate + default forward action
aws elbv2 create-listener \
  --load-balancer-arn arn:aws:elasticloadbalancing:...:loadbalancer/app/alb-web/xxx \
  --protocol HTTPS --port 443 \
  --certificates CertificateArn=arn:aws:acm:...:certificate/abc \
  --default-actions Type=forward,TargetGroupArn=arn:aws:...:targetgroup/tg-app-http/yyy

Step 4 — Configure Security Groups using the "LB → App" model

The LB receives traffic from the Internet; EC2 only receives traffic from the LB's SG. This is the golden security rule.

# SG for ALB: open 80/443 from anywhere
aws ec2 authorize-security-group-ingress --group-id sg-0alb123 \
  --protocol tcp --port 443 --cidr 0.0.0.0/0

# SG for EC2: only accept port 80 from the ALB SG (source-group reference)
aws ec2 authorize-security-group-ingress --group-id sg-0app456 \
  --protocol tcp --port 80 \
  --source-group sg-0alb123

Step 5 — Enable Cross-Zone Load Balancing

Ensure instances in all AZs receive even traffic. ALB is enabled by default; NLB/GWLB must be enabled manually.

aws elbv2 modify-load-balancer-attributes \
  --load-balancer-arn arn:aws:elasticloadbalancing:...:loadbalancer/net/nlb-1/xxx \
  --attributes Key=load_balancing.cross_zone.enabled,Value=true

Step 6 — Configure Sticky Sessions (only if truly needed)

Use an LB-generated cookie (AWSALB) or an application cookie. Keep duration short and plan to move sessions out.

aws elbv2 modify-target-group-attributes \
  --target-group-arn arn:aws:...:targetgroup/tg-app-http/yyy \
  --attributes \
    Key=stickiness.enabled,Value=true \
    Key=stickiness.type,Value=lb_cookie \
    Key=stickiness.lb_cookie.duration_seconds,Value=900

Step 7 — Set up SSL/TLS and SNI for multiple domains

Only support TLS 1.2+ with a modern policy. Add multiple certificates to the same listener 443 — the client sends SNI so the LB picks the correct cert.

# Add a second certificate for another domain on the same listener 443
aws elbv2 add-listener-certificates \
  --listener-arn arn:aws:...:listener/app/alb-web/xxx/aaa \
  --certificates CertificateArn=arn:aws:acm:...:certificate/domain2

# Enforce TLS 1.2+ and enable SNI (already enabled by default for ALB/NLB)
aws elbv2 modify-listener \
  --listener-arn arn:aws:...:listener/app/alb-web/xxx/aaa \
  --ssl-policy ELBSecurityPolicy-TLS13-1-2-2021-06

Step 8 — Create a Launch Template as the instance "blueprint"

A Launch Template contains the AMI, instance type, key pair, security group, and user data so the app starts automatically when an instance is created.

aws ec2 create-launch-template \
  --launch-template-name lt-web-v1 \
  --version-description v1 \
  --launch-template-data '{
    "ImageId": "ami-0abcdef1234567890",
    "InstanceType": "t3.micro",
    "SecurityGroupIds": ["sg-0app456"],
    "UserData": "IyEvYmluL2Jhc2gKeXVtIGluc3RhbGwgLWUgbmdpbnggLXkKc3lzdGVtY3RsIGVuYWJsZSAtLW5vdyBuZ2lueAo="
  }'

Step 9 — Create an Auto Scaling Group spread across multiple AZs

Choose subnets in ≥ 2 AZs, attach to the LB Target Group, and set min/desired/max. ASG will replace unhealthy instances.

aws autoscaling create-auto-scaling-group \
  --auto-scaling-group-name asg-web \
  --launch-template LaunchTemplateName=lt-web-v1,Version='$Latest' \
  --min-size 2 --max-size 10 --desired-capacity 2 \
  --vpc-zone-identifier "subnet-priv-a,subnet-priv-b" \
  --target-group-arns arn:aws:...:targetgroup/tg-app-http/yyy \
  --health-check-type ELB \
  --health-check-grace-period 60

Step 10 — Attach a Scaling Policy (Target Tracking is the default choice)

Target Tracking keeps a metric around a target threshold and automatically calculates the required capacity — less configuration, fewer errors than Simple Scaling.

aws autoscaling put-scaling-policy \
  --auto-scaling-group-name asg-web \
  --policy-name cpu-target-50 \
  --policy-type TargetTrackingScaling \
  --target-tracking-configuration '{
    "PredefinedMetricSpecification": {
      "PredefinedMetricType": "ASGAverageCPUUtilization"
    },
    "TargetValue": 50.0,
    "ScaleInCooldown": 300,
    "ScaleOutCooldown": 60
  }'

Step 11 — Create CloudWatch Alarms for custom metrics

For web apps, ALB RequestCountPerTarget is often a better scaling metric than CPU. For workers, use queue depth (SQS ApproximateNumberOfMessages).

aws cloudwatch put-metric-alarm \
  --alarm-name "asg-high-requests" \
  --metric-name RequestCountPerTarget \
  --namespace AWS/ApplicationELB \
  --statistic Sum --period 60 \
  --threshold 1000 --comparison-operator GreaterThanThreshold \
  --evaluation-periods 2 \
  --dimensions Name=TargetGroup,Value=targetgroup/tg-app-http/yyy

Step 12 — Tune Cooldown, Grace Period, and Connection Draining

These three parameters decide whether the system is smooth or jumpy: grace period long enough for app startup, draining long enough for requests to finish, and cooldown long enough to avoid flapping.

# Default cooldown for ASG (seconds)
aws autoscaling update-auto-scaling-group \
  --auto-scaling-group-name asg-web \
  --default-cooldown 300 \
  --health-check-grace-period 120

# Deregistration Delay (Connection Draining) on Target Group - default 300s
aws elbv2 modify-target-group-attributes \
  --target-group-arn arn:aws:...:targetgroup/tg-app-http/yyy \
  --attributes Key=deregistration_delay.timeout_seconds,Value=60
💬

Memorable Quotes

Concise, thought-provoking quotes from this topic.

"Scalability is not about making a machine stronger — it is about making the system wider."

— AWS SAA content, Scalability & High Availability

"Vertical scaling has limits; horizontal scaling is nearly limitless."

— AWS SAA content, Vertical vs Horizontal Scalability

"High Availability means the system stays alive when an entire datacenter dies."

— AWS SAA content, High Availability

"A Load Balancer does not just distribute traffic — it is the single entry point that hides your entire backend."

— AWS SAA content, What is Load Balancing?

"Without health checks, a Load Balancer is just a proxy sending traffic to dead places."

— AWS SAA content, Health Checks

"Let AWS manage the Load Balancer — you do not need to patch and scale a proxy yourself."

— AWS SAA content, Why use an Elastic Load Balancer?

"ALB understands HTTP; NLB only understands bytes. Choosing the wrong layer means choosing the wrong tool."

— AWS SAA content, Types of Load Balancer

"Sticky sessions are an easy promise — and technical debt when the system has to scale."

— AWS SAA content, Sticky Sessions

"SNI lets one listener serve multiple domains — no need for multiple Load Balancers for multiple websites."

— AWS SAA content, SSL – Server Name Indication

"Connection Draining is kindness to users: do not cut off requests that are still running."

— AWS SAA content, Connection Draining

"An Auto Scaling Group is both a scaling tool and insurance against instance failures."

— AWS SAA content, What is an Auto Scaling Group?

"Scaling on the right metric matters more than scaling fast. Low CPU does not mean the system is idle."

— AWS SAA content, Good metrics to scale on

"Cooldown is not slowness — it is how the system avoids harming itself."

— AWS SAA content, Scaling Cooldowns
📚

Concept Explanations

The 14 most important terms — explained simply, with real-world comparisons.

📊

Scalability

Foundation

The ability of a system to handle an increasing workload by adding resources. There are two directions: vertical scaling (stronger machine) and horizontal scaling (more machines).

🏙️ Analogy: A busy restaurant — either upgrade to a bigger industrial kitchen (vertical) or hire more chefs (horizontal).
⬆️

Vertical Scalability

Scaling

Upgrading the resources of one instance: from t3.micro to m5.2xlarge, adding RAM, adding CPU. Often used for databases or systems that cannot be distributed.

🚗 Analogy: Upgrading a car engine — more powerful, but has a ceiling and needs garage time (downtime).
↔️

Horizontal Scalability

Scaling

Increasing the number of instances running in parallel (scale out). This is the cloud-native way, nearly unlimited, but requires a stateless app and a Load Balancer.

🏪 Analogy: Opening more branches instead of expanding one store.
🛡️

High Availability

Reliability

The system remains operational when a component fails. On AWS, this usually means running resources in at least 2 Availability Zones.

✈️ Analogy: A twin-engine aircraft — one engine fails, it can still fly; a single-engine cannot.
⚖️

Load Balancer

Networking

A device/service in front of servers that distributes traffic to multiple backends and exposes only one access point to the outside.

🏦 Analogy: An airport coordinator — routes passengers to available check-in counters.
☁️

Elastic Load Balancer (ELB)

Managed Service

A Load Balancer fully managed by AWS: automatically scales with traffic, patches itself, has an SLA, and integrates with ASG, CloudWatch, and ACM.

🚕 Analogy: Ride-hailing vs owning a car — no maintenance or inspections to worry about.
❤️

Health Check

Monitoring

The LB periodically sends a request to an endpoint to check whether an instance can still serve. An instance that fails N times is removed from traffic rotation.

🩺 Analogy: A regular health checkup — if unhealthy, rest, do not keep working.
🎯

Target Group

ELB Component

A logical group of backends (EC2, Lambda, IP, container) that the LB sends traffic to. Each target group has its own health check and attributes.

📋 Analogy: A class list — the teacher (LB) chooses the class (target group) and then the student (target) for the assignment.
📌

Sticky Sessions (Session Affinity)

Feature

The same client is always routed to the same instance for the session. Useful when the app stores sessions in memory, but it causes load imbalance.

💇 Analogy: Always asking for the same barber — convenient, but if they are off, you wait.
🌍

Cross-Zone Load Balancing

Feature

Each LB node distributes traffic evenly to all instances in all AZs, instead of only within its own AZ. ALB is enabled by default; NLB/GWLB are off by default and charge for cross-AZ traffic when enabled.

🍽️ Analogy: A waiter serves all tables in the restaurant, not just the assigned area.
🔒

SSL/TLS Termination & SNI

Security

The LB holds certificates and decrypts HTTPS, reducing backend CPU load. SNI lets the client declare the hostname so the LB picks the correct certificate — multiple domains on one listener.

🏨 Analogy: A hotel receptionist holds the keys and takes you to the right room — you do not need the building map.
🚰

Connection Draining

ELB Setting

Also called Deregistration Delay. When an instance is removed from the LB, the LB stops sending new requests but waits for in-flight requests to finish (default 300s) before disconnecting.

🍜 Analogy: A restaurant about to close still serves seated guests; it does not kick them out mid-meal.
🤖

Auto Scaling Group (ASG)

Compute

A collection of EC2 instances managed automatically: maintains the desired count, replaces failed instances, and scales based on policy. Set min, max, and desired capacity.

👥 Analogy: A contracted workforce — always enough people; if someone leaves, hire a replacement.
⏱️

Scaling Cooldown

ASG Setting

The period ASG pauses evaluation to let metrics and new instances stabilize (default 300s). It prevents repeated up/down scaling that causes waste and instability.

🌡️ Analogy: An AC does not turn on/off every minute — it waits for the temperature to stabilize.
📈

Target Tracking Scaling

Scaling Policy

Choose a metric and a target value (e.g., CPU 50%), and ASG automatically calculates and adjusts capacity to keep the metric near that level. The simplest and most effective option.

🚗 Analogy: Cruise control in a car — you set the speed, and the car adjusts the throttle.