AWS High Availability and Scalability
Aug 6, 2026
AWS High Availability and Scalability
When we build an application on AWS, launching one EC2 instance is only the beginning. That single server may work for learning, testing, or a small project, but real applications need to handle more traffic and survive failures. This is where High Availability and Scalability come in. These two topics are connected, but they are not exactly the same thing, and this difference is important.
Before reading this, you should know the basic meaning of EC2, Availability Zone, Region, security group, and CloudWatch. You do not need to be an expert, but you should understand that one EC2 instance can fail, one Availability Zone can have problems, and application traffic can go up and down at different times.
The Quick Answer
Scalability means your application can handle more load when traffic increases. If more users come to your website, your system should adapt instead of crashing. High Availability means your application keeps running even if one server or one Availability Zone has a problem. So scalability is mainly about handling growth, and high availability is mainly about surviving failure.
In AWS, the common setup for this is simple. You run multiple EC2 instances across multiple Availability Zones, put an Elastic Load Balancer in front of them, and use an Auto Scaling Group to add or remove instances based on demand. The load balancer sends traffic to healthy instances, and the Auto Scaling Group keeps the right number of instances running.
Scalability vs High Availability
Scalability means the system can handle bigger load by adapting. For example, if your application has 100 users today and 10,000 users tomorrow, the system should be able to grow. AWS gives two main ways to scale: vertical scaling and horizontal scaling.
Vertical scaling means increasing the size of the machine. If your application is running on a small EC2 instance and you move it to a bigger instance with more CPU and RAM, that is vertical scaling. This is also called scaling up. It is common for systems that are harder to distribute, like databases. RDS and ElastiCache can scale vertically because you can move them to a bigger instance type.
Horizontal scaling means increasing the number of machines. Instead of making one server bigger, you add more servers and divide the work between them. This is also called scaling out. Modern web applications usually use horizontal scaling because web traffic can be distributed across many EC2 instances.
High Availability is different. High Availability means your application is running in a way that it can survive failure. In AWS, this usually means running the application in at least two Availability Zones. If one Availability Zone has a problem, the application can still serve users from another Availability Zone.
The simple way to remember is this: scalability helps when traffic increases, high availability helps when something fails. A system can be scalable but not highly available if all servers are in one Availability Zone. A system can also be highly available but not very scalable if it has redundancy but cannot grow with traffic.
How This Looks for EC2
For EC2, vertical scaling means changing the instance size. You may move from a small instance to a larger one if the server needs more CPU or memory. This is easy to understand, but it has limits because every instance family has a maximum size. At some point, you cannot keep making the same machine bigger forever.
Horizontal scaling for EC2 means adding more EC2 instances. This is where Auto Scaling Groups and Load Balancers become important. The Auto Scaling Group controls how many EC2 instances should exist, and the Load Balancer distributes incoming traffic between them.
High Availability for EC2 means placing those instances in multiple Availability Zones. If you have all instances in one Availability Zone, then you still have a weak point. But if your Auto Scaling Group spans two or more Availability Zones, your application has a better chance of staying available during an Availability Zone issue.
What Is a Load Balancer?
A load balancer is a server that receives traffic from users and forwards that traffic to multiple backend servers. In AWS, this service is called Elastic Load Balancing. Users do not need to know which EC2 instance is serving the request. They only access the load balancer DNS name, and the load balancer decides where to send the request.
This solves a very practical problem. If you have five EC2 instances, you do not want users manually connecting to different instance IP addresses. You want one entry point for the application. The load balancer gives that single entry point and spreads traffic across the healthy instances.
Load balancers also do health checks. A health check is a request sent by the load balancer to check if an instance is still able to respond. A common health check path is /health. If the application returns a successful response, the instance is treated as healthy. If the instance fails the health check, the load balancer stops sending traffic to it.
Why Elastic Load Balancer Is Useful
Elastic Load Balancer is managed by AWS. That means AWS handles the availability, upgrades, and maintenance of the load balancer itself. You could create your own load balancer on EC2, but then you would also need to manage updates, scaling, failure recovery, and high availability by yourself.
ELB is useful because it spreads load, gives one DNS endpoint, checks backend health, supports SSL termination, supports sticky sessions, and can work across Availability Zones. It also integrates with services like EC2, Auto Scaling Groups, ECS, ACM, CloudWatch, Route 53, AWS WAF, and Global Accelerator.
One important security pattern is to expose the load balancer to users, but keep EC2 instances private. The EC2 security group should allow traffic only from the load balancer security group. This means users can reach the application through the load balancer, but they cannot directly hit the EC2 instances.
Types of Load Balancers in AWS
AWS has multiple load balancer types, and each one solves a different problem. For most modern web applications, Application Load Balancer is the common choice. For very high performance TCP or UDP traffic, Network Load Balancer is used. For third-party network appliances, Gateway Load Balancer is used. Classic Load Balancer is the older option and is usually not preferred for new systems.
Application Load Balancer works at Layer 7, which means it understands HTTP and HTTPS. It can route traffic based on path, hostname, headers, query strings, and other request details. For example, requests to /users can go to one target group, and requests to /search can go to another target group. This is very useful for microservices and container-based applications.
ALB target groups can contain EC2 instances, ECS tasks, Lambda functions, or private IP addresses. Health checks are configured at the target group level. One important point is that the backend EC2 instance does not directly see the original client IP as the source IP. The real client IP is passed using headers like X-Forwarded-For, and protocol information can be passed using X-Forwarded-Proto.
Network Load Balancer works at Layer 4, which means it is built for TCP, TLS, and UDP traffic. It is used when you need very high performance, very low latency, or millions of requests per second. NLB also provides one static IP per Availability Zone, and you can attach Elastic IP addresses, which is useful when another system needs to whitelist fixed IP addresses.
Gateway Load Balancer is used for network appliances like firewalls, intrusion detection systems, deep packet inspection systems, and similar tools. It works at Layer 3 and uses the GENEVE protocol on port 6081. In simple words, GWLB helps you insert security appliances into the network traffic path while still scaling them.
Sticky Sessions
Sticky sessions mean the same client keeps going to the same backend instance. This is also called session affinity. It is useful when session data is stored on the instance itself. For example, if a user logs in and their session is stored locally on one EC2 instance, sending the next request to a different instance may cause problems.
Sticky sessions can help with that, but they also create a tradeoff. If many users become stuck to the same instance, traffic may become uneven. One instance may receive more load than others. That is why sticky sessions are useful in some cases, but they are not always the best long-term design. A better design is usually to store session data outside the instance, like in ElastiCache or a database, so any instance can handle any request.
Cross-Zone Load Balancing
Cross-zone load balancing means the load balancer can distribute traffic evenly across targets in all enabled Availability Zones. Without cross-zone load balancing, traffic may be distributed only to targets in the same Availability Zone as the load balancer node that received the request. This can create uneven traffic if one Availability Zone has more instances than another.
For Application Load Balancer, cross-zone load balancing is enabled by default and there is no inter-AZ data charge for it. For Network Load Balancer and Gateway Load Balancer, it is disabled by default and inter-AZ data charges can apply if you enable it. For Classic Load Balancer, it is disabled by default, but there is no inter-AZ data charge if enabled.
SSL, TLS, and SNI
When users access a website over HTTPS, traffic between the client and the load balancer is encrypted. This uses SSL/TLS certificates. Technically, TLS is the newer protocol, but people still commonly say SSL certificate.
AWS Certificate Manager is usually used to manage certificates for load balancers. With an HTTPS listener, you need a default certificate. You can also add more certificates if the load balancer needs to support multiple domain names.
SNI means Server Name Indication. It allows one load balancer to serve multiple websites with different certificates. The client tells the server which hostname it wants during the TLS handshake, and the load balancer chooses the correct certificate. SNI works with Application Load Balancer and Network Load Balancer, but not with Classic Load Balancer.
Connection Draining and Deregistration Delay
When an instance is removed from a load balancer, you do not always want to cut active users immediately. Connection draining, or deregistration delay for ALB and NLB, gives existing requests time to finish before the instance is fully removed.
During this time, the load balancer stops sending new requests to that instance, but it allows in-flight requests to complete. The default value is usually 300 seconds, and it can be configured. If your requests are short, you can use a lower value. If your requests are long, you may need more time.
This is important during deployments and scaling events. Without a proper deregistration delay, users may see failed requests when instances are terminated or replaced.
What Is an Auto Scaling Group?
An Auto Scaling Group is used to automatically manage EC2 instances. Its main job is to keep the right number of instances running. If traffic increases, it can scale out by adding instances. If traffic decreases, it can scale in by removing instances. If an instance becomes unhealthy or gets terminated, the Auto Scaling Group can replace it.
An ASG has minimum capacity, desired capacity, and maximum capacity. Minimum capacity is the lowest number of instances the group should keep. Desired capacity is the number it tries to run right now. Maximum capacity is the upper limit so AWS does not keep launching endless instances.
Auto Scaling Groups are free by themselves. You pay for the EC2 instances and other resources they create, but the Auto Scaling Group feature does not add a separate charge.
Launch Templates and ASG Configuration
An Auto Scaling Group needs a launch template. The launch template tells AWS how to create new EC2 instances. It includes things like AMI, instance type, EC2 user data, EBS volumes, security groups, SSH key pair, IAM role, network settings, and other instance configuration.
This is important because the ASG can only create good instances if the launch template is correct. If the AMI is outdated, user data is broken, or the security group is wrong, the ASG will keep launching instances with the same mistake. So in production, the launch template should be tested properly before using it in an Auto Scaling Group.
When you connect an ASG to a load balancer, new instances can automatically register with the load balancer. This is what makes the architecture practical. The ASG creates instances, the load balancer checks their health, and healthy instances start receiving traffic.
Scaling Policies
Auto Scaling can use CloudWatch alarms and scaling policies. A CloudWatch alarm watches a metric, like average CPU utilization across the Auto Scaling Group. When the metric crosses a threshold, the ASG can add or remove instances.
Target tracking scaling is one of the easiest scaling policies. You set a target, like keeping average CPU around 40%, and AWS adjusts capacity to stay near that target. Simple scaling and step scaling are more manual. For example, if CPU goes above 70%, add two instances. If CPU goes below 30%, remove one instance.
Scheduled scaling is used when you already know the traffic pattern. For example, if traffic always increases every Friday at 5 PM, you can schedule the ASG to increase capacity before that time. Predictive scaling goes one step further and forecasts future load, then schedules capacity ahead of time.
Good scaling metrics depend on the application. CPU utilization is common, but it is not always the best metric. For web applications behind an ALB, RequestCountPerTarget can be very useful because it keeps the number of requests per instance stable. Network input and output are useful if the application is network bound. You can also publish custom metrics to CloudWatch if your application has a specific business or performance signal.
Scaling Cooldowns
After a scaling action happens, the Auto Scaling Group enters a cooldown period. The default cooldown is 300 seconds. During this time, the ASG gives the system time to stabilize before launching or terminating more instances.
Cooldown matters because metrics need time to reflect the new capacity. If AWS adds instances and immediately checks the same metric again, it may scale too aggressively. A cooldown helps avoid unnecessary scaling actions.
A good practical tip is to use a ready-to-use AMI. If your instance takes a long time to install packages and configure itself, scaling becomes slow. But if the AMI already contains most of the setup, the instance can become ready faster, and your application can respond to traffic changes more smoothly.
Instance Refresh
Instance Refresh is used when you update the launch template and want to replace existing EC2 instances with new ones. For example, maybe you created a new AMI with a new application version. The Auto Scaling Group can gradually replace old instances with new instances.
This is better than manually terminating every instance. You can define a minimum healthy percentage so the ASG keeps enough healthy instances running during the refresh. You can also set warm-up time, which tells AWS how long a new instance needs before it should be counted as ready.
Instance Refresh is very useful for rolling updates. It helps update the fleet without taking the whole application down at once.
Common Mistakes
One common mistake is thinking that one bigger server always solves scaling. Vertical scaling is simple, but it has a hardware limit and can still leave you with one main point of failure. For web applications, horizontal scaling with multiple instances is usually more flexible.
Another mistake is putting multiple instances behind a load balancer but keeping all of them in one Availability Zone. That may help with traffic, but it does not fully solve availability. If that Availability Zone has a problem, the application can still go down.
Another mistake is forgetting health checks. If health checks are wrong, the load balancer may send traffic to broken instances, or it may mark healthy instances as unhealthy. The health check path should reflect whether the application is actually ready to serve traffic.
Another mistake is scaling only on CPU when CPU is not the real bottleneck. Some applications are limited by network, memory, database connections, queue depth, or request count. The scaling metric should match what actually represents load for the application.
Quick Summary
High Availability and Scalability are core ideas in AWS architecture. Scalability means the system can handle more load. High Availability means the system can survive failures. For EC2 applications, the usual design is multiple instances across multiple Availability Zones, an Elastic Load Balancer in front, and an Auto Scaling Group controlling capacity.
Application Load Balancer is best for HTTP and HTTPS applications, especially when routing by path or hostname. Network Load Balancer is best for high-performance TCP, TLS, or UDP traffic. Gateway Load Balancer is for network appliances. Auto Scaling Groups help add, remove, replace, and refresh EC2 instances based on demand and health.
The main exam idea is simple: use load balancers to distribute traffic, health checks to avoid bad instances, multiple Availability Zones for availability, and Auto Scaling Groups for automatic capacity management. If you understand that flow, High Availability and Scalability becomes much easier to remember.