Command-line reference
Every flag, every subcommand.
Cairn ships two binaries: cairn-build for everything
offline (build, augment, sign, replicate, inspect) and
cairn-serve for the runtime HTTP API. This page
documents every subcommand and every flag, with examples for the
common workflows.
00
The two binaries
cairn-build
Offline pipeline. Reads upstream sources (OSM PBF, WhosOnFirst
SQLite, OpenAddresses CSV, Geonames TSV, GeoParquet, Overture
drops, Microsoft Building Footprints, Wikidata dumps) and emits
a self-contained bundle directory: tile blobs,
spatial layers, text index, manifest, signature.
Also handles incremental updates (replication, diff/apply),
augmentation (lane A buildings, lane I Wikidata), signing,
and inspection.
cairn-serve
Runtime. Loads one or more bundles via mmap and
serves the HTTP API: search, autocomplete, reverse, parse,
place lookup, layers metadata, healthz, metrics, OpenAPI spec.
Federation built in — pass --bundles a/,b/,c/
to fan out across continental shards from one process. Hot
reload via POST /admin/reload; signed manifest
verification at startup.
Help on demand. cairn-build --help and
cairn-build <subcommand> --help always print
the canonical surface — this page mirrors the same content but
groups examples and adds the operator-facing context the
machine-generated help can't.
01
Common workflows
Build a country bundle from OSM + WoF + OA
cairn-build build \
--osm liechtenstein-latest.osm.pbf \
--wof whosonfirst-data-li.spatial.db \
--oa openaddresses/li.csv \
--geonames geonames-LI.txt \
--postcodes geonames-LI-postcodes.txt \
--out ./bundle-li \
--bundle-id "li-2026-04" \
--simplify-meters 100
Produces bundle-li/ with a self-contained corpus.
The --simplify-meters flag trims admin polygon
vertices below 100 m precision; saves 30-60 % bundle size on
dense boundaries with no user-visible change.
Augment with Microsoft Building Footprints + Wikidata
cairn-build augment \
--bundle ./bundle-li \
--buildings ms-buildings-li.parquet \
--wikidata wikidata-20260420-all.json.gz \
--key ./signing/cairn.key
Layers building footprints into spatial/buildings/,
runs the spatial join to stamp building_id on
Places whose centroid lands inside a building bbox, then streams
the Wikidata dump to enrich Place names with multilingual
labels and cross-refs (P1566 GeoNames ID, P300 ISO 3166-2,
P901 FIPS, P131 admin parent, P31 instance-of for kind
refinement). Re-signs the manifest at the end.
Generate keys, sign, verify
cairn-build keygen --out ./signing
cairn-build sign --bundle ./bundle-li --key ./signing/cairn.key
cairn-build sign-verify --bundle ./bundle-li --pubkey ./signing/cairn.pub
Incremental updates (OSM minutely)
cairn-build replicate-fetch --bundle ./bundle-li \
--upstream https://planet.openstreetmap.org/replication/minute --max 60
cairn-build replicate-status --bundle ./bundle-li
cairn-build replicate-apply --bundle ./bundle-li --max 60
Fetches up to 60 minutely diffs, prints state, then applies
them to place tiles. Way + relation re-application is deferred
(logged + skipped); run a full rebuild from PBF for boundary
churn.
Diff + apply between bundles
cairn-build diff --old ./bundle-li-old --new ./bundle-li --out ./bundle-li.diff
cairn-build apply --bundle ./bundle-li-old --diff ./bundle-li.diff \
--source ./bundle-li-new-mirror
Computes a tile-level delta as a TOML manifest, then applies it
on the receiving side without re-downloading the whole bundle.
Designed for airgap upload paths.
Serve
# Single bundle.
cairn-serve --bundle ./bundle-li --bind 0.0.0.0:8080
# Federated (planet split into continents).
cairn-serve --bundles ./bundle-eu,./bundle-na,./bundle-as --bind 0.0.0.0:8080
Inspect a tile
cairn-build inspect-tile --bundle ./bundle-li --tile 2:49509 --sample 5
cairn-build inspect-admin-tile --bundle ./bundle-li --tile 1:12345
cairn-build inspect-building-tile --bundle ./bundle-li --tile 2:49509
02
cairn-build — subcommand reference
Every subcommand below corresponds to cairn-build <name>.
Run cairn-build --help for the live list, or
cairn-build <name> --help for a single
subcommand's flag table.
build
Build a bundle from configured sources.
| Flag | Type | Default | Notes |
--osm | path | — | OSM PBF input. |
--wof | path | — | WhosOnFirst SQLite (spatial.db). |
--oa | path | — | OpenAddresses combined CSV. |
--geonames | path | — | Geonames named-feature TSV (allCountries.txt or per-country). |
--postcodes | path | — | Geonames postcode TSV (<CC>.txt). |
--csv | path... | — | Operator CSV files. Repeatable. Columns: lon,lat,name minimum; kind, population, lang, id optional. |
--geojson | path... | — | Operator GeoJSON FeatureCollections. Repeatable. Point preferred, polygon centroid fallback. |
--parquet | path... | — | GeoParquet files (WKB Point in geometry). Repeatable. Foundation for Overture. |
--parquet-config | path | — | Optional TOML mapping override for --parquet column names. |
--overture | spec... | — | Overture drops as <theme>:<path> (places or addresses). Repeatable. Each row stamped SourceKind::Overture. |
--out | path | required | Bundle output directory. |
--bundle-id | string | alpha-bundle | Stamped on the manifest + metrics. |
--no-zstd | flag | off | Disable zstd tile compression. Default ZSTD on (~50-70 % size drop). |
--source-priority | csv | wof,osm,oa,geonames | Cross-source dedup priority; earlier = higher trust. |
--simplify-meters | float | 0 | Douglas-Peucker tolerance in meters for admin polygons. 0 disables. Reasonable: 50-200 m. |
--node-cache | enum | auto | OSM node-coord strategy: auto / inline / sorted-vec / flatnode. |
--flatnode-path | path | <pbf-stem>.flatnode.bin | Override flatnode location when --node-cache flatnode is in effect. |
--node-cache picker
- auto — picks
inline at ≤ 5 GB, sorted-vec at 5-30 GB, flatnode above 30 GB.
- inline — HashMap, fastest lookup, ~48 B/entry.
- sorted-vec — i32-quantized binary-searchable Vec, ~16 B/entry.
- flatnode — disk-backed mmap'd dense
[i32;2] array indexed by node id; bounded RSS regardless of input size.
augment
Apply v0.3 enrichers (Microsoft Building Footprints + Wikidata) to an existing bundle.
| Flag | Type | Default | Notes |
--bundle | path | required | Bundle to augment in place. |
--buildings | path... | — | Building-footprint GeoParquet drops. Repeatable. Polygons partitioned to per-tile rkyv blobs at L2 and recorded in manifest.building_tiles. |
--no-building-attach | flag | off | Skip the Place-tile spatial join. Default behavior stamps building_id + building_height on Places whose centroid lies inside a building's actual outer ring (strict ray-cast point-in-polygon, not just the enclosing bbox). |
--wikidata | path | — | Wikidata JSONL dump (.json[.gz]). Two-pass: collect Q-ids from existing place tags, then stream the dump to extract labels + aliases + cross-refs and rewrite affected tiles. |
--key | path | — | Optional ed25519 secret. Re-signs manifest.toml after augment. |
Both lanes are idempotent: re-running with the same inputs
produces a byte-identical bundle (deduped by (lang,
value) and (key, value) before insertion).
Wikidata also runs the P31 instance-of check to refine
PlaceKind when the upstream importer fell back to
Poi.
verify
Verify bundle integrity against its manifest (blake3 every tile, admin layer, point layer, building layer, text index segment).
| Flag | Type | Default | Notes |
--bundle | path | required | Bundle to verify. |
info
Print summary information about a bundle (sources, schema_version, tile counts, sizes, sign state).
| Flag | Type | Default | Notes |
--bundle | path | required | Bundle to summarize. |
diff
Compute a tile-level diff manifest between two bundles.
| Flag | Type | Default | Notes |
--old | path | required | Older bundle (the one to migrate forward). |
--new | path | required | Newer bundle (the source of truth). |
--out | path | required | Output diff manifest path (TOML). |
apply
Apply a previously-computed diff to a target bundle.
| Flag | Type | Default | Notes |
--bundle | path | required | Bundle to migrate forward (the old from diff). |
--diff | path | required | Diff manifest from cairn-build diff. |
--source | path | required | Mirror of the new bundle to pull added/changed files from. |
inspect-tile
Decode a single place tile and pretty-print its contents.
| Flag | Type | Default | Notes |
--bundle | path | required | Bundle to read. |
--tile | string | required | LEVEL:TILE_ID, e.g. 2:49509. |
--sample | int | 10 | Place rows to print. |
--grep | string | — | Substring filter on default name (case-insensitive). |
inspect-admin-tile
Decode a single admin spatial tile and pretty-print its AdminFeature list.
| Flag | Type | Default | Notes |
--bundle | path | required | Bundle to read. |
--tile | string | required | LEVEL:TILE_ID. |
inspect-building-tile
Decode a single building spatial tile (v0.3 lane A) and print per-building rows (id, centroid, bbox, vertex count, height).
| Flag | Type | Default | Notes |
--bundle | path | required | Bundle to read. |
--tile | string | required | LEVEL:TILE_ID. |
--sample | int | 10 | Building rows to print. |
replicate-fetch
Fetch new OSM minutely diff files into <bundle>/replication/. Idempotent.
| Flag | Type | Default | Notes |
--bundle | path | required | Target bundle. |
--upstream | url | (state file) | e.g. https://planet.openstreetmap.org/replication/minute. Required on first run; remembered after. |
--max | int | 60 | Cap on diffs fetched per invocation. Stale bundles catch up over multiple runs. |
replicate-status
Print the current replication state for a bundle.
| Flag | Type | Default | Notes |
--bundle | path | required | Bundle to inspect. |
replicate-apply
Apply previously-fetched OSM minutely diffs to the bundle's place tiles.
| Flag | Type | Default | Notes |
--bundle | path | required | Target bundle. |
--max | int | 60 | Cap on diffs applied per invocation. |
--dry-run | flag | off | Parse + bucket without rewriting any tile blobs. Prints dirty-tile count + per-action histogram. |
keygen
Generate a fresh ed25519 signing keypair (cairn.key + cairn.pub).
| Flag | Type | Default | Notes |
--out | path | required | Directory to write keys into. Refuses to overwrite an existing cairn.key. |
sign
Sign <bundle>/manifest.toml with the secret key. Writes manifest.toml.sig.
| Flag | Type | Default | Notes |
--bundle | path | required | Bundle directory. |
--key | path | required | Path to cairn.key. |
sign-verify
Verify manifest.toml against manifest.toml.sig using the public key. Non-zero exit on failure.
| Flag | Type | Default | Notes |
--bundle | path | required | Bundle directory. |
--pubkey | path | required | Path to cairn.pub. |
03
cairn-serve — runtime flags
One process, one mmap region, one HTTP listener. Federation
transparent to clients — pass multiple bundles and the router
fans out per-request.
| Flag | Type | Default | Notes |
--bundle | path | — | Single bundle directory. Mutually exclusive with --bundles. |
--bundles | csv paths | — | Comma-separated list of bundle dirs to federate. Each keeps its own indices; queries fan out + merge by score (or distance for reverse). |
--bind | SocketAddr | 0.0.0.0:8080 | Listen address. |
Either --bundle or --bundles is
required. Auth + rate-limiting + CIDR proxy trust are
configured at the API layer (env vars + headers) — see the
OpenAPI spec at /openapi.json on a running
instance for the runtime contract.
Endpoints exposed
Forward search (/v1/search), structured search
(/v1/structured), reverse (/v1/reverse),
autocomplete (/v1/autocomplete), parse
(/v1/parse, /v1/expand), place lookup
by gid or u64 (/v1/place?ids=…), buildings
(/v1/buildings), layers metadata
(/v1/layers), bundle info (/v1/info),
SBOM (/v1/sbom), unprefixed aliases of the same
endpoints (/search, /autocomplete,
/reverse, /place) for clients that
target the unversioned path, ops endpoints
(/healthz, /readyz,
/metrics, /openapi.json), and admin
hot-reload (POST /admin/reload).