Skip to content

Getting the Most out of Routing with Valhalla

We're all familiar with the process of getting directions. In fact, you may even use an app on your phone to get directions several times/week! But what do you do when you need to avoid a specific area after dark? Or how about seeking out hills when cycling? Or getting routes while driving a golf cart? These are just some of the topics we'll cover in this guide.

At Stadia Maps, our routing APIs are powered by Valhalla, an engine that we (and many others!) have selected for its extreme flexibility. We have a long history of contributing back to the project and hosting the API at scale with our global infrastructure. This guide will occasionally make references specific to the Stadia Maps hosted routing APIs, but almost everything we discuss about the API applies to every Valhalla deployment.

How to use this guide

Whether you're brand new to the world of routing or a veteran looking to optimize for your use case, this guide has something for you. You don't necessarily need to read this guide from top to bottom. Each section can stand alone, so you can skip around freely.

This is not an exhaustive reference, so it won't cover every single option. However, we will try to cover the most interesting / unusual ones, and point you to the appropriate section of the API reference for more details. The reference is vast, so we'll try to highlight specific schemas covered at the beginning of every major section. If you are using one of our SDKs, the reference documentation may be automatically accessible through your IDE.

Costing Models

Stadia API schema: costingModel

What's a costing model?

A costing model is a technical term used in routing for the way the routing engine determines which edges (routes) to prefer or avoid. You may have heard this referred to as a routing "profile" or "mode" in other contexts.

The first step to a perfect route request is selecting the right costing model. This probably isn't much of a surprise, but you probably don't want to ride your bicycle on a major motorway. You can use auto, bus, taxi, truck, bicycle, bikeshare, motor_scooter, motorcycle, low_speed_vehicle, and pedestrian costing models with the Stadia Maps hosted APIs.

Vehicle attributes

Stadia API schema: autoCostingOptions, truckCostingOptions, bicycleCostingOptions, and lowSpeedVehicleCostingOptions

You can customize many vehicular attributes to get better routes or avoid roads that you shouldn't be using.

Most motor vehicles have a tunable height, width and top_speed. Automobiles can also specify whether they are eligible for HOV (high occupancy vehicle) lanes using include_hov2, include_hov3, and include_hot attributes. Trucks have configurable length, weight, axle_load, and hazmat attributes which allow them to avoid roads which are unsuitable.

Vehicle types

Low-speed vehicles have a vehicle_type (ex: golf_cart) and a max_allowed_speed_limit which also heavily influence the routing.

Low-Speed Vehicle Routing Preview

We offer routing for low-speed vehicles (LSVs) in public preview! The golf_cart vehicle type is well-tested across the US, but the generic profile (vehicle_type: "low_speed_vehicle") is still relatively new and under active development. Please report any issues to

Bicycles have a bicycle_type attribute which determines the type of paths that can be traveled. Values are Road, Hybrid, Cross, and Mountain.


Stadia API schema: directionsOptions

As you might expect, Valhalla APIs support both metric and imperial units (for the route responses at least; most inputs are metric only!). They also offer localization of maneuver instructions in over 25 languages (including en-US-x-pirate, if you'rrrrrrrre in the mood)!

Rich Waypoints

Stadia API schema: routingWaypoint

Valhalla supports a lot of flexibility in specifying locations to visit on a route. In this section we'll explore how rich waypoints can be used to get more complex or higher quality routes.

Location type

Each waypoint (location in the API) has an optional type, which can be one of four values:

Type Allows U-turns at the location Generates a new leg and arrival/departure maneuvers Description
break Yes Yes The default value (and always used for the first and last locations in a route).
through No No A location which you want to simply pass through without any fuss. We don't allow U-turns, and no maneuver information / route guidance are generated.
via Yes No Similar to through in that it does not generate a new route leg or arrival/departure guidance, but it relaxes the U-turn restriction.
break_through No Yes Generates a new route leg and arrival/departure maneuvers, but requires the route to proceed straight (no immediate U-turn) on as with through.

Location type and optimized routing

Optimized routing ignores the type of all locations. It assumes that the first and last location are the fixed start/end points, and all intermediate locations may be rearranged into a more optimal ordering.


You can optionally specify a heading which indicates the preferred direction of travel when starting from a location. This often results in a better experience for mobile turn-by-turn navigation applications, especially when the user misses a turn and you need to calculate a new route.

There are multiple ways of deriving a heading value to send to the routing API. The optimal strategy depends somewhat on the application, which sensors are available, and how accurate they are. Compass heading is often the the best sensor when the user has not moved much recently. But be careful though, as it may be wildly inaccurate under certain conditions (ex: after emerging from a metro transit station).

Calculating a course from recent GPS readings often gives a better result if the user is moving. When a user misses a turn and you need to calculate a new route, you can usually use the recent course for the heading value to avoid asking the user to U-turn.

Many mobile operating systems and hardware devices can provide an estimate of sensor accuracy, so be sure to check the documentation from your vendor to get the best results.

Preferred Side of Road

You can also influence which side of the street to start on with the preferred_side and street_side_tolerance These provide flexibility in determining which side of the road the location is on, either automatically or manually.

Parameter Description
preferred_side Determines whether the location should be visited from the same, opposite, or either side of the road (accounting for the side of the road driven on in the area). Has no effect if the location is directly on the centerline or is closed to an intersection.
street_side_tolerance Tolerance in meters from the road centerline for automatically determining which side the location is on. If the distance is less than this tolerance, no side will be inferred. Defaults to 5 meters.

Avoiding areas

Stadia API schema: routingWaypoint

Do you need to route residents around a one-day festival on main street? Or how about avoid a multi-use path that's closed for maintenance? The Valhalla API lets you exclude areas that might be otherwise allowed via the exclude_locations and exclude_polygons parameters.

The exclude_locations parameter (which use the same format as route locations) lets you specify points to avoid. These will be snapped to the nearest road(s), and the entire road(s) will be excluded from the route calculation.

You can also exclude an entire area using exclude_polygons! These are specified as nested JSON arrays, each representing an exterior ring of a polygon. All roads intersecting the polygons will be excluded.

Performance tip

If you just want to exclude a few roads, use exclude_locations, as it's much faster than exclude_polygons.

Costs and Penalties

Stadia API schema: *CostingOptions (almost all costing models)

Costs and penalties are two common ways to influence characteristics of the route. They are easily confused, so let's define them real quick.

A cost is a number of seconds added to the estimated time for a route. You can use costs to adjust how long it takes to do something like cross a border or traverse a gate. Costs are reflected in the total trip duration estimates.

A penalty is also measured in seconds, but rather than affecting the trip duration directly, it is only considered for the purposes of optimal route selection. Penalties are used to influence routing away from certain features.

You should normally use costs to tune travel time estimates and penalties to influence routing decisions. The table below shows the available parameters (which often come in pairs).

Cost parameter Penalty parameter What it applies to
gate_cost gate_penalty Gates with undefined or private access
country_crossing_cost country_crossing_penalty International border crossing
toll_booth_cost toll_booth_penalty Toll booth
ferry_cost N/A Ferry (boarding time)
bss_rent_cost bss_rent_penalty Renting a bike from a bikeshare station
bss_return_cost bss_return_penalty Returning a bike to a bikeshare station
N/A service_penalty Service roads
N/A maneuver_penalty Transitioning between roads (determined by comparing names)
N/A step_penalty Transitioning onto a path with stairs (pedestrian only)


Stadia API schema: *CostingOptions (all costing models)

Factors multiply the costs to favor (between 0.1 and 1) or avoid (up to 100,000) a road attribute. A factor of 1 has no impact. Factors are usually most effective when used to avoid things.

Factors can have confusing results because the impact is proportional to the distance traveled along a road. For this reason, penalty options tend to be better at influencing the final route than factor.

Parameter What it applies to
service_factor Service roads
walkway_factor Footways (no motor vehicles allowed; may be designated footpaths or sidewalks; pedestrian costing only)
sidewalk_factor Roads with dedicated sidewalks (pedestrian costing only)
alley_factor Alleys; narrow service roads between buildings (pedestrian costing only)
driveway_factor Driveways (pedestrian costing only)

Willingness to Use

Stadia API schema: *CostingOptions (all costing models)

This set of attributes determines the "willingness to use" route sections with specific attributes. All values are specified in a range from 0 to 1. In most cases, the value 0 indicates an aversion to the attribute and the value 1 indicates either preference or indifference. The API reference has complete details of how each parameter is treated by the various costing models (ex: use_lit can be found under pedestrianCostingOptions in the Stadia Maps API).

Parameter What it applies to Where it applies
use_ferry Ferries All costing models
use_highways Highways (think US interstates or European motorways) Motor vehicles only
use_tolls Roads with tolls Motor vehicles only
use_living_streets Living streets / residential roads All costing models
use_tracks Track roads (may not have a great surface; usually avoided by automobiles) Motor vehicles and pedestrian
use_roads Roads alongside other vehicles Bicycle only
use_hills Hills/steeper grades Bicycle, motor scooter, and pedestrian
use_primary Primary roads Motor scooter only
use_trails Tracks, unclassified highways, and bad surfaces Motorcycle only
use_lit Lit streets Pedestrian only
avoid_bad_surfaces Roads with bad surfaces relative to the bicycle being ridden Bicycle only


Stadia API schema: routeRequest (elevation_interval property)

Are you building an application that displays elevation profiles (ex: along with a cycling or hiking route)? You can ask for this in a single API call! The elevation_interval parameter lets you specify a sampling rate along with your route request. (We recommend 30 meters, as this is the "native" value and will yield the best performance.)

Accounting for bridges and tunnels in an elevation profile is usually difficult, since the surrounding terrain can be much higher or lower than the road. When using elevation_interval though, Valhalla interpolates linearly between the start and end of the feature. This neatly solves the problem of sharp artifacts in many route elevation profiles.

Ignoring Restrictions

Stadia API schema: *CostingOptions (most costing models)

Is a route looking really obviously wrong to you? Maybe you know that a road is a legal shortcut, but routes never use it? Or maybe you're map matching telemetry from your fleet, but the matched route diverges from the path your driver took?

Ignoring restrictions is powerful in identifying cases where the underlying map data needs improvement.

Parameter What it does
ignore_access Ignores access restrictions (can my vehicle type access this legally road?
ignore_oneways Ignores one-way restrictions, allowing travel the wrong way on one-way streets.
ignore_restrictions Ignores restrictions such as "no left turn" or "no access after 10pm."
ignore_non_vehicular_restrictions Ignores most restrictions (eg: turn and conditional restrictions), but still respects restrictions that impact vehicle safety such as weight and size.

Our routing network comes from OpenStreetMap, which means that if you find an issue, you can fix it! No months-long bureaucratic change request process required. (If you aren't sure how to start, check out LearnOSM.)

We update our routing data frequently, so you can expect to see any fixes reflected within a week.

Wrapping up

In this relatively short guide, we've looked at how you to use Valhalla for a variety of scenarios. We've covered the tools you need to generate high-quality routes, and shown how the API is flexible enough to support many niche use cases with only a little extra effort.

If you'd like to try it out in your application, our SDKs give you a shortcut past API glue code, straight to productivity. Most of the APIs discussed in this guide are available on our free tier, and we even offer a 14-day trial of the professional APIs like optimized routing and time/distance matrix (no credit card required!).

Get Started With a Free Account

If you're looking for mobile navigation solutions or want to discuss custom routing solutions, give us a shout at or track us down on social media (links in the footer).