Start Your Overture Migration With One Region, Not the Whole Planet
Nothing breaks the day your pipeline starts reading Overture Maps. Release 2026-09-23.1 serves tiles, answers analytics queries, and sits quietly beside the OpenStreetMap extract nobody has uninstalled yet. The quiet is the trap: with no fire to put out, the migration slips a quarter, and OSM's maintenance cost keeps arriving every month while the comparison tab stays open on your screen. This post is for the GIS lead in exactly that position, the one who has to put a plan in front of a CTO.
The plan, stated so you can argue with it: a base-map migration from OSM to Overture is eight steps of unglamorous pipeline work that fits inside one quarter. The teams it hurts are the ones that start with the whole planet instead of one region. Loading the data is the easy half of that work. The other half retires assumptions your OSM pipeline grew on without anyone writing them down, and the list of those five comes first, because every step of the plan exists to retire one of them.
The switch breaks five assumptions before it breaks any code
Break one is schema. OSM hands your pipeline free-floating tags, and every crosswalk from tags to columns is a schema you own by another name. Overture hands you the columns, taxonomy.primary for the category and speed_limits with a unit attached, and it versions that schema as a whole. Schema v2.0.0 in release 2026-09-23.1 removed the places categories field in favor of taxonomy and basic_category, and every query written against the previous minor version stopped running in the same month. That removal is the case study for step one, not a scare story.
Break two is identity. OSM gives you node and way IDs, which churn whenever a mapper retraces the same wall. Overture gives you GERS identifiers, designed to survive exactly that churn. The two systems do not translate into each other, because a node ID names an edit that happened once and a GERS ID names a feature that persists. What moves your records onto the new layer is a join you build and then maintain, which is nearer to owning a data product than to converting a format. We documented the join itself, version counters included, in joining two map datasets by GERS identifiers.
Break three is license posture, and it surfaces in paperwork rather than code. Overture publishes its data under the CD-ODbL-BY license. The schema documentation is CC BY and the tooling is MIT. Write that into your architecture document in those words. Then attach this caveat next to it, in the same plain words: how a database license's share-alike terms treat your derived tables deserves an actual legal read before your company commits. We are engineers, not lawyers, and a migration is the wrong week to discover what the obligations on a derived database were.
Break four is freshness, because the two sources run on different clocks. OSM is live: an edit made in the morning in one city can be inside your extract before the week is out. Overture publishes monthly, so release 2026-09-23.1 was already a month of history on the day it landed. Neither clock is wrong. Your product contains both kinds of data, though, so the decision has to happen layer by layer. Building footprints feeding a coverage report tolerate a month of age. A restaurant's opening hours in a delivery app do not, and OSM stays on that layer.
Break five is tooling maturity, named here so it cannot ambush you in step six. The OSM tooling around your pipeline is twenty years old and boring. Overture's is young enough to shift between releases, which is a property to plan around rather than a reason to wait. The sharpest edge is the addresses theme: 474 million features, marked alpha in the Overture docs, with no GERS identifiers yet. None of that blocks the base-map move. It just means the geocoder is the last thing to migrate, and step six says so out loud.
The plan: eight steps, one region
Every step below runs against one region, and the region is ours. It is a Tahoe bounding box from longitude -121.0 to -119.6 and latitude 38.7 to 39.5, the sample we load whenever we want Overture answers on a laptop. Counts next to its name come from queries run with DuckDB 1.5.6 on 2026-10-11, against release 2026-09-23.1 unless the sentence says otherwise. Your region will produce different numbers in every row. The shape of the work is the part that transfers.
Step one pins the release before any data moves. The identifier 2026-09-23.1 goes into a constants file in your repository, and every script that follows reads the release from that file. A check in CI fails any build where two scripts disagree, because the v2.0.0 schema break showed what an unpinned minor version does to a query. Pinning costs ten minutes and buys something pricier: the ability to reproduce every number you print in an incident report.
Step two cuts the extract, and it does so in place, with DuckDB. Install the spatial and httpfs extensions, point read_parquet at the release path with hive partitioning on, and filter on the bbox struct column rather than geometry. That predicate prunes Parquet files and rows without opening a single geometry, which is how our box answered 28,166 places in 2.77 seconds and 228,935 buildings in 37.1 seconds on 2026-10-11. The full recipe, extensions and partition behavior included, is in querying Overture with DuckDB.
Step three maps your schema and your identity in the same sitting. For each OSM tag your pipeline actually reads, name the Overture column that replaces it, and write NULL where nothing does, because those rows are your rewrite list. Build the OSM-to-GERS join table here as well, keyed to the pinned release. Expect some rows to resist: in our Tahoe sample, 896 of 28,166 places, 3.2 percent, had no taxonomy.primary, so any logic resting on that column needs a fallback path written the day you map it.
Step four lands serving by workload, and the workload picks the store rather than taste. Questions that used to be Overpass queries go to DuckDB, which keeps reading the pinned release in place. The map your application reads goes to PostGIS, loaded from the extract. Documents that already live in MongoDB can absorb Overture directly, because the official overturemaps-py CLI writes to MongoDB as one of its output modes. We ran the same questions through the three paths in storing Overture in Postgres, MongoDB, and DuckDB.
Step five rebuilds tiles from the pinned extract, not from whatever the previous renderer left behind. The official tiles tooling emits PMTiles from Overture GeoParquet, and the docs' build-a-map example walks from DuckDB through tile generation to a MapLibre viewer. Name the tile bundle after the release it came from, the way you named the extract. A tile set without a version attached is just the next crosswalk table without an owner.
Step six adds geocoding and routing only where the product requires them, and "requires" is doing real work in that sentence. Teams that answer address questions from their own tables may need no geocoder at all on day one. Where you route, the omf-bifrost project builds Valhalla graph tiles from Overture GeoParquet, and it is the most mature tool of its kind in the ecosystem, which is faint praise. Where you geocode, benchmark before you commit. The overture-geocoder project publishes 80 percent top-1 accuracy on city questions against Nominatim's 67 percent, a figure its authors scope to city lookups. A test narrower than your production traffic deserves exactly the skepticism you would give a figure of ours.
Step seven dual-reads through the cutover window. Both readers stay pointed at their sources while the Overture path accumulates weeks of evidence, with OSM still owning the fresh-venue layer per the freshness break. There is no big flag flip. A layer stops dual reading when its QA passes against two consecutive releases, and until then both pipelines keep earning their keep.
Step eight writes the QA checklist and the rollback date on the same day the cutover starts. Recount features against the pinned release. Spot-check attributes on ten features you can visit. Render the tiles at three zoom levels and look at them. Every check cites the release ID it ran against, and the rollback date goes on a calendar with a name next to it, because a rollback nobody owns is a rollback that does not happen.
The planet-first attempt we do not repeat
Our own record includes precisely the mistake this post argues against. Our first Overture session pulled answers about the whole planet, 81,455,423 places and 4,688,229 divisions, when the actual question on the screen was one region's worth of data. The counts were honest and useless to a plan: no extract, no schema map, no join table, and a data volume far past the serving decisions of step four. A migration that begins with the entire planet buys the same lesson a month later at a higher price. Region first, planet when the product actually spans one, is now the sequence we push in every conversation where a CTO is in the room.
What this plan cannot promise
Nothing here comes from a client engagement, so the post carries no invented before-and-after numbers. The opinion is the kind you form from maintaining OSM pipelines, in our case years of them. One of those pipelines is the trail graph we build from OpenStreetMap, whose tag-interpretation layer outgrew the graph code underneath it and is never finished.
The tooling caveat stays real as well. The routing builder and the community geocoders are young code, the addresses theme is alpha, and the schema has already broken a minor version once. The plan absorbs that by design: one pinned release, one region, and a geocoder that stays put until your own benchmark says otherwise are what let the young parts fail safely. And the license question remains a legal one we cannot answer for you. What we can do is read the release notes with you, pin the release, and hand you the measured numbers for your region.
The decision in one line: give the migration one quarter, start it on one region's data, and hold the rollback date to a standard a CTO can read without a translator.
AngoraTek runs base-map migrations like this one for small teams. If the comparison tab on your screen has been open longer than you would like to admit, bring us that region and we will run step two together.Thanks for reading this far. If this sounds like the problem you're wrestling with, tell us about it. A principal reads every message.
Start a conversation