Both Valhalla and OSRM are outstanding open-source routing engines, both run on OpenStreetMap data, and both are free. So the question I get most often from teams is simply: which one do I pick? The honest answer is "it depends" — but on a small number of things that are easy to reason about once you've run both in anger.
The one-line summary
Reach for OSRM when you need raw speed on fixed cost profiles. Reach for Valhalla when you need flexibility — dynamic costing, trucks, time-based restrictions, or many transport modes from one dataset.
OSRM: built for speed
OSRM's contraction-hierarchies (CH) pipeline pre-processes the graph so hard that
individual queries are blisteringly fast. Its /table service is, in my
experience, the best distance/time matrix you can self-host — which matters enormously
if you're feeding a VRP solver.
- Strengths: lowest latency, fantastic matrices, simple mental model.
- Costs: the CH profile is essentially baked at preprocessing time — changing costing means re-running an expensive build. The MLD pipeline relaxes this but trades away some speed.
Valhalla: built for flexibility
Valhalla uses hierarchical tiled routing with dynamic costing — the costs are applied at query time. That means one dataset can serve car, truck, bike, pedestrian and multimodal requests, and you can pass per-request options like avoiding tolls or honoring vehicle height and weight limits.
- Strengths: dynamic costing, truck routing, time-based restrictions, map-matching, isochrones and elevation — all first-class.
- Costs: a little more moving parts, and you'll spend time learning the costing model to get results exactly right.
How I actually decide
Three questions settle it most of the time:
- Do you need trucks or complex restrictions? → Valhalla.
- Is your workload dominated by huge matrices? → OSRM.
- Do you need many modes or per-request cost tweaks? → Valhalla.
And the answer many mature systems land on: run both. OSRM for the matrix hot path, Valhalla for rich single-route requests and truck logic. They share the same OSM source, so the operational overhead of running two engines is smaller than it sounds — one data pipeline, two consumers.
The part nobody warns you about
Whichever you pick, the engine is the easy 20%. The other 80% is the data pipeline (PBF extracts, tile/graph builds, scheduled refreshes), the scaling story (autoscaling, caching, health checks) and the correctness testing. That's where projects stall — and it's exactly the part I help teams get right.
Running into this decision yourself? Let's talk — I've productionized both more times than I can count.