Design always-available architecture: multi-AZ with no single point of failure, the difference between L4 and L7 load balancers, and auto-scaling that adjusts capacity based on load, complete with AWS CLI command examples.

In episode 5 we built a VPC with subnets across several AZs, and in episode 6 we filled it with VMs. But a single VM handling all traffic is a weak point: if it dies, the application dies with it. Episode 8 answers two big cloud architecture questions: how to distribute load across many machines, and how the number of machines adjusts itself to the load.
We'll start with the concept of high availability and no single point of failure, then compare L4 and L7 load balancers, map each provider's services, and close with auto-scaling complete with AWS CLI examples.
Before touching any tooling, understand three terms that shape architecture design:
The basic principle for achieving all three is redundancy across AZs. Because an AZ is a physically separate data-center building, placing machines in at least two AZs means that if the power or network of one building goes out, the other building keeps serving. This is why in episode 5 we always placed subnets across several AZs, never just one.
Note
Measure availability agreements in numbers: a 99.9 percent uptime target means roughly 43 minutes of downtime per month at most; 99.99 percent only about 4.3 minutes. The higher the nines, the more expensive the architecture. Choose a target that fits the business — don't automatically chase the highest one.
A load balancer is the "single entry point" that receives traffic and distributes it across many servers. But it can work at two different layers:
/api to service A, /assets to service B), read headers and cookies, terminate TLS connections, and perform HTTP-based health checks.| Aspect | L4 (transport) | L7 (application) |
|---|---|---|
| Works on | TCP/UDP | HTTP/HTTPS |
| Routing basis | IP + port | Path, header, host |
| Typical features | Lowest latency | Path routing, SSL termination, HTTP health checks |
| Example services | NLB, Azure Load Balancer | ALB, GCP HTTP(S) LB, Azure Application Gateway |
Tip
Think of it like a building's receptionist. An L4 receptionist only knows "all visitors go to the floor matching their destination number". An L7 receptionist knows more: a visitor going to floor 3 who needs HR is directed to desk A, one who needs finance to desk B. Both are valid — choose based on how much routing "intelligence" you need.
Same concept, different names. The complete map:
| Need | AWS | GCP | Azure |
|---|---|---|---|
| HTTP/HTTPS (L7) | Application Load Balancer | HTTP(S) Load Balancing | Application Gateway |
| TCP/UDP (L4) | Network Load Balancer | TCP/UDP Load Balancing | Load Balancer |
| Internal | Internal ALB or NLB | Internal Load Balancing | Internal Load Balancer |
One thing worth noting: because a load balancer is a single entry point, it itself should be replicated. In the cloud, load balancers are usually run as managed services that are redundantly implemented internally by the provider — you don't need to build HA for the load balancer itself, only make sure its configuration spans several AZs.
Redundancy handles failures, but not surges. Auto-scaling solves that: the number of machines adjusts to load automatically.
Important
Auto-scaling reduces capacity when load drops, but reducing capacity is a risky operation. Make sure scale-in never kills an instance that's processing important requests — use application-based health checks (for example, an HTTP check against a dedicated endpoint), not merely "the process is alive". And always keep insurance: don't let the minimum be so small that one instance carries all traffic.
Imagine a restaurant that adds chefs at lunchtime and lets them go when it's quiet — with three simple rules: at least two chefs are always present, at most ten, and add one more if the customer queue exceeds a certain threshold. That's exactly how auto-scaling works.
The first step is creating a launch template — a configuration blueprint for every new instance. The aws ec2 create-launch-template command stores that blueprint in the cloud:
aws ec2 create-launch-template \
--launch-template-name web-template \
--launch-template-data '{
"ImageId": "ami-0abcdef1234567890",
"InstanceType": "t3.medium",
"KeyName": "lab-key",
"SecurityGroupIds": ["sg-0abc123"]
}'Then form an Auto Scaling Group that uses that template and spreads across several subnets in different AZs — done via aws autoscaling create-auto-scaling-group:
aws autoscaling create-auto-scaling-group \
--auto-scaling-group-name web-asg \
--launch-template "LaunchTemplateName=web-template" \
--min-size 2 --max-size 10 --desired-capacity 3 \
--vpc-zone-identifier "subnet-0aaa,subnet-0bbb" \
--health-check-type ELBFinally, attach a target-based scaling policy: let the cloud keep average CPU around 60 percent, adding or removing instances automatically:
aws autoscaling put-scaling-policy \
--auto-scaling-group-name web-asg \
--policy-name cpu-target \
--policy-type TargetTrackingScaling \
--target-tracking-configuration '{
"PredefinedMetricSpecification": { "PredefinedMetricType": "ASGAverageCPUUtilization" },
"TargetValue": 60
}'If the target feels too aggressive or too loose, just change one number:
{
"PredefinedMetricType": "ASGAverageCPUUtilization",
"TargetValue": 60, # [!code --]
"TargetValue": 75 # [!code ++]
}Tip
Combine two strategies: target tracking for unexpected surges, and scheduled scaling for predictable ones. Raising capacity before peak hours prevents the "cold effect" — a new instance takes a few minutes to be ready to accept traffic, and if scale-out only starts once load has already risen, users will already feel the slow responses.
In this episode 8, we designed a resilient architecture: high availability through cross-AZ redundancy, no single point of failure, L4 and L7 load balancers that distribute traffic intelligently, and auto-scaling that adjusts the number of machines to the load. You also saw concrete examples of creating a launch template, an Auto Scaling Group, and a scaling policy via the AWS CLI.
The keys to take away:
Your application can now grow and survive. But the database that follows it hasn't yet: scaling an application without a reliable database is like adding more entrances without reinforcing the warehouse. Episode 9 next covers Relational Managed Databases (RDBMS) — managed versus self-hosted, multi-AZ high availability with automatic failover, and cloud-native distributed SQL like Aurora and Spanner.