Guides

Build a heatmap from raw IP address logs

An access log full of IP addresses has real geographic information buried in it, but only once each address has been resolved to coordinates that a mapping tool can actually plot.

Extracting addresses from the log

Pull the unique IP addresses out of your log file first, rather than looking up every single log line individually, since the same visitor address commonly appears many times across a session and there is no reason to pay for the same lookup repeatedly.

sort logfile.txt | awk '{print $1}' | sort -u > unique_ips.txt

Resolving in bulk

Send the list of unique addresses as a bulk POST array to /v1/ip.

POST /v1/ip
Content-Type: application/json

["203.0.113.10", "198.51.100.25", "192.0.2.44"]
{
  "status": "ok",
  "results": [
    {"ip": "203.0.113.10", "version": 4, "found": true, "country": "Germany", "country_code": "DE", "region": "Berlin", "city": "Berlin", "postcode": "10115", "lat": 52.5300, "lon": 13.3800, "timezone": "Europe/Berlin", "asn": 1111, "org": "Example ISP"},
    {"ip": "198.51.100.25", "version": 4, "found": true, "country": "Spain", "country_code": "ES", "region": "Madrid", "city": "Madrid", "postcode": "28001", "lat": 40.4168, "lon": -3.7038, "timezone": "Europe/Madrid", "asn": 2222, "org": "Example Networks"},
    {"ip": "192.0.2.44", "version": 4, "found": false}
  ]
}

Building the heatmap dataset

Pair each returned lat and lon with the frequency count of that original address in your log, so a visitor who appears a hundred times in the log contributes proportionally more weight than one who appears once. Feed the resulting list of weighted coordinate points into whichever mapping or charting tool you use to render the heatmap.

A second example: a country-level breakdown instead

If a precise point-by-point heatmap is more detail than you need, aggregating by country_code instead of raw coordinates produces a simpler choropleth-style view, one figure per country rather than a scattered cloud of points. This uses exactly the same bulk lookup, just grouped differently once the results come back, so it costs nothing extra to build both views from the same resolved data.

Handling addresses that do not resolve

An entry with found: false, as in the third result above, should simply be excluded from the heatmap rather than plotted at a default location, since including it would misleadingly cluster unresolved traffic somewhere on the map that has nothing to do with where it actually came from.

A common mistake to avoid

Do not skip filtering out obvious non-visitor traffic, such as internal health checks or monitoring services that hit your server constantly from a fixed address, before building the unique address list. A monitoring service polling every minute can rack up a disproportionate log line count that has nothing to do with real visitor geography, and while deduplication already limits it to one resolved point, that one point can still visually dominate a heatmap out of proportion to any real traffic pattern it represents.

An edge case: hosting and data center traffic

The org field on a resolved address often reveals when traffic is coming from a data center or cloud hosting range rather than a residential or mobile connection, which is a reasonable signal for filtering out bot or scraper traffic before it skews a heatmap meant to represent real visitor locations.

What it costs

Resolving unique addresses rather than every log line is what keeps this affordable, since request cost is one per unique address, not one per log line. A log with a million lines but only a few thousand unique visitor addresses costs a few thousand requests, not a million, comfortably manageable against prepaid credit or an Unlimited package for a large site, and often within the free allowance for a smaller one. Watching the X-Quota-Used header during a large batch job is a simple way to confirm usage is tracking as expected before the job finishes.

Deduplicating before you resolve is the single biggest lever for keeping a log-based heatmap affordable. The IPv4 lookup docs cover the bulk request format in full.