# How routing works

> How geolith Routing works: OpenStreetMap in, a road graph cut into tiles by the builder, stored as 64 KiB zstd blocks in the routing part of a .glx file, read in byte ranges by a Rust router, answered as Valhalla-compatible JSON. In development, not deployed for public use.

**Status: in development. Not deployed for public use.** The builder writes routing files and the router answers from them; nothing is offered as a service yet. What is done and what is left is on [Status and roadmap](/routing/status).

## The steps

```text
input → builder → .glx routing part → router → response
```

1. **Input.** An OpenStreetMap extract (`.osm.pbf`).
2. **Builder.** The [geolith builder](/builder) reads the roads, applies tag rules, builds edges, sets access on each edge and reads turn restrictions. It then runs the enhancer, builds the road hierarchy and adds shortcuts. It cuts the graph into graph tiles on three grids: 4°, 1° and 0.25° cells.
3. **The routing part.** The builder writes each tile as fixed 64 KiB blocks, each its own zstd frame, behind a per-tile block directory, after a tile index, as the routing part of a `.glx` file. See [The routing part](/routing/routing-part).
4. **Router.** The Rust router library keeps the tile index in memory and asks for the blocks a request needs; the program around it fetches them with HTTP range requests or file reads.
5. **Response.** The router answers with Valhalla's response bodies. See [API](/routing/api).

The builder command:

```bash
geolith --output-format routing --osm-pbf berlin.osm.pbf \
  --routing-output berlin-routing.glx
```

Add `--routing-predicted-speeds <dir>` to store historical speeds in the tiles; see [Traffic and live data](/routing/traffic).

## What happens to a request

1. **Snap.** Each location is matched to the nearest road edge the chosen costing (`auto`, `pedestrian` or `bicycle`) may use.
2. **Search.** For `/route`, a bidirectional A\* search runs from both ends over the road hierarchy, honouring turn restrictions. `/isochrone` runs a one-to-all search, `/sources-to-targets` a many-to-many search, and the map matching endpoints match a GPS trace to the roads.
3. **Build the answer.** For a route, the router adds up the length and time, encodes the shape as a polyline with precision 6, and writes the maneuvers with English text and spoken (`verbal_*`) instructions.

## The data, end to end

| Question               | Answer                                                                                                                                                                                                                    |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| What is the input?     | An OpenStreetMap `.osm.pbf` extract. Berlin is built and tested; a country and the planet are not built yet.                                                                                                              |
| How is the input made? | Downloaded from OpenStreetMap (planet file or a regional extract). geolith does not edit it.                                                                                                                              |
| Where is it stored?    | In one `.glx` file, in its routing part: R2, S3, any server that answers `Range` requests, or local disk.                                                                                                                 |
| How is it ingested?    | It is not. The file is the database: there is no import step, no database server and no index to load beyond the tile index the router reads on start.                                                                    |
| How is it used?        | The router reads the tile index once, then fetches only the blocks a request touches.                                                                                                                                     |
| How is it accessed?    | By HTTP range requests (R2 or any HTTP server) or file reads (local disk). Adjacent blocks are merged into one request.                                                                                                   |
| How is it served?      | A Cloudflare Worker app serves the six endpoints. It runs as a test deployment on workers.dev only; nothing is deployed for public use.                                                                                   |
| How is it kept safe?   | The file is read-only. Tile decoders are bounds-checked Rust with no `unsafe`. Every tile is treated as untrusted input and refused whole if malformed, never read in part. The request path does not panic on bad input. |

## Inputs, now and planned

| Input                        | Use                                                                   | Status                             |
| ---------------------------- | --------------------------------------------------------------------- | ---------------------------------- |
| OpenStreetMap `.osm.pbf`     | Roads, access, turn restrictions, names                               | Now                                |
| Historical speeds (CSV)      | Speed by time of week, free-flow and constrained-flow speeds per edge | Now (`--routing-predicted-speeds`) |
| Administrative boundaries    | Driving side and country rules                                        | Next, before launch                |
| Time zones                   | Local time for time-dependent rules                                   | Next, before launch                |
| Overture Maps transportation | Roads and names from Overture                                         | Later                              |
| Elevation                    | Grades on edges                                                       | Later                              |
| GTFS                         | Public transit                                                        | Later                              |
