Backstory · Gravel

The question routing libraries don't ask

Every routing library computes the shortest path. The more useful question is what happens to the network when one edge fails.

I did not set out to write Gravel. I set out to renew a badge. My Department of Labor credential was up, and the nearest office, by straight-line distance, was in Gatlinburg, Tennessee. On a map that looks like a forty-five minute drive. In reality the only sensible road climbs over the Great Smoky Mountains, so it is closer to an hour and a half. That is fine. That is just geography, and routing already knows how to handle geography.

Then the one road over the park, US 441, closed for weather. With 441 gone, the detour around the range turns a ninety-minute trip into two and a half hours each way. A full day, erased, because a single road shut for an afternoon. I sat with that number and got annoyed in a very specific, professional way. This was not bad luck. It was a property of the network, and the network had been quietly telling me it had no second way out the whole time.

The annoyance landed on top of something I was already living in. My dissertation is on how communities absorb disasters, and I spent years in disaster response watching this exact thing at much higher stakes: a road closes and a neighborhood is not inconvenienced but cut off, and the mutual-aid networks we picture as resilient turn out to hang on a few fragile threads. I had just watched Helene tear through western North Carolina and sever whole communities in the mountains, where an alternate route is a luxury the terrain refuses to give you. My badge renewal was the same problem in miniature. The question underneath both is the one I could not put down: how do you put a number on how cut off a place can become?

That is a network problem, and network problems are a real, slightly strange passion of mine. Social networks, flow networks, all of it. My LinkedIn banner is a map of international arms flows between countries, if that tells you anything about how I relax. So I jumped in, with three questions stacked on top of each other. How do you quantify whether a community is fragile? How do you tell, before the storm, that a place is about to become hard to reach? And, much closer to home, how do I keep my own employer from sending me down a route one closure can erase? Gravel is my answer to all three, and getting there turned out to be a genuinely novel measurement problem sitting on top of a genuinely brutal performance one.

Old, versus alone

Infrastructure risk gets argued two ways, and each is half right. The asset-condition camp grades the parts: this bridge is rated poor, that transformer is past its service life, here is the maintenance backlog in dollars. The network-topology camp grades the shape: this corridor has no alternative, that town hangs off a single line. The condition people are right that physical state is real and fails in real weather. The topology people are right that a brand-new bridge with no detour is still a single point of failure, while a crumbling one with five parallels nearby is a nuisance, not a catastrophe.

Gravel sits on the topology side and tries to turn it into a number. Not "this bridge is old" but "these regions have no topological alternative." Fragility is dependence, scored: given a graph and a notion of failure, how badly does connectivity degrade, which edges are load-bearing, and which nodes get stranded when those edges go.

INTACT: ONE CONNECTED GRAPH critical edge EDGE FAILS, RIGHT SIDE STRANDED 6 nodes isolated
Two clusters joined by one edge. Routing sees a connected graph. Fragility sees the link whose loss strands everything behind it.

Make it comparable

The whole point is comparison. A fragility score is only useful if New Hampshire's number and Kansas's number mean the same thing, so you can rank them and act on the ranking instead of a hunch. I ran isolation fragility for all 3,221 US counties. The Great Plains came out most resilient (Kansas lowest, at 0.146): flat terrain, rectangular road grids, redundancy everywhere. The mountain and coastal states came out most fragile (New Hampshire highest, at 0.638): constrained geography forces traffic through single corridors. And the mountain county this whole story starts in scores worse than any state's average. Jackson County, North Carolina comes in at 0.673: the terrain telling you, in one number, that it never built you a second way out.

Every US county, scored. Green is resilient; red is a closure away from cut off. The Great Plains hold together, the Appalachians and mountain West do not, and the western North Carolina mountains this story starts in sit in the red. Hover any county for its number.

It does not tell you a bridge is old. It tells you which regions have no plan B.

That is the kind of pattern the method exists to surface, and underneath it is really a question about power: who can be cut off, and by the failure of what. Power, water, telecom, and roads turn out to be the same math wearing different clothes — and the math does not care which one you hand it.

What I got wrong, and shipped anyway

Version 2.1 of the location-fragility analysis was about four hundred times slower than 2.2. Not a typo: 400×. The speedup did not come from more cores or a smaller memory footprint. It came from running the whole thing backwards.

Fragility, mechanically, is a demolition. I take the road network and pull edges out one at a time, recomputing connectivity after each removal to see who just got stranded. Version 2.1 did exactly that, in order, and it was honest and unusable at national scale. What I had not noticed is an asymmetry buried in the contraction-hierarchy index that makes the queries fast in the first place: pulling an edge out forces a full re-evaluation of the tree, because a deletion can invalidate shortcuts anywhere in it, while adding an edge back only triggers a small incremental update right where it lands. Deletion is global and expensive. Insertion is local and almost free. The two operations were doing the same work, and only one of them was paying full price for it.

So I stopped deleting. I pull out every edge I mean to remove up front, drop the network into its most-degraded state, then add them back one at a time and read the same measurements off in reverse. Identical sequence of network states, identical fragility numbers, at a fraction of the cost, because every step is now a cheap insertion instead of an expensive teardown. That is a 400× speedup I am only allowed to be proud of if I also admit the first version earned it by doing the obvious thing in the obvious, expensive direction.

Gravel is also deliberately not several things. It is not turn-by-turn navigation (use OSRM). It is not a transit planner. And it assumes a static graph, because contraction hierarchies do: no live traffic, no edges that change under you. Those are real limits, not modesty. The moment your network is changing every second, this is the wrong tool, and I would rather tell you that than hand you a fragility score that is already stale.

So here is the question I would actually want you to sit with. Pick a system you depend on (your commute, your power, the one road off your street) and ask not whether it is in good repair, but whether it has an alternative. If the honest answer is no, that is fragility, and now there is a way to put a number on it.

There is a line I use about my own work: I find where systems fail people, and then rebuild them. Gravel is the first half made literal, the finding, turned into a score you can rank and act on. The rebuilding is still the hard part, and still ours. It is open source, Apache 2.0, at github.com/rhoekstr/gravel...

Robert Hoekstra
Robert Hoekstra builds independent software as awryLabs: games, libraries, and small tools, one project at a time. More about me, or see Gravel itself.

← All stories