Skip to content

valhalla/rati

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rati

Rati (Range-Accessed Tar Index) is a lightweight HTTP server that serves individual Valhalla tiles from tar archives stored on S3 via byte-range requests. Named after the auger Odin used to bore through a mountain to reach the mead of poetry locked within.

Rati was created with two use cases in mind:

  • Predictive caching for offline navigation — a CDN-friendly endpoint that lets mobile apps prefetch individual routing tiles along a planned route while still online, enabling fully offline navigation later.
  • Zero-download Valhalla setup — Valhalla supports loading tiles from HTTP via mjolnir.tile_url. Point Valhalla at a Rati instance backed by S3 and get a working router with near-zero startup time — no need to download an 80 GB planet tarball first.

Usage

rati <archive> [OPTIONS]

Arguments:

  • <archive> — S3 location of the tar archive: s3://bucket/path/to/tiles.tar

Options:

Flag Default Description
--scan-index off Build index by scanning tar headers if index.bin is missing
--dataset-id <ID> auto Override the dataset ID (auto-detected from GraphTileHeader if omitted)
--cache-max-age <SECONDS> 86400 Cache-Control max-age in seconds
--port <PORT> 3000 Port to listen on
--concurrency <N> 4 Max worker threads

Example with Valhalla

# Start Rati pointing at an S3 tile archive
rati s3://my-bucket/valhalla/tiles.tar --port 8080

# Generate a Valhalla config pointing at Rati
./valhalla_build_config \
    --mjolnir-tile-url "http://localhost:8080/tiles/{tilePath}" \
    --mjolnir-tile-dir "./valhalla_data" \
    --mjolnir-use-lru-mem-cache=True \
    --mjolnir-max-cache-size=100000000 \
    > ./valhalla.json

See valhalla_build_config for the full list of flags.

Endpoints

GET /                              Status: dataset_id, tile_count, s3_source, s3_etag
GET /tiles/{tilePath}              Tile by path (Valhalla-compatible)
GET /tiles/{tilePath}.gz           Tile by path, gzip-compressed file
GET /tiles_by_id/{tile_id}         Tile by numeric packed ID
GET /health                        Health check

The /tiles/{tilePath} endpoint is directly compatible with Valhalla's mjolnir.tile_url setting, e.g. /tiles/2/000/818/660.gph.

Tile Path Convention

Valhalla identifies tiles by a packed ID that encodes level | (tile_index << 3) — 3 bits for the hierarchy level, 22 bits for the tile index within a level's grid (see valhalla::baldr::GraphId).

File paths are derived by zero-padding tile_index to the nearest multiple of 3 digits and splitting into groups of 3 separated by /, with the level as the first path component. This keeps directory fan-out under ~1000 entries.

Examples:

  • Level 2, tile index 818660 → 2/000/818/660.gph
  • Level 0, tile index 529 → 0/000/529.gph

Gzip Support

Tiles are compressed on the fly. Two modes cover different client expectations:

  1. Transparent compression (Accept-Encoding: gzip) — Response includes Content-Encoding: gzip; compliant HTTP clients decompress automatically and see plain tile bytes. This is the mode Valhalla uses.

  2. Raw gzip file (.gz extension) — Requesting /tiles/2/000/818/660.gph.gz returns the gzip stream as-is, without Content-Encoding. The response body is a gzip file — useful for saving compressed tiles to disk.

CDN Headers

Every tile response includes headers suitable for CDN caching:

Header Description
ETag S3 object ETag, fetched at startup
Last-Modified S3 object last-modified timestamp
Cache-Control public, max-age=<n>, immutable<n> from --cache-max-age (default 86400)
X-Dataset-Id Auto-detected from GraphTileHeader, overridden with --dataset-id, or S3 ETag as fallback
Vary Accept-Encoding — ensures correct CDN behavior with gzip negotiation
Content-Type application/octet-stream

Dataset ID

For graph tile archives (.gph), the dataset ID is automatically extracted from the GraphTileHeader of the first tile in the archive. This is typically the OSM changeset ID (dataset_id_ field, a u64 at byte offset 32 in the 272-byte header).

For any other kind of archive, use --dataset-id to provide an explicit value. If neither works, the S3 ETag is used as a fallback.

Index Modes

Rati supports two archive formats:

Tile extracts with index.bin (default) — The archive contains index.bin as its first entry, a flat binary index where each 16-byte entry holds (offset: u64, tile_id: u32, size: u32) in little-endian format. This is the format produced by valhalla_build_extract. At startup, Rati reads only the first tar header (512 bytes) plus the index payload — two small range requests, fast regardless of archive size.

Plain tars (--scan-index) — For tar archives without index.bin but with files following Valhalla's naming convention, pass --scan-index. Rati scans all tar headers and indexes each filename that parses as a valid tile path. Non-tile entries are silently skipped. This requires reading the full archive at startup, so it is slower for large files.

Build

cargo build --release

License

Dual-licensed under MIT or Apache-2.0 at your option.

About

Lightweight HTTP server for Valhalla tiles stored on S3

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors