The situation
A travel company runs a booking platform in eu-west-2. The architecture was drawn on a whiteboard in the first month and has not changed since.
Three EC2 instances run the web and application tiers behind a load balancer. One RDS for MySQL instance holds the bookings, with a second instance beside it that a nightly script replicates to. Static assets, images and the booking confirmations in PDF live in an S3 bucket. Everything was launched into the same subnet, which means everything is in eu-west-2a.
In March that Availability Zone had a four-hour disruption. The load balancer had no healthy targets, the database and its copy were both unreachable, and the platform was down for the duration. The team had described the architecture as redundant, because there were three web servers and two databases.
Three requirements come out of the review. The platform has to survive the loss of an Availability Zone. Customers in Australia, who make up a fifth of bookings, are complaining about page load times of six to nine seconds. And the legal team has asked whether booking records for European customers can be guaranteed to stay in Europe.
What actually matters
Start with what redundancy means, because the team had the right count and the wrong distribution. Three instances protect against one instance failing. They protect against nothing if all three depend on the same power, the same cooling and the same building. Availability Zones give independent failure domains inside a Region. Each is one or more discrete data centres with separate, redundant power infrastructure, networking and connectivity, and common points of failure such as generators and cooling equipment are not shared between zones. Zones sit up to around 100km apart, far enough that one flood or fire does not take two of them, close enough for synchronous replication at single-digit millisecond latency. Redundancy is a property of how the copies are spread, not of how many there are.
Then separate the three requirements, because they are not variations of one problem. Surviving a zone failure is a Region-internal question answered by Availability Zones. Six-second page loads in Australia are a distance problem, answered at the edge. Keeping records in Europe is a Region-selection question and has nothing to do with either. A design that solves one and assumes it has solved the others is how a review finishes with two of three requirements still open.
The nightly replication script is a separate problem. A copy made once a day means that losing the primary loses up to a day of bookings, and a booking platform that loses a day of bookings has a commercial problem rather than a technical one. Recovery point and recovery time are separate numbers, and a nightly script is a poor answer on both. There is a managed option that makes the standby synchronous and the failover automatic, and knowing that it exists is the difference between a design that recovers in minutes and one that recovers in a morning.
Finally, distance and caching are not the same lever. Static assets served from London to Sydney travel the same distance every time unless something caches them closer. Dynamic requests, the ones that actually query availability, cannot be cached in the same way, but they can still travel over a better path. Those are two different mechanisms, and the requirement usually says which one the traffic needs.
What we’ll filter on
- Survives the loss of one Availability Zone with no manual intervention.
- Recovery point measured in seconds rather than hours.
- Improves latency for users on the other side of the world.
- Keeps European booking records inside Europe.
- Achievable without running a second Region’s worth of infrastructure.
The landscape
A single Availability Zone is where the platform is now. Everything is cheap, everything is close together, and one power event takes all of it. It is a valid choice for a development environment and for nothing that has customers.
Multiple Availability Zones in one Region spreads the same resources across independent failure domains connected by high-bandwidth, low-latency links. The load balancer distributes across zones and stops sending traffic to targets that fail their health checks. An Auto Scaling group spanning three zones replaces a lost instance automatically. This is the standard answer to high availability, and it is a change to placement rather than to architecture.
RDS Multi-AZ maintains a synchronous standby in a different Availability Zone and fails over to it automatically, updating the DNS record so the endpoint stays the same. In a Multi-AZ DB instance deployment the standby takes no read traffic; it is there for availability. Recovery point is effectively zero because the replication is synchronous. A Multi-AZ DB cluster is the other shape, with two standbys that do serve reads.
RDS read replicas are asynchronous copies that do serve reads, which takes query load off the primary. They can be promoted to standalone instances, which makes them useful in a recovery plan, but you create and promote them yourself, and the replication lag means some writes may be missing. Read replicas and Multi-AZ answer different questions and a good design often has both.
A second Region protects against the loss of an entire Region and puts infrastructure near a distant user base. It is the largest step available: data has to be replicated across Regions, deployments have to reach both, costs roughly double, and data residency has to be thought about deliberately rather than inherited. It is what a sovereignty requirement or a Region-level failure calls for, and an expensive way to fix slow images.
Amazon CloudFront caches content at edge locations, which number in the hundreds against a few dozen Regions, and which include points of presence in Sydney, Melbourne, Brisbane and Perth. A request from Sydney terminates at a nearby edge rather than crossing the world, and cached objects are served from there. A request that must reach the origin still terminates at the edge and travels on from there over the AWS network rather than the public internet.
AWS Global Accelerator provides static anycast IP addresses and routes traffic over the AWS global network to the best healthy endpoint, chosen on client location, endpoint health and the weights you set. It does not cache. Its listeners take TCP or UDP, which covers non-HTTP protocols, and it shifts traffic away from a Regional endpoint that stops passing health checks.
Local Zones and Outposts put AWS infrastructure closer to a particular place. A Local Zone extends a Region into a metropolitan area; an Outpost is a rack or server of AWS-managed capacity installed at your own site and operated as part of a Region. Both answer a latency or residency requirement that no Region can meet, and neither is what a booking website in Sydney needs.
Evaluation
Side by side
| Option | Survives an AZ loss | Recovery point in seconds | Helps distant users | Keeps data in Europe | No second Region to run |
|---|---|---|---|---|---|
| Single Availability Zone | ✗ | ✗ | ✗ | ✓ | ✓ |
| Instances across three AZs | ✓ | n/a | ✗ | ✓ | ✓ |
| RDS Multi-AZ | ✓ | ✓ | ✗ | ✓ | ✓ |
| RDS read replica | ✗ | Depends | Partly | ✓ | ✓ |
| A second Region | ✓ | Depends | ✓ | ✗ | ✗ |
| Amazon CloudFront | n/a | n/a | ✓ | ✓ | ✓ |
| AWS Global Accelerator | n/a | n/a | ✓ | ✓ | ✓ |
The three requirements are satisfied by three different rows, and no row satisfies all three. Multi-AZ placement and RDS Multi-AZ cover the zone failure. CloudFront covers the Australian latency without moving any data out of Europe. The Region row is the one that fails the residency column, and it is the row a team reaches for when it treats “users are far away” and “we need to survive a failure” as the same requirement.
What each layer protects against
| Failure | Instance in one AZ | Instances across AZs | Multi-Region |
|---|---|---|---|
| One instance fails | ✗ | ✓ | ✓ |
| One data centre loses power | ✗ | ✓ | ✓ |
| One Availability Zone is disrupted | ✗ | ✓ | ✓ |
| An entire Region is unavailable | ✗ | ✗ | ✓ |
| A user is 17,000km from the Region | ✗ | ✗ | ✓, or use an edge service |
The solution
Spread what already exists before adding anything. Create subnets in eu-west-2a, eu-west-2b and eu-west-2c, and put the web and application instances in an Auto Scaling group spanning all three, behind an Application Load Balancer configured across the same three zones. The load balancer health-checks its targets and routes only to healthy ones, so a zone whose instances are failing stops receiving requests; the scaling group launches replacements in a zone that is still up. Nothing about the application changes, and the March failure becomes a period of reduced capacity rather than an outage.
Replace the nightly script with RDS Multi-AZ. The standby sits in a different Availability Zone, replication is synchronous, and failover is automatic. The DNS record moves to the standby, so the endpoint does not change and the application keeps its connection string, though open connections have to be re-established. That takes the recovery point from up to twenty-four hours to effectively zero, and the recovery time from a morning’s work to the 60 to 120 seconds a failover typically runs to. If read traffic is also heavy, add a read replica alongside it: the two features coexist, and they answer different problems. Keep taking backups regardless: replication is synchronous, so a deletion lands on the standby as well.
Put CloudFront in front of the platform for the Australian users. The static assets, images and PDFs cache at edge locations close to Sydney and Melbourne, which takes the London round trip out of most of the page load. Dynamic booking requests still reach the origin in London, but they terminate at the edge and cross the AWS network rather than the public internet, which puts fewer networks in the path than they cross today. The data stays in eu-west-2; an edge cache holds copies of assets, and the cache behaviour for anything containing personal data should be set to not cache at all.
The residency question is answered by Region choice and worth writing down clearly. Resources are Regional: objects stored in a Region never leave it unless you explicitly transfer or replicate them, and the same holds for the database and its standby. Keeping the booking records in Europe therefore means not adding cross-Region replication on the S3 bucket, not creating a cross-Region read replica, and setting CloudFront’s cache behaviour so that responses containing personal data are not stored at the edge. The answer to the legal team is a set of decisions rather than a property that happens automatically.
Leave the second Region out of this round. Nothing on the requirement list needs it: zone independence handles the failure mode that actually occurred, CloudFront handles the distance, and a second Region would create exactly the data residency question the legal team is trying to close. Revisit it if the business ever states a recovery objective that survives the loss of a whole Region, at which point it becomes a funded programme rather than a change to a subnet.
What’s worth remembering
- An Availability Zone is one or more discrete data centres with separate, redundant power infrastructure, networking and connectivity; generators and cooling are not shared between zones, and high availability inside a Region comes from spreading across them.
- Redundancy is about distribution, not count. Three instances in one zone survive one instance failing and nothing else.
- RDS Multi-AZ is a synchronous standby with automatic failover, for availability, and in a DB instance deployment it serves no reads; a read replica is an asynchronous copy that does serve reads, for performance. They can be used together.
- Use multiple Regions for disaster recovery, data sovereignty, or users on another continent. It is the largest step and it introduces its own residency questions.
- Edge locations outnumber Regions by a wide margin; CloudFront caches there, and Global Accelerator routes over the AWS global network on static anycast IPs without caching.
- Data stays in the Region it was placed in unless you explicitly transfer or replicate it, so residency is a set of deliberate choices about replication and caching rather than an automatic guarantee.