Impossible travel is one of the oldest and most intuitive fraud signals: a user authenticates from New York, then eleven minutes later from Singapore. No aircraft covers that distance that fast, so one of those sessions is not the real account holder. It is a clean idea that account takeover teams reach for early, because it needs no machine learning and maps directly to human intuition.
The trouble is that the clean idea drowns in noise the moment it meets real traffic. VPNs, corporate proxies, mobile carrier gateways, and imprecise IP geolocation all conspire to make legitimate users look like teleporting attackers. This article explains how the computation works, where it breaks, and how device-level identity turns a noisy heuristic into a reliable input for account takeover prevention.
The core computation
Impossible travel is fundamentally a velocity check. For two consecutive authenticated events, you compute the great-circle distance between their locations and divide by the elapsed time. If the implied speed exceeds a threshold, you flag the pair.
from math import radians, sin, cos, asin, sqrt
def haversine_km(lat1, lon1, lat2, lon2):
r = 6371.0
dlat = radians(lat2 - lat1)
dlon = radians(lon2 - lon1)
a = sin(dlat/2)**2 + cos(radians(lat1))*cos(radians(lat2))*sin(dlon/2)**2
return 2 * r * asin(sqrt(a))
def implied_kmh(ev1, ev2):
dist = haversine_km(ev1.lat, ev1.lon, ev2.lat, ev2.lon)
hours = abs(ev2.ts - ev1.ts) / 3600.0
return dist / hours if hours > 0 else float('inf')
# implied_kmh > 900 roughly exceeds commercial flight speed
The threshold is a policy choice. Commercial aircraft cruise around 900 km/h, so a naive rule flags anything faster. But the moment you pick a number, you inherit two problems: the locations you feed in are approximate, and the elapsed time can be tiny, which makes the implied speed explode from small geolocation errors.
Why IP geolocation lies
The distance calculation is only as good as the coordinates, and IP-based coordinates are frequently wrong. Understanding the failure modes is the difference between a signal you trust and one that pages your on-call at 3am.
- VPNs and privacy tools place the user wherever the exit node lives. A user who enables a VPN mid-session appears to jump continents instantly.
- Corporate egress routes an entire office through one gateway, sometimes in a different country from the employees.
- Mobile carriers aggregate traffic through regional gateways; a phone in one city can present an IP that geolocates hundreds of kilometers away.
- Database imprecision means IP-to-location mappings resolve to a city centroid or a country default, not the real position. See our MaxMind GeoLite2 guide and IP geolocation spoofing.
- CGNAT and IP churn reassign addresses across regions faster than databases update.
The result: a large share of “impossible travel” alerts on raw IP data are legitimate users doing nothing wrong. If you block on the raw signal, you punish travelers, remote workers, and anyone with a VPN. For deeper background on the underlying data, see ASN and geolocation fraud and IP reputation.
Device identity changes the equation
The fix is to stop treating the IP as the identity. A stable device fingerprint tells you whether the same physical device is present in both events, regardless of what the network says.
Consider the two interpretations of an impossible-travel pair:
| Scenario | Same device? | Interpretation |
|---|---|---|
| VPN toggled mid-session | Yes | Benign relocation, not travel |
| Traveler on airport WiFi | Yes | Same person, new network |
| Stolen credentials, new machine | No | Genuine takeover risk |
| Session token replayed elsewhere | No | Hijack or sharing |
When the device is the same across both events, an impossible-travel flag usually means the network moved, not the person — a VPN, a roaming phone, a proxy. When the device is different, the geographic jump corroborates a real account takeover. Device continuity converts an ambiguous distance number into a confident decision. This is why impossible travel should never run on IP alone; it should run on device plus IP together. Related reads: new device login detection and session hijacking detection.
Building a signal that survives production
A production-grade impossible-travel detector is a scored pipeline, not a single rule. The components:
- Resolve location from IP, but attach a confidence radius. A city-level match is not a point; treat it as a circle. Subtract the radius before computing distance so you do not flag inside the error margin.
- Classify the network on both ends: VPN, Tor, datacenter, residential proxy, or clean. A VPN on either side downgrades the impossible-travel weight. See VPN detection and proxy detection.
- Check device continuity using the visitor ID. Same device across the jump is a strong benign indicator.
- Score, do not block. Feed the result into a suspect score with reason codes so analysts see why an event fired.
- Respond proportionally. High score plus new device plus clean-to-datacenter jump warrants step-up auth or a hold. A same-device VPN jump warrants nothing.
This staged approach is the backbone of a modern credential stuffing and ATO program, where impossible travel is one input among device, behavior, and reputation signals rather than the whole system.
Tuning thresholds and windows
Two parameters dominate the false-positive rate: the speed threshold and the time window.
- A very short elapsed time between events makes implied speed unstable. Enforce a minimum elapsed floor (for example, ignore pairs under a few minutes) so a small distance error does not read as supersonic travel.
- A single global speed threshold is crude. Regional travel patterns differ; a 900 km/h line works for flights but misclassifies fast rail corridors and dense metro areas where geolocation error alone spans the threshold.
- Consider a graduated response: below one threshold, log only; above a second, step up authentication; above a third with a new device, block pending verification.
Track outcomes with bot and fraud KPIs and keep the false-positive budget explicit, because impossible travel is a signal users notice immediately when it misfires on their vacation.
Frequently asked questions
What counts as impossible travel?
Two authenticated events from locations far enough apart that no physical travel could cover the distance in the elapsed time. If the implied speed exceeds a plausible threshold, the pair is flagged.
Why does impossible travel produce so many false positives?
IP geolocation is imprecise, VPNs and corporate egress relocate users, and mobile carriers route traffic through distant gateways. Naive distance rules treat all of these as impossible travel.
Is impossible travel enough to block a login on its own?
No. It is a strong signal but not proof. Pair it with device identity and network reputation, and use step-up authentication rather than a hard block.
Impossible travel earns its place in an ATO program, but only when it stops trusting the IP as the identity. Anchor it to a stable device, classify the network on both ends, score instead of block, and respond in proportion to the evidence. Done that way, the oldest fraud heuristic becomes one of the most dependable. Explore the signals in the playground or read the docs to wire it into your login flow.
Run it yourself
Prynt is open-source, self-hostable device intelligence — visitor IDs, bot & fraud Smart Signals, and behavioral biometrics you own end to end.