The 15-Minute Clinic That Takes 25 Minutes on Foot
A parent in Carson City, Nevada is told by a clinic's front desk that it is about fifteen minutes away. Both buildings sit on the same flat valley floor, about a kilometer apart, and nothing about that sounds wrong.
The doubt is structural, not personal. A quoted travel time is a claim about a road network at a specific hour, and the honest way to check it is to ask the network itself. One request does it: return every road the network lets a person reach from the clinic within fifteen minutes, and wrap the result in a polygon. That polygon is an isochrone, the most useful and most quietly dishonest diagram in applied geospatial work. This post walks through what the polygon actually computes, and where it lies to you along the way.
What the polygon actually computes
Under the hood, a routing engine holds the road network as a graph: intersections are nodes, road segments are edges. Every edge carries a cost, usually seconds, adjusted by whatever traffic data the provider holds for that segment. An isochrone computation floods that graph outward from your origin until the cumulative cost budget runs out, then collects the endpoints it reached and stitches their outline into a polygon. Everything inside the line is reachable within your budget by the network's own rules. Everything outside is not.
A radius cannot say any of that. A radius is a circle. An isochrone is a circle with a river and a one-way system subtracted, plus a highway corridor added in the one direction the ramps allow. Picture a store 4 km from your door on a map's straight line, with the only river crossing 9 km downstream, and you understand the gap between the two shapes.
Two candidates, one real address, three polygons
Here is the worked example, with one real address as the anchor: the Nevada State Capitol at 101 North Carson Street, Carson City. Say a committee is weighing two clinic sites the Capitol's neighborhood could plausibly feed. Site A sits on the city's south side with immediate access to the US 395 corridor, and Site B lies a few kilometers northeast on surface streets. Three polygons per site answer most of the committee's actual question:
| Question about each site | Site A, south side | Site B, northeast |
|---|---|---|
| 15 minutes on foot (approx.) | covers the downtown core | roughly the same size, shifted east |
| 15 min driving, mid-afternoon (approx.) | most of the city and some valley floor | similar area, different neighborhoods |
| 15 min driving, 8:30 a.m. on a weekday (approx.) | collapses toward the interchange | keeps most of its shape |
The queries themselves are small. Using everymap, our Rust client, the same isolines call runs against HERE, TomTom, and Mapbox, which is exactly how we caught provider-shaped disagreements in the first place.
# Illustrative shape of the call, not a pasted transcript
# one call per candidate site and per budget:
# Site A (south side, US 395 corridor) and Site B (northeast, surface streets)
everymap --api-key $KEY isolines \
--origin "<candidate site, lat,long>" \
--transport walk --range 900 \
--provider here
The same query over plain HTTP, if you are calling a provider directly:
# Illustrative endpoint shape; parameter names vary by provider
GET {provider}/v2/isolines?origin={site_lat},{site_lng}&profile=walk&range=900
Run each site at each budget and overlay the polygons. Then count how much of your actual patient population, however you model it, falls inside each line. That count is the answer the radius was pretending to give you.
Default walking speed is a claim your toddler disagrees with
Walking isochrones deserve their own warning. Providers' default walk profiles commonly assume an adult moving at about 5 km/h over flat ground; check your provider's docs, because the exact figure varies a little. Real walking includes crossings timed to traffic lights, sidewalk snow, a stroller, and a toddler who has opinions about pacing. Push those realities uphill, in a town sitting at about 1,470 m elevation with grades rising toward the Sierra, and the fifteen-minute polygon describes a person who does not exist. The line is a correct answer to the wrong question.
Do the arithmetic for the parent waiting at the clinic: at the engine's default 5 km/h, fifteen minutes buys 1.25 km. At the 3 km/h a stroller, a curb ramp, and a traffic light actually deliver, that same circle takes 25 minutes. The polygon on the map is the first circle, and it never leaves the office.
The fix is cheap and unsentimental: lower the speed and shrink the budget. Accept that the honest walking distance for the person you serve might be one-third of the engine's. A walking polygon computed at default speed is an athlete's polygon. Your parent with the stroller needs a stricter one.
Barriers and the edge of the network sample
Three failure sources live outside the polygon's math. First, barriers plain and bureaucratic: a gated road here, a construction closure there. The seasonal kind matters most. Some roads west of Carson City toward the Sierra close for winter, typically for months at a time, and an isochrone computed in July says nothing about February. Second, the provider's network sample itself: providers ingest and sample road networks at different densities, so one provider's graph may simply not contain the private road that connects your origin to the arterial. Third, edge effects: near the polygon boundary, a single included or excluded road swings whole neighborhoods in or out, which is why two providers' fifteenth-minute lines disagree far more than their tenth-minute lines do.
We met this problem from the other side when building everymap. The first design exposed one parameter table that every provider accepted, and the table shrank with each addition until it could barely express anything real. The fix was to model isolines per provider behind one trait and let unsupported combinations fail loudly, which is a design lesson that applies beyond Rust: a silent lowest-common-denominator is a lie with a 200 response code.
Where the model ends and the person begins
The limit to state out loud: an isochrone is a model of a road network, as sampled by one provider on one day, and it is not a model of a person's trip. It does not include the four minutes circling for parking, the walk from the far corner of the lot, or the ten minutes in the lobby before anyone looks at the toddler. Peak-versus-off-peak accuracy is only as good as the probe data behind it, which thins out fast away from big cities.
Use isochrones to kill candidates, never to crown them. Polygons that miss the population are disqualifications; the survivors deserve a real routing query, run at the exact hours your users travel, with the actual origin addresses people type. The receptionist's fifteen minutes deserves to be checked. The network keeps the receipts.
Thanks for reading this far. If this sounds like the problem you're wrestling with, tell us about it. A principal reads every message.
Start a conversation