Skip to content

Isochrone Maps: How "15 Minutes From Here" Gets Computed

9 min read · updated August 11, 2026

An isochrone is not a special algorithm. It is Dijkstra with a stopping condition, followed by a shape-fitting step that nobody documents and that decides most of what you see.

A search with a budget

Fifteen minutes of walking at an assumed 4.5 km/h is a distance budget:

budget = 4.5 km/h x (15/60) h = 1.125 km = 1,125 m

Run a one-to-many search from the origin, settling nodes in increasing cost exactly as in an ordinary shortest-path search, and stop expanding as soon as the popped cost exceeds the budget. There is no goal node, so no heuristic helps: A* is useless here because there is nothing to aim at. Every isochrone engine runs plain Dijkstra, which is why an isochrone costs far more than a route on the same graph.

node   cost from origin (m)     status
  O          0                   settled
  A        180                   settled
  B        410                   settled
  C        640                   settled
  D        905                   settled
  E      1,040                   settled
  F      1,310                   beyond budget
  H      1,180                   beyond budget

edges leaving the frontier:
  E -> F   length 270 m
  D -> H   length 275 m

Eight nodes, five inside. If you stop here and draw a shape through the five settled nodes, the isochrone ends at E — 1,040 m from the origin along that street, with 85 metres of budget unspent. Do that everywhere and the polygon is systematically too small, by up to a full edge length in every direction. On a network with 200-metre blocks that is a 200-metre error on a 1,125-metre radius.

The edge that runs out halfway

The fix is to walk partway down the edges that leave the frontier. For the edge E→F:

remaining = 1,125 - 1,040 = 85 m
fraction  = 85 / 270 = 0.3148
cut point = 31.5% of the way along the E-F geometry

for D -> H:
remaining = 1,125 - 905 = 220 m
fraction  = 220 / 275 = 0.80

In PostGIS that last step is ST_LineInterpolatePoint(edge_geom, 0.3148), which respects the edge’s actual geometry rather than the straight line between its endpoints — important, because a road that bends puts the 31.5% point somewhere a straight-line interpolation would not.

The set of cut points, plus the settled nodes, is the isochrone boundary as a point cloud. Everything after this is interpretation.

Turning reachable nodes into a shape

A point cloud is not a polygon, and there are two families of answer.

Hull fitting. A convex hull is trivial and almost always wrong: it spans straight across the harbour, the railway cutting and the golf course, because convexity forbids the concave notches that a real network produces. A concave hull, or alpha shape, takes a parameter controlling how deeply the boundary is allowed to intrude. Too large and it degenerates to the convex hull; too small and the shape shatters into disconnected slivers around individual streets, because the algorithm starts carving out the gaps between adjacent roads. There is no correct value — it is a display parameter, and two isochrone providers with identical routing engines will produce visibly different polygons because they chose it differently.

Cost-surface contouring. Rasterise the settled costs onto a grid, interpolate cost between nodes, and contour the surface at the budget value with marching squares. This handles multiple disconnected regions naturally — an island reachable by ferry appears as its own polygon — and it degrades gracefully where the network is sparse. The parameters move to the grid cell size and the interpolation method, but at least they are parameters with physical meaning.

Whichever you pick, the polygon is a rendering of a set of reachable street positions. The interior of a city block is inside the polygon and was never reachable in fifteen minutes; a strip of land between two roads at the frontier may be outside it and perfectly reachable. That matters the moment you count something inside the shape, which is the usual next step — see estimating population inside a polygon.

Why a circle is not an approximation

The tempting shortcut is to buffer the origin by the budget distance and be done. The error is large and it is one-directional.

naive circle:      area = pi x 1.125^2 = 3.98 km^2

network circuity (assumed 1.3: you walk 1.3 m of street per
metre of straight-line displacement)

effective radius = 1,125 / 1.3 = 865 m
comparable area  = pi x 0.865^2 = 2.35 km^2

overstatement = 3.98 / 2.35 = 1.69

The circuity factor of 1.3 is an assumption stated so you can replace it: it is lower on a regular grid, much higher in a cul-de-sac suburb, and effectively infinite across a river with no bridge. But the direction never changes. A buffer always over-states reach, because the network can only ever be longer than the straight line, and the over-statement compounds when you count population inside the shape. A site-selection model built on buffers systematically over-values locations near barriers, which is precisely where the decision is hardest.

From here is not the same as to here

An isochrone has a direction, and half the isochrones in production have the wrong one.

Searching forward from the origin along outbound edges gives you “places I can reach in fifteen minutes”. Searching backward along inbound edges gives you “places from which I can be reached in fifteen minutes”. On an undirected walking graph these coincide. On a driving graph with one-way streets they do not, and for a delivery depot or an emergency service the question is almost always the reverse one — which addresses can we get to — while the default in most APIs is the forward one.

  • Transit isochrones are a function of departure time. A fifteen-minute reach from a suburban stop at 08:10 on a Tuesday and at 22:10 on a Sunday are different shapes, sometimes by a factor of several in area, because the waiting time for the next service dominates the budget. An isochrone drawn without a timestamp is not a claim about anything.
  • Waiting time has to be inside the budget. If the model charges you only in-vehicle time, every stop looks equally good. The standard treatment is to run the search over a departure window and take a percentile of the resulting reach, which is more honest and considerably more expensive.
  • Speed is not a constant. Walking 4.5 km/h ignores gradient, crossings and signal waits; driving isochrones drawn on free-flow speeds are optimistic everywhere and wildly optimistic at 08:00. The budget arithmetic above is only as good as the edge cost model feeding it.
  • Long dead-ends produce spikes. A single rural road reaching far out from an otherwise dense network gives the hull a thin spike, and a concave-hull parameter tuned to remove it will also remove real detail elsewhere. Contouring a cost surface handles this better than hull fitting does.

When several isochrones from different origins are used to carve a service area into pieces, the overlaps and gaps between them are the real problem, and that is a partitioning question rather than a reachability one; see spatial clustering for delivery zones.