We have ipinfo at home or how to geolocate IPs in your CLI using latency
Source: Hacker News
TL;DR
I made a CLI tool that can resolve an IP address to a country, US state and even a city.
GitHub – geolocation‑tool
It works well and confirms ipinfo’s findings.
Background
Recently I read how ipinfo finally proved what most technical people assumed: VPN providers don’t actually maintain a crazy amount of infrastructure in hundreds of countries. They simply fake the IP geolocation by intentionally providing wrong location data to ARIN, RIPE and Geo‑DB providers via geofeeds.
Their results come from a novel approach compared to other Geo‑IP providers. Based on their blog and Hacker News comments, they built a large probe network and used it to trace and ping every (or most) IP address on the Internet.
This latency and hop data—combined with advanced algorithms and cross‑referencing—provides a reliable way of correctly detecting the physical geolocation of an IP address, without relying on the faked data available in public sources.
The approach makes total sense, and I’m sure their clients appreciate it and heavily rely on it.
My Experiment
I can’t ping every single IP address from hundreds of locations yet, but I can do it for a limited subset using Globalping. So I decided to try to replicate ipinfo’s results and build a small tool that anyone can use.
Globalping is an open‑source, community‑powered project that lets users self‑host container‑based probes. These probes become part of our public network, which anyone can use to run network‑testing tools such as ping and traceroute.

At the moment the network has more than 3 000 probes, which in theory should be plenty to geolocate almost any IP address down to a country and even a US‑state level.
To automate and simplify the process I wrote a tiny CLI tool using the globalping‑ts library. My original idea was simple:
- Accept a single IP as input.
- Ping it a few times per continent to select the continent.
- Ping the IP from many different probes on that continent.
- Group and sort the results; the country with the lowest latency should be the correct one.
- (Bonus) Repeat the same process for US states if the winning country is the US.
All I had to do was create a few measurements and pass the desired location using Globalping’s magic field, which automatically selects a few pseudo‑random probes that match the location and limit.
Implementation Details
- Initial attempt – ICMP ping (2 packets) – too fast, but most networks block ICMP.
- Switch to TCP‑based ping – required trying several popular ports; proved complicated and unreliable.
- Final solution – traceroute – works perfectly. Even when the target blocks ICMP, the upstream network usually allows it, and the last hop is typically in the same country.
The resulting data isn’t 100 % perfect. A more robust solution would:
- Use multiple methods (TCP, UDP traceroute on different ports).
- Analyse the last few hops instead of just one.
- Combine ASN registration data and public WHOIS info in a weighted “vote”.
- Mark low‑certainty IPs for retesting with more probes.
That’s a job for a commercial provider – which is exactly what ipinfo appears to have done.
Continent Detection
I used 5 probes per continent. The results were extremely accurate; only IPs right on a continental “border” might need more probes.
Example – my home IP (central Europe):
Phase 1: Detecting continent...
North America: 137.18 ms
Europe: 32.39 ms
Asia: 174.54 ms
South America:215.08 ms
Oceania: 244.15 ms
Africa: 156.83 ms
Country Detection
Phase 2 runs a single measurement on the winning continent with a higher probe limit.
- Started with 250 probes – great accuracy.
- Dropped to 50 probes as the default – still very good, and it stays within the unauthenticated Globalping API limits (250 tests / hour per IP, 50 probes / measurement).
Tip: Register for a free account at dash.globalping.io and authenticate with a token to get up to 500 tests per hour.
If you need more tests, you can either:
- Host your own probe (generates passive credits), or
- Donate via GitHub Sponsors – we’ll automatically credit your account.
Example output (50‑probe run):
Phase 2: Detecting country...
Measuring from 50 probes...
[████████████████████████████████████████] 100.0% 50/50 - Best: PL (7.29 ms)
Top 3 Locations:
─────────────────────────────────────────────────
1.. Poland, EU 7.29 ms
2.. Germany, EU 13.42 ms
3.. Lithuania,EU 15.87 ms
Closing Thoughts
The approach of using latency‑based measurements from a distributed probe network is surprisingly effective for geolocation. While my CLI tool is a simple proof‑of‑concept, it demonstrates that anyone can achieve decent accuracy without relying on the (often falsified) public Geo‑IP databases.
Feel free to check out the source code, run it yourself, or contribute improvements! 🚀
SUMMARY
Location: Poland, EU
Minimum Latency: 7.29 ms
Confidence: Medium
Great, now we have a basic IP‑to‑country resolver that only takes a few seconds to provide a response, and I didn’t even have to understand or write any complicated math. Although I’m sure someone smarter could use a formula to geolocate IPs with even fewer probes and higher accuracy.
Phase 3 – Detecting US state
Phase 3: Detecting US state...
Measuring from 50 probes...
[████████████████████████████████████████] 100.0% 50/50 - Best: FL (0.45 ms)
Top 3 Locations:
─────────────────────────────────────────────────
1. Florida, USA 0.45 ms
2. South Carolina, USA 12.23 ms
3. Georgia, USA 15.01 ms
═══════════════════════════════════════════════════
SUMMARY
═══════════════════════════════════════════════════
Location: Florida, United States
Minimum Latency: 0.45 ms
Confidence: Very High
═══════════════════════════════════════════════════
The tool agrees—Florida is the correct location. But how accurate can this system be? Can we expand it to show the city too?
Phase 4 – Detecting city
Phase 4: Detecting city...
Measuring from 36 probes...
[████████████████████████████████████████] 100.0% 36/36 - Best: Miami (0.00 ms)
Top 3 Locations:
─────────────────────────────────────────────────
1. Miami, Florida, USA 0.00 ms
2. West Palm Beach, Florida, USA 4.36 ms
3. Tampa, Florida, USA 5.85 ms
═══════════════════════════════════════════════════
SUMMARY
═══════════════════════════════════════════════════
Location: Miami, Florida, United States
Minimum Latency: 0.00 ms
Confidence: Very High
═══════════════════════════════════════════════════
The current results are good but could be better. The main problem is with how the magic field works: when setting, for example, “Europe” as the location, it spreads the tests across all European probes but does not guarantee that every single country will be included. This can cause a probe in the same country as the target IP to be omitted, leading the tool to assume the IP is in a neighboring country.
Suggested fix
- Change the selection logic to manually set every country per continent (and every US state).
- Pass the full list of countries/states to the Globalping API so at least one probe in each location is selected.
- Control the number of probes per location to improve accuracy.
Example for North America (43 countries/territories):
| Country | Recommended probes |
|---|---|
| United States | ~200 |
| Canada | ~20 |
| Mexico | ~10 |
| … (other territories) | 1‑5 each |
The goal of the tool is to use a minimum number of probes so unauthenticated users can test it easily. The current approach works great, is simple to implement, and accuracy can be tuned by raising the probe limit.
Overall, latency‑based geolocation detection is a solid way to verify an IP’s location—provided you have enough vantage points. It will struggle in regions with minimal or no coverage.
Running the tool
geolocate $IP
Use the --limit flag to increase the number of probes per phase, but remember it applies to all phases and can quickly consume your quota.
Full documentation is available on the GitHub repo.
Contributing
Pull requests with improvements are welcome!
If you need free credits to experiment, feel free to email me at .
Host a probe
Running a probe is as simple as launching a container:
docker run -d ghcr.io/jsdelivr/globalping-probe