Geolocation routing lets you direct traffic to different resources based on the geographic location of your users.
Let’s see it in action. Imagine you have a website hosted in two AWS regions, us-east-1 and eu-west-1. You want users in the US to hit the us-east-1 instance and users in Europe to hit the eu-west-1 instance.
Here’s a simplified Route 53 record set configuration:
{
"Comment": "Geolocation routing example",
"Changes": [
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "example.com",
"Type": "A",
"SetIdentifier": "us-east-1-us",
"TTL": 300,
"Region": "us-east-1",
"GeoLocation": {
"ContinentCode": "NA"
},
"AliasTarget": {
"HostedZoneId": "Z1UJRXOUMOOFQ8",
"DNSName": "dualstack.my-elb-us.us-east-1.elb.amazonaws.com."
}
}
},
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "example.com",
"Type": "A",
"SetIdentifier": "eu-west-1-eu",
"TTL": 300,
"Region": "eu-west-1",
"GeoLocation": {
"ContinentCode": "EU"
},
"AliasTarget": {
"HostedZoneId": "Z2NY5P3367T49C",
"DNSName": "dualstack.my-elb-eu.eu-west-1.elb.amazonaws.com."
}
}
},
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "example.com",
"Type": "A",
"SetIdentifier": "default-fallback",
"TTL": 300,
"GeoLocation": {
"CountryCode": "GE"
},
"AliasTarget": {
"HostedZoneId": "Z1UJRXOUMOOFQ8",
"DNSName": "dualstack.my-elb-us.us-east-1.elb.amazonaws.com."
}
}
}
]
}
In this setup:
- The first record set targets North America (
NA) and points to a load balancer inus-east-1. - The second record set targets Europe (
EU) and points to a load balancer ineu-west-1. - The third record set is a fallback for any location not covered by the previous rules, defaulting to the US load balancer. You could also use
Defaultas aCountryCodefor a true fallback.
Route 53 uses a sophisticated system of DNS resolvers’ IP addresses to infer the geographic location of the requesting client. When a DNS query for example.com arrives at Route 53, it looks at the IP address of the DNS resolver making the request. Route 53 then uses its internal geolocation database to map that IP address to a physical location. If a specific record set matches that location (e.g., CountryCode is "US", SubdivisionCode is "CA", or ContinentCode is "EU"), Route 53 returns the IP address(es) associated with that record set. If no specific match is found, it falls back to the record set with the most general GeoLocation or the one designated as the default.
The "SetIdentifier" is crucial. When you have multiple records with the same name and type (like multiple A records for example.com), the SetIdentifier uniquely distinguishes them. This is how Route 53 knows which specific record set to return for a given geolocation.
You can be as granular as you like, specifying countries, subdivisions (like states or provinces), or continents. For example, to direct traffic from California specifically:
{
"Name": "example.com",
"Type": "A",
"SetIdentifier": "us-east-1-california",
"TTL": 300,
"Region": "us-east-1",
"GeoLocation": {
"CountryCode": "US",
"SubdivisionCode": "CA"
},
"AliasTarget": {
"HostedZoneId": "Z1UJRXOUMOOFQ8",
"DNSName": "dualstack.my-elb-us-west.us-west-2.elb.amazonaws.com."
}
}
This would override the broader ContinentCode: NA rule for users originating from California.
The "Region" field in the ResourceRecordSet is not about where the DNS record itself is managed; it’s about the AWS region where the resource specified in AliasTarget or ResourceRecord is located. This is important for Route 53’s internal routing and for associating the record with a specific AWS health check if you configure one.
What many people don’t realize is that Route 53’s geolocation is based on the IP address of the DNS resolver that forwards the request, not necessarily the end-user’s actual IP if they are using a VPN or a different DNS server than their ISP’s default. This means a user in France using a VPN server in New York might appear to Route 53 as being in the US, and thus be routed to your US-based resources. The accuracy is dependent on the resolver’s reported location.
The next thing you’ll want to configure is latency-based routing to serve users from the geographically closest and fastest resource, rather than just the closest geographically.