Network · Traffic map accuracy

How to get city/state-level truth on the /admin/traffic map — Cloudflare location headers, the places contract extension, and what the map does and does not claim today.

Network · Traffic map accuracy

How to get city/state-level truth on the /admin/traffic map — Cloudflare location headers, the places contract extension, and what the map does and does not claim today.

---

.. toc::

What the map claims today (be honest with yourself first)

Two very different data sources share one map:

returns lat/lon + city + region per public IP, and markers group into ~10 km cells. City-level, genuinely useful.

markers sit on country centroids. Every US visitor to dash-email becomes one marker in Kansas. The per-app ring offset around each centroid is *presentation* (so overlapping apps stay hoverable), not accuracy — the tooltip still names only the country.

That is the ceiling of the current satellite contract, and why the map clusters at country centers. Raising the ceiling means satellites must *capture* finer location, then *report* it.

Step 1 — turn on Cloudflare visitor-location headers (free)

For every zone proxied through Cloudflare (2plot.media, 2plot.xyz, 2plot.dev, …): Dashboard → your zone → Rules → Settings → Managed Transforms → enable "Add visitor location headers". Available on all plans, including Free. Every request then arrives with:

`` CF-IPCity: Denver CF-IPLatitude: 39.739 CF-Region: Colorado CF-IPLongitude: -104.984 CF-Region-Code: CO CF-IPCountry: US CF-IPContinent / CF-Timezone / CF-PostalCode also available ``

No API calls, no latency, no rate limits — the accuracy problem becomes a header read. The headers only appear on proxied (orange-cloud) records, and proxying is decided per DNS record, not per zone — which matters for this network:

accounts.<domain>, and the email DKIM CNAMEs) — proxying those breaks Clerk's TLS provisioning. But those are Clerk's own subdomains; the app host record (2plot.media, www, …) is a separate record and CAN be proxied without touching them. In this network only the hub carries Clerk DNS anyway — satellites use the redirect model (sign-in happens on 2plot.ai), so their zones have no Clerk records at all.

to *Full (Strict)* on the zone. Test the sign-in round trip after flipping any record.

If you'd rather not proxy anything, that's fine too — the map does not depend on Cloudflare. The hub already gets city-level lat/lon from ip-api.com per public IP (free tier ~45 lookups/min over plain HTTP: cache per IP, resolve outside the request path), and that is what powers the map's "Precise" layer today. Cloudflare headers are the zero-cost upgrade path, not a requirement; without them, satellites simply stay on the country-centroid layer.

Step 2 — the places contract extension (v2.1)

Alongside countries, satellites report a capped list of place rollups:

``json "places": [ {"cc": "US", "region": "CO", "city": "Denver", "lat": 39.7, "lon": -105.0, "hits": 41}, {"cc": "DE", "region": "BE", "city": "Berlin", "lat": 52.5, "lon": 13.4, "hits": 9} ] ``

Rules that keep it truthful and private:

impossible to see a house. Never ship raw coordinates.

country-level in countries (which remains the complete count).

cc + rounded lat/lon still beats a centroid.

Hub-side this rides the same accumulate-across-restarts reader as pages/countries; the map prefers a report's places and falls back to centroid-countries per app. (Reader + map support is the next hub change; satellites can start sending places first — unknown fields are ignored, nothing breaks.)

Step 3 — reading the map like a marketing tool

marker area, which scales with √hits so big markers don't lie.

small marker with long sessions is a better ad target than a big marker of bounces. Cross-check both before spending.

(that's the reported granularity); only hub markers have per-place session medians until places ships with per-place durations.

UAs still slip through — a "city" showing hundreds of hits, seconds of session, from one visitor is a crawler, not a market.

Current limitations, stated plainly

| Limitation | Cause | Fix | |---|---|---| | Satellite traffic clusters at country centers | contract sends countries only | Steps 1–2 | | Ring offsets around centroids | presentation, not data | tooltip names the country; ignore the spread | | Hub geo misses some visitors | private/CGNAT IPs, ip-api misses | unavoidable; counts stay truthful, only the map thins | | One app median for satellite session markers | reported granularity | per-place durations in a later places rev |

---

*Source: /docs/traffic-map*

Note for AI agents: This is the static, prerendered view of an interactive Dash application served because we detected a non-JS user agent. Full prose docs: