A 200 OK proves nothing about location. Why geo databases disagree, how silent fallback contaminates data, and a four-step check for any city filter.
· 14 min read · Targeting
Does city-level proxy targeting actually work? Sometimes. The problem is that
you cannot tell which times from the responses you get back, because a request
that landed 200 kilometers from the city you asked for returns exactly the same
200 OK as one that landed downtown. City targeting is not a switch that is on
or off. It is a filter applied against a database that is approximate by
construction, over a pool that changes hour to hour, with a fallback behavior
most networks do not announce.
None of which makes it useless. It makes it a thing you verify rather than a thing you trust. Here is the procedure.
When you ask a proxy network for an exit in Chicago, this is what happens: the network looks up its available exit addresses in a geolocation database, it finds the subset that database labels Chicago, and it hands you one.
Both halves of that sentence are approximations.
The database is a third-party product — MaxMind, IPinfo, IP2Location, DB-IP and several smaller vendors — that infers a physical location for a block of addresses from routing data, registry records, latency measurements, WHOIS entries and customer-supplied corrections. Nobody surveys the houses. It is inference at scale, refreshed on the vendor's own schedule.
And the pool is live. Residential exits are real consumer connections that come and go, so "available in Chicago right now" is a set that changes continuously.
Neither of those is a defect in any particular provider. They are properties of how IP geolocation works, and they set the ceiling on what any city filter from anyone can deliver. Which is why the useful skill is measurement, not vendor selection.
This deserves to be a section rather than a footnote, because it is the single assumption that ruins geo-sensitive datasets.
A successful HTTP response tells you that a request left an exit address, reached a target, and came back. It carries no information whatsoever about where that exit address was. There is no header, no status code and no error condition that distinguishes "your Chicago filter was satisfied" from "your Chicago filter was not satisfied and something else was used instead."
Teams build entire pipelines on the implicit inverse — the job did not error, so the targeting must have worked. That inference is not available. The only thing that proves location is checking the exit address against something, which is the whole of the procedure below.
Here is the behavior that turns an approximation into a contaminated dataset.
When no exit matches your filter, a network has two choices. It can tell you, or it can substitute. Substitution is common: no address available in the requested city, so route through the nearest available one and return a normal response. Your job succeeds. Your rows are wrong. Nothing logged it.
The damage compounds in a specific way that makes it hard to catch. Fallback is not random — it correlates with exactly the conditions that make a city interesting. Small cities have thin supply, so they fall back most. Overnight hours have thin supply, so they fall back most. The rows most likely to be wrong are the rows about the markets and time windows you were investigating precisely because they were unusual. A dataset with 5 percent silent fallback distributed that way is worse than one with 20 percent distributed evenly, because the error is aligned with your conclusion.
The alternative design is an explicit error, which AnonEdge returns as
400 NO_RAY. That trade is covered further down.
Test one address against four geolocation sources and expect more than one answer. Three structural reasons, none of which any vendor can fix.
Databases lag reallocation. An operator can transfer a block, re-home it to a different market, or reassign it to a different customer segment on Monday. The vendor's next refresh reflects it on some later schedule, and every vendor refreshes differently. In the interval, the database is confidently wrong.
Carriers allocate above the city level. A mobile operator or a large ISP may announce one prefix that serves a whole region, and there is no per-subscriber geography inside it to discover. This is measurable, and it has been measured. The 2026 study Lost in the Prefix: Revisiting IP Geolocation Accuracy Across Networks and Geographies (Nabi, Bliton, Chung and Hasan, submitted 2026-05-21) evaluated MaxMind GeoLite2, IPinfo, IP2Location and DB-IP against ground truth from RIPE Atlas and UNICEF Giga across 175 countries, and reports median errors of 179 to 207 km on mobile networks against 3 to 16 km on fixed networks — more than a tenfold gap, consistent across all four providers. The paper attributes the gap to prefix geography: roughly 70 percent of mobile prefixes span more than 100 km, and between 32 and 40 percent of all geolocation prefixes span more than 100 km, with 9 to 14 percent spanning more than 500 km.
Read those numbers as the ceiling on the mechanism rather than a rating of any vendor. When a prefix physically covers 300 kilometers, no database can place an address inside it to within a city, because the information does not exist to be looked up. The same paper notes that wrong-country assignments are rare — under 1 percent of observations per provider — which is the real shape of the problem: country is solid, city is soft, and the softness is structural. It also reports far higher failure rates for Global South observations than Global North ones across all four providers — counting an observation as failed when the error exceeds 100 km, Asia runs 53 to 61 percent and Africa 66 to 72 percent, against 9 to 20 percent in Europe. A filter that behaves acceptably in one region does not transfer to another.
Registered location is not physical location. Registry records carry the address of the organization that holds the allocation, which for a national ISP is a corporate office. An inference pipeline that leans on that record places subscribers at headquarters. This is why an address in a small town sometimes geolocates to a capital city several hundred kilometers away.
The consequence for you is narrower than it sounds: the database your target uses is the one that decides what you see, and you cannot ask which one it is. Agreement among your own sources is a proxy for confidence, not proof.
Four steps. Run it once per city you depend on, and again whenever your results move for no visible reason.
Open N sessions with the city filter applied and log the exit address each one returns. Not one session. Not five. A sample large enough that the number you compute in step 4 means something.
The standard conservative bound for a proportion at 95 percent confidence is
approximately 1 / sqrt(N):
| Sessions sampled | Approximate margin of error |
|---|---|
| 100 | ±10 points |
| 400 | ±5 points |
| 1,000 | ±3 points |
So a 30-session check that returns "27 correct" is telling you the true match rate is somewhere in a band nearly 20 points wide. If your decision changes across that band, sample more. Log the timestamp with every address — supply varies by hour, and you will want to compare morning against night.
Resolve every logged address against at least three independent geolocation sources. The four evaluated in the study above are the obvious candidates because their behavior is documented.
Record all three answers, not the majority. Disagreement is the finding. An address that three sources place in three different cities is not a data point you should count as a pass or a fail — it is a data point telling you that this address is unresolvable at city granularity and that your target's answer is a coin flip you do not control.
Keep a running disagreement rate alongside your match rate. If disagreement is high, no amount of provider switching will help you, because the ambiguity is in the address, not in the network that served it.
This is the step almost nobody runs, and it is the only one that measures what you actually care about.
Your target tells you where it thinks you are, for free, in its own output. Collect it:
Any of these is worth more than every geolocation lookup combined, because it is the target's own verdict rendered through the target's own database. When the geolocation sources say Chicago and the store locator offers Milwaukee branches, the store locator is right about the only question that matters.
Divide addresses that matched by addresses sampled. Then the part that requires discipline: decide your threshold before you look at the number.
Thresholds are a function of what the data is for, and they are not interchangeable:
| Use case | Tolerance | Because |
|---|---|---|
| Ad verification and compliance evidence | Very low | A wrong row is a wrong finding presented as fact |
| Localized pricing collection | Low | Wrong-city prices are indistinguishable from a price change |
| Local SERP tracking | Moderate | Rankings vary within a metro anyway |
| Broad availability checks | High | Metro-level correctness is usually sufficient |
| Content localization QA | Moderate | You are testing whether localization fires, not where exactly |
Write the threshold down first. Deciding it after you have seen 71 percent produces a threshold of 70 percent every time.
400 NO_RAYWhen no exit matches your filter, AnonEdge returns 400 NO_RAY rather than
substituting. The error is documented under proxy error
codes, and the available filters —
country, state, city and ZIP — under city, state and ZIP
filters.
An explicit error is worse ergonomics and better data. It costs you a retry and some handling code. Silent substitution costs you the ability to know your dataset is wrong, which is not a trade any measurement job should accept.
Practically, treat 400 NO_RAY as a supply reading rather than a bug. Its rate
over time is a free, continuous signal about how thin your filter is. A city
that produced no errors in March and errors every night in August is telling you
something about that pool that no dashboard will. Log the rate, alert on the
change, and widen one level at a time when it fires — drop the ZIP and keep the
city before you drop the city.
ZIP filters are the most requested and the most misunderstood.
The structural point first: a US ZIP code is not an area. It is a set of mail delivery routes maintained by the postal service for operational convenience, redrawn when delivery logistics change. The polygons everyone maps them with are approximations produced after the fact — the Census Bureau's ZCTAs are the best-known example. Asking a geolocation database to place an address inside a construct that is not fundamentally geographic, when that database already struggles at city granularity, compounds two approximations.
Where ZIP targeting genuinely earns its keep is where the target uses ZIP as its own key: a retailer whose inventory and pricing are keyed to store catchments, a delivery service with ZIP-scoped coverage, a tax calculation, an insurance quote. In those cases you are not asking "where is this address," you are asking "which bucket does this address fall into," and the target's own bucketing is the thing you verify against in step 3.
Where it does not earn its keep is as a proxy for demographics. A ZIP is a routing convenience that correlates with neighborhoods; it does not define one, and treating it as a demographic segment quietly imports the postal service's operational decisions into your analysis.
No accuracy figure for ZIP targeting appears anywhere in this article, from any provider, and you should distrust one that does. The published measurement in this field reports median distance error and prefix span; nobody publishes a ZIP match rate, because a ZIP match rate is a property of one database against one postal geography at one moment. Run the four steps above with ZIP as the filter and the match rate you compute is the only ZIP figure that describes your pool.
The honest answer to does city level proxy targeting actually work is that it works well enough to be useful and not well enough to be assumed. Three conclusions:
It works better on fixed networks than mobile ones. The cited median errors differ by more than a factor of ten. If your job needs city precision, a residential pool on fixed-line connections is structurally the better instrument than a mobile one, whatever else mobile buys you.
It works better in large metros than small towns. Supply concentrates where
people are. Thin supply is where silent fallback and 400 NO_RAY both live.
It works when you verify it and not otherwise. That is not a hedge. It is the entire finding.
You measured, the number came in below the line you set. Four moves, in increasing order of how much you give up:
Sample a meaningful number of sessions with the filter applied, log every exit address, and resolve each one against at least three independent geolocation sources. Record disagreement rather than only the majority answer. Then check the target's own output — store locator, currency, tax, shipping options — because that reflects the database your target actually uses, which is the one that decides what you see.
Three common reasons. The geolocation database has not caught up with a reallocation. The address sits in a prefix that physically spans a wide area, so no database can resolve it to a city. Or no exit was available in the requested city and the network substituted a nearby one without telling you. The first two are structural; the third is a provider design choice.
Accurate enough to be useful and not accurate enough to assume. Peer-reviewed measurement puts median geolocation error at 3 to 16 km on fixed networks and 179 to 207 km on mobile ones across four major databases. That is the ceiling on the mechanism, not a rating of any provider. Measure the match rate for your specific city and pool before you depend on it.
When no exit matches your location filter, some networks route through the
nearest available address and return a normal response with no indication that
substitution occurred. Your job succeeds and your data is wrong. AnonEdge returns
400 NO_RAY instead, which costs a retry but keeps the failure visible.
Explicit errors are recoverable; contaminated datasets frequently are not.
Enough that your margin of error is smaller than the decision you are making.
The conservative approximation is 1 / sqrt(N), so 100 sessions gives roughly
±10 points, 400 gives ±5, and 1,000 gives ±3. Sample across different hours as
well as different sessions, because residential supply varies through the day
and thin hours are when fallback is most likely.
Use ZIP only when the target itself keys on ZIP — store catchments, delivery coverage, tax or insurance quoting. Otherwise city or metro is more reliable and cheaper to satisfy. A US ZIP code is a set of mail delivery routes rather than a geographic area, so ZIP filters stack a second approximation on top of one that is already soft at city granularity.
Measure once per city, at two different hours, before any pipeline depends on
the result. Log the exit address and the 400 NO_RAY rate permanently — they
are your ongoing early warning that a pool has thinned.
Talk to sales about geo-heavy workloads with your target city list and your tolerance, and check which countries are available before you scope the work.