Fly.io’s Anycast routing is designed to get user traffic to the closest available application instance, but the magic isn’t in choosing a region; it’s in how the internet already knows how to do that.
Let’s see it in action. Imagine you have a Fly app deployed in both New York and London.
fly deploy -a my-app -r usa-east -r "ams"
When a user in Chicago types my-app.fly.dev into their browser, their local DNS resolver doesn’t ask a single, central server for the IP address. Instead, it queries the Border Gateway Protocol (BGP) routing tables of the internet. Multiple DNS servers, distributed globally, will respond with IP addresses. The key here is that the IP address returned will be associated with a specific network edge, often a major internet exchange point (IXP) or a data center’s network. For our Chicago user, this will typically be an IP address reachable via a network path that terminates geographically closer to Chicago than, say, London.
Fly.io leverages this by announcing the same IP address range for my-app.fly.dev from its edge routers in both usa-east and ams. When a user’s DNS query for my-app.fly.dev reaches a DNS server that’s peering with a network provider near Chicago, that DNS server will resolve my-app.fly.dev to an IP address that Fly.io is announcing from its usa-east region. Conversely, a user in Berlin would resolve to an IP address announced from the ams region. The internet’s BGP routing protocol, which is the backbone of global IP routing, handles the "which path is shortest" decision before the traffic even hits Fly.io’s infrastructure.
The "nearest" is determined by BGP’s path selection algorithm, which prioritizes the shortest AS path (Autonomous System path) to the destination IP. Fly.io’s edge routers are strategically placed at major internet hubs worldwide. When you deploy your app to multiple regions, Fly.io announces the same IP address space from each of those regions. Your users’ local DNS resolvers, querying the global DNS infrastructure, will receive different IP addresses for your app depending on their geographic location. These IP addresses are all associated with your Fly app, but they are announced by different Fly.io edge routers.
The system works by advertising the same IP prefixes from multiple Fly.io points of presence (PoPs). When a user’s device performs a DNS lookup for your app’s hostname (e.g., my-app.fly.dev), the DNS servers it queries will return an IP address that is advertised by the closest Fly.io PoP. This is achieved through BGP, the internet’s routing protocol. Each Fly.io PoP announces the IP addresses associated with your app. The internet’s routers then use BGP to determine the shortest path from the user’s location to one of those advertised IP addresses.
Consider this: your app is running on VMs in usa-east and ams. Fly.io announces the IP address for my-app.fly.dev from both regions. A user in New York queries DNS. The DNS server they use, likely peered with a US-based ISP, sees that the shortest path to the IP for my-app.fly.dev is via Fly.io’s usa-east edge. The user’s browser gets that IP and connects to the usa-east instance. A user in Paris queries DNS. Their DNS server, peered with a European ISP, sees the shortest path is via Fly.io’s ams edge. They connect to the ams instance.
The actual IP addresses your users receive are not specific to a region in the traditional sense; they are global Anycast IPs. Fly.io manages the BGP announcements for these IPs from its various edge locations. When you deploy to usa-east and ams, Fly.io configures its routers in those locations to advertise the same set of Anycast IP addresses. The global routing fabric of the internet then naturally directs traffic to the nearest advertised source based on BGP routing policies.
The mental model is that you’re not choosing a region for the user; you’re participating in a global routing system that selects the region for you. Fly.io’s role is to ensure that the same "destination" (your app’s IP) is advertised from multiple points, allowing the internet to pick the closest one.
What most people don’t realize is that the "nearest" isn’t necessarily the closest data center by physical distance. It’s the closest by network path as determined by BGP. A user in a city with a major internet exchange point might be routed to a PoP that’s physically further away but has a more direct, lower-latency connection via that IXP.
The next step is understanding how to manage application state and data consistency when instances can be geographically distributed.