Everyone’s first AWS question is some version of “where should I put this thing?” So you pick us-east-1 because the console defaulted to it, launch a server, and move on. Sometimes that’s fine. Sometimes you find out six months later that your users are on the other side of the planet, or that legal wanted the data to stay in Europe.
This post sorts out the whole picture: Regions, Availability Zones, Local Zones, Wavelength and edge locations. Then it shows you how to pick a Region with numbers instead of guesses. The AWS CLI output comes from a real Free Tier account (account IDs removed), and the latency tests ran on Ubuntu 26.04.1 LTS and AlmaLinux 10.2.
New to AWS? AWS Fundamentals for Linux Admins covers the basics first. Everything below uses AWS CLI v2.
AWS Regions versus Availability Zones, in plain words
A Region is a geographic area, like Ireland or Mumbai. Each Region is isolated from the others, so a problem in one doesn’t spread to the rest. Inside every Region you get several Availability Zones (AZs). An AZ is one or more data centers with their own power, cooling and networking, close enough to each other for fast links but far enough apart that one fire or flood doesn’t take out all of them.
Here’s the same idea as a list, including the newer pieces we’ll get to later:
| Layer | What it is | Example name |
|---|---|---|
| Region | A geographic area with multiple AZs | eu-west-1 |
| Availability Zone | One or more data centers inside a Region | eu-west-1a |
| Local Zone | A small extension of a Region near a big city | us-east-1-bos-1a |
| Wavelength Zone | AWS compute inside a telecom carrier’s 5G network | eu-west-2-wl2-man-wlz-1 |
| Edge location | A CloudFront and Route 53 point of presence, no general compute | SIN2-P4 |
Let’s see them for real. Ask AWS which Regions your account can use right now, and which AZs one Region has:
aws ec2 describe-regions --query 'length(Regions)'
aws ec2 describe-availability-zones --region us-east-1 \
--query 'AvailabilityZones[].[ZoneName,ZoneId,ZoneType,State]' --output table
17
--------------------------------------------------------------
| DescribeAvailabilityZones |
+------------+-----------+---------------------+-------------+
| us-east-1a| use1-az1 | availability-zone | available |
| us-east-1b| use1-az2 | availability-zone | available |
| us-east-1c| use1-az4 | availability-zone | available |
| us-east-1d| use1-az6 | availability-zone | available |
| us-east-1e| use1-az3 | availability-zone | available |
| us-east-1f| use1-az5 | availability-zone | available |
+------------+-----------+---------------------+-------------+
Seventeen Regions are usable, and us-east-1 has six AZs. Other Regions have fewer, eu-west-1 in my account shows three. Notice the second column, though. We’ll come back to those IDs, because they matter more than the names.
How to choose an AWS Region for latency, cost and data residency
Four things decide it, and they often pull in different directions.
Latency. Distance to your users matters, but so does the network path. The Region that looks closest on a map isn’t always the fastest. More on measuring that in a minute.
Cost. The same instance costs different amounts in different Regions. I pulled on-demand Linux prices for a t3.micro from the AWS Price List API:
| Region | t3.micro per hour | Compared with us-east-1 |
|---|---|---|
| US East (N. Virginia) | $0.0104 | baseline |
| Asia Pacific (Mumbai) | $0.0112 | about 8% more |
| EU (Ireland) | $0.0114 | about 10% more |
| Asia Pacific (Singapore) | $0.0132 | about 27% more |
| South America (Sao Paulo) | $0.0168 | about 62% more |
One small instance won’t hurt. Hundreds of them, plus storage and data transfer, will. Prices also change, so check the AWS Pricing Calculator before you commit.
Data residency. If a law or a contract says customer data must stay in a country or a bloc, the Region is how you enforce it. AWS doesn’t move your data to another Region on its own. You’re the one who would, by turning on replication or copying a backup. So this is the one factor that can overrule the other three.
Service availability. Not every service exists everywhere. I’ll show you how to check, since it can rule out a Region before you’ve written any code.
Measure user latency before choosing an AWS Region
Don’t guess. Every Region has a public endpoint, and the TCP connect time to it is roughly one network round trip. That’s a decent first signal. This runs on Ubuntu and RHEL as is, since curl ships on both:
for r in us-east-1 us-west-2 eu-west-1 eu-central-1 ap-south-1 ap-southeast-1 sa-east-1; do
best=$(for i in 1 2 3 4 5; do
curl -s -o /dev/null -w '%{time_connect}\n' "https://ec2.$r.amazonaws.com/"
done | sort -n | head -1)
printf '%-16s %s\n' "$r" "$(awk -v t="$best" 'BEGIN{printf "%.0f ms", t*1000}')"
done | sort -k2 -n
It takes five samples per Region and keeps the best one, so a random hiccup doesn’t skew things. Here’s what came back from my Ubuntu 26.04 box:
ap-southeast-1 152 ms
eu-central-1 199 ms
eu-west-1 212 ms
ap-south-1 221 ms
us-east-1 267 ms
sa-east-1 353 ms
us-west-2 371 ms
AlmaLinux 10 gave the same order, within a few milliseconds. And look at it: us-east-1, the default everyone picks, comes fifth. For users sitting where my test machine sits, Singapore is about 115 ms closer. Your numbers will differ, because they depend on where you run the test. So run it from where your users are, or from a few cloud VMs in their cities, before you decide.
Keep in mind what this measures. It’s the network path only. It says nothing about how fast your app responds once it gets there.
Regional service availability and opt-in Regions
Two gotchas catch people out. First, some Regions are switched off by default. Regions launched after March 2019 need you to opt in. Here’s how many my account has, and which ones:
aws ec2 describe-regions --all-regions --query 'length(Regions)'
aws ec2 describe-regions --all-regions \
--query 'Regions[?OptInStatus==`not-opted-in`].RegionName' --output text
34
ap-south-2 eu-south-1 eu-south-2 me-central-1 il-central-1 ap-east-2 mx-central-1 eu-central-2 af-south-1 me-south-1 ap-east-1 ca-west-1 ap-southeast-3 ap-southeast-4 ap-southeast-5 ap-southeast-6 ap-southeast-7
So 17 are on by default and 17 more need a deliberate opt-in. Enabling one is a single command, though it can take a while to finish:
aws account enable-region --region-name ap-east-1
Second, services don’t launch everywhere at once. AWS publishes the list as public SSM parameters, so you can check from the terminal. Here I compared EC2 against Amazon Bedrock:
for s in ec2 bedrock; do
aws ssm get-parameters-by-path \
--path /aws/service/global-infrastructure/services/$s/regions \
--query 'Parameters[].Value' --output text | tr '\t' '\n' | sort > $s.txt
done
wc -l ec2.txt bedrock.txt
comm -23 ec2.txt bedrock.txt
39 ec2.txt
36 bedrock.txt
75 total
ap-east-1
cn-north-1
cn-northwest-1
EC2 is listed in 39 places and Bedrock in 36. That 39 is bigger than my account’s 34 because it also counts the two China Regions, two GovCloud Regions and the European Sovereign Cloud, which a normal account can’t use. Among the Regions I could use, Bedrock was missing from ap-east-1 (Hong Kong). Finding that out after you’ve built everything there is an unpleasant afternoon. Check first.
Multi-AZ versus multi-Region architecture
This is the question people overthink. Here’s the short version.
Multi-AZ protects you from a data center problem. It’s cheap, fast and mostly built into the services. Put your instances behind a load balancer in at least two AZs. Turn on Multi-AZ for RDS. Remember that an EBS volume lives in one AZ only, so a replacement server in another AZ needs a snapshot, not a reattach. S3 and DynamoDB already spread data across AZs for you. Traffic between AZs isn’t free, but the per-GB charge is small.
Multi-Region protects you from a whole Region going down, and from distance. It’s also far more work. You’re running two copies of everything, replicating data asynchronously, and deciding what happens when the copies disagree. You pay for the duplicate infrastructure and for inter-Region data transfer.
My rule of thumb: go multi-AZ almost always, and go multi-Region only when you have a clear reason. Good reasons are a strict recovery requirement, users on several continents, or a rule that demands a second geography. “It feels safer” doesn’t count. A well-built multi-AZ setup survives the failures you’re most likely to see.
AWS Local Zones, Wavelength Zones and edge locations
These sit closer to users than a Region does, but they do different jobs.
Local Zones put a limited set of services, mostly EC2, EBS and a few more, in a big metro area. They’re managed as part of a parent Region. My account sees 14 of them under us-east-1, all switched off until I opt in:
aws ec2 describe-availability-zones --region us-east-1 --all-availability-zones \
--query 'AvailabilityZones[?ZoneType==`local-zone`].[ZoneName,OptInStatus,GroupName]' --output table
| us-east-1-atl-2a | not-opted-in | us-east-1-atl-2 |
| us-east-1-atl-2b | not-opted-in | us-east-1-atl-2 |
| us-east-1-bos-1a | not-opted-in | us-east-1-bos-1 |
| us-east-1-bue-1a | not-opted-in | us-east-1-bue-1 |
| us-east-1-chi-2a | not-opted-in | us-east-1-chi-2 |
The three letters in the name hint at the city (bos is Boston, chi is Chicago). You opt in per group, not per zone:
aws ec2 modify-availability-zone-group --region us-east-1 \
--group-name us-east-1-bos-1 --opt-in-status opted-in
Wavelength Zones are for apps that talk to 5G devices. The compute sits inside a carrier’s network, so traffic from phones never has to leave it. They only exist in a few Regions. In mine, eu-west-2 and ap-northeast-1 showed some:
eu-west-2-wl2-man-wlz-1 not-opted-in
ap-northeast-1-wl1-kix-wlz-1 not-opted-in
ap-northeast-1-wl1-nrt-wlz-1 not-opted-in
Edge locations are different. You can’t run your own servers there. They serve cached content for CloudFront and answer DNS for Route 53. You can even see which one served you, because CloudFront puts it in a response header:
curl -sI https://docs.aws.amazon.com/ | grep -i -E '^(x-cache|x-amz-cf-pop)'
X-Cache: Hit from cloudfront
X-Amz-Cf-Pop: SIN2-P4
That’s the Singapore edge, and it answered from cache. The airport-style code at the front is the city. Same result on Ubuntu and AlmaLinux.
Plan cross-Region replication and regional data boundaries
Replicating to a second Region is easy to switch on and easy to regret. So think about the boundary first.
Ask which data is actually allowed to leave. If your rule is “EU customer data stays in the EU”, then a backup bucket in us-east-1 breaks it, even if nobody ever reads it. Pick a destination inside the same boundary, like eu-central-1 for an eu-west-1 source.
For S3, replication needs versioning on both buckets, and it only copies new objects after you turn it on. It’s asynchronous, so a copy can lag behind, and replicated objects aren’t replicated again to a third bucket. A minimal config looks like this:
aws s3api put-bucket-versioning --bucket my-app-prod-eu-west-1 \
--versioning-configuration Status=Enabled
aws s3api put-bucket-versioning --bucket my-app-backup-eu-central-1 \
--versioning-configuration Status=Enabled
cat > replication.json <<'EOF'
{
"Role": "arn:aws:iam::111122223333:role/s3-replication-role",
"Rules": [
{
"ID": "all-objects-to-frankfurt",
"Status": "Enabled",
"Priority": 1,
"Filter": {},
"DeleteMarkerReplication": { "Status": "Disabled" },
"Destination": { "Bucket": "arn:aws:s3:::my-app-backup-eu-central-1" }
}
]
}
EOF
aws s3api put-bucket-replication --bucket my-app-prod-eu-west-1 \
--replication-configuration file://replication.json
The bucket names and role ARN above are placeholders, and I haven’t run this against real buckets, so swap in your own. Don’t trust a boundary just because you were careful, either. Enforce it. A Service Control Policy in AWS Organizations can deny anything outside the Regions you approve, while leaving global services like IAM alone:
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "DenyOutsideApprovedRegions",
"Effect": "Deny",
"NotAction": ["iam:*", "organizations:*", "route53:*", "cloudfront:*", "support:*", "sts:*"],
"Resource": "*",
"Condition": {
"StringNotEquals": { "aws:RequestedRegion": ["eu-west-1", "eu-central-1"] }
}
}]
}
One more thing. Some services are global, such as IAM, Route 53 and CloudFront. Their control plane isn’t tied to your Region, so read the docs before you claim “nothing leaves the EU”.
Availability Zone names, IDs and cross-account mapping
Here’s the part that surprises people. The name us-east-1a isn’t the same physical zone for every account. AWS maps names to zones separately per account, which spreads load so everyone doesn’t pile into “a”. The ID is the stable one. From my account, earlier:
aws ec2 describe-subnets --region us-east-1 --filters Name=default-for-az,Values=true \
--query 'Subnets[].[AvailabilityZone,AvailabilityZoneId]' --output table
| us-east-1a | use1-az1 |
| us-east-1e | use1-az3 |
| us-east-1d | use1-az6 |
| us-east-1f | use1-az5 |
| us-east-1b | use1-az2 |
| us-east-1c | use1-az4 |
In my account, us-east-1a is use1-az1. In a teammate’s account, us-east-1a could be use1-az4. When does this bite? When two accounts need to line up. Say you share subnets with AWS RAM, or you want your app and a partner’s endpoint in the same physical zone to avoid cross-AZ traffic. Compare IDs, never names.
You can also build with IDs directly. The CLI takes --availability-zone-id, and Terraform’s aws_subnet has an availability_zone_id argument:
aws ec2 create-subnet --vpc-id vpc-0abc1234 --cidr-block 10.0.1.0/24 \
--availability-zone-id use1-az1
(That VPC ID is a placeholder.) If you’re planning address ranges for those subnets, CIDR and Subnetting Explained helps, and AWS VPC Explained shows where subnets fit.
Frequently asked questions
How many Availability Zones should I use?
Two is the practical minimum for high availability, and three is better if the Region has them, since you can lose one and still keep two-thirds of your capacity.
Is us-east-1 a bad choice?
No. It’s the cheapest of the five Regions I checked and it launches new services early. It’s a bad choice only when your users, your data rules or your latency numbers point somewhere else.
Can I change a resource’s Region later?
Not in place. You create a new copy in the target Region and move the data over, with an AMI copy, a snapshot copy or replication. Picking well on day one saves a migration.
Do I pay to opt in to a Region or a Local Zone?
Opting in itself isn’t the cost. The resources you run there are. But prices can differ from your home Region, so check before you launch.
Why do my AZ names differ from a colleague’s?
Because names are mapped per account. Compare the zone IDs, like use1-az1, which are the same for everyone.
Where to go next
Run the latency script from the places your users actually are, and write the numbers down next to the price table. That’s your Region decision, backed by data. Then read AWS VPC Explained to lay out subnets across your AZs. The official AWS Regions and Availability Zones documentation is worth a bookmark for the current numbers, since AWS keeps adding Regions and zones.