We shipped 'world coverage.' It covered 97 countries.
Open the demo and type an address in Kabul, and the demo returns no result. It does not place a pin a few streets off or fall back to the city center, because the gazetteer has no entry for Kabul. Hong Kong, Tirana, Chişinău, and every place in the Democratic Republic of the Congo return no result as well. We had been calling this gazetteer "world coverage" for weeks, and it covered 97 of the world's ~195 countries. The other ninety-odd countries were absent from the file.
This gap did not come from a single dramatic mistake. It built up without any error, the way most data gaps do, and the most useful part of this post is the audit that finally exposed it.
A missing place never files a complaint
Coverage gaps are hard to see because a missing place does not raise an error. When a parser mislabels a token, the wrong field shows up in a diff. When a resolver picks the wrong Springfield, the pin lands in the wrong state and a test fails. When a place is absent from the gazetteer, the system behaves exactly as it does for a typo or a fictional street: it returns no result. Afghanistan returning no result looks identical to "Hgsdfgh Street" returning no result.
You can run the eval suite, see it pass, ship, and announce world coverage while every number you report is accurate. The US accuracy is real, and so is the German coordinate error. Those numbers are measured against the places that are in the file, so the file determines what gets measured. We were grading ourselves on the 97 countries we had, and the missing countries never entered the average.
This applies to anyone building on open geodata: your coverage is your sources' coverage, and you inherit its gaps without any warning. We build the gazetteer from Who's On First plus Overture's administrative divisions. Both are high-quality sources, and we would choose them again. High quality does not mean complete, though, and the admin DB built from those two sources contains localities for 97 countries. We never decided to drop Libya. It was never in the data, and no stage of the pipeline was designed to detect the absence.
The trick: audit against a yardstick you didn't build
Your own data cannot reveal gaps that are absent from it. Compare it against an independent source and check where the two disagree.
We did the cheapest version of that comparison. GeoNames publishes cities15000, a flat file of every populated place on Earth with more than 15,000 people. We already had it on disk. For each country, we counted the localities in our gazetteer and the cities in GeoNames and printed the ratio. The audit took about a minute to write. Most countries had reasonable ratios, and a long column of countries had zero:
country ours GeoNames cities>15k
AF 0 54
HK 0 141
KP 0 97
CD 0 114
AL 0 25
...
Hong Kong has a hundred and forty-one cities in the reference and zero in ours. Model settings cannot fill a gap of that size. We checked whether the candidate build was filtering out data that existed, and it was not: the source admin DB itself stops at 97 countries. The gap was real and came from upstream.
This external comparison was the most productive hour of the whole effort, and it was simple. It needed no model or new metric. It needed a comparison of our file against someone else's count. The main recommendation of this post is to compare your coverage against a reference you did not build, along whatever dimension matters to you. A gap you cannot see still limits your results.
A data update fills the gap without retraining
A pure data gap needs only a data fix. It needs no GPU, model, or retrain, because GeoNames already has the places, with coordinates and per-language names, for every country we were missing. We extended our gap-fill builder to register country codes it had not seen before and ran it on the full allCountries dump, keeping only current populated places and dropping historical and abandoned ones.
The result is 4.6 million town-level localities across 248 countries, up from 97. We also checked a handful of major cities in the previously empty countries because each result must place the city correctly. Kabul resolves to Kabul within a few hundred meters. Hong Kong, Tirana, Tripoli, Sarajevo, and Yerevan also resolve correctly. All nine checked cities landed within thirty kilometers, and most were exact. A spot-check of small towns placed them inside the correct country's bounding box two hundred times out of two hundred.
The cost
The change has a cost. Full town-level depth grows the gazetteer from 811 MB to 1.26 GB. That size costs little on a server but matters in the browser, where the demo streams the database a few kilobytes at a time over byte-range requests, and a file about 50% larger means about 50% more data to range over. The fix is therefore two builds. The browser gets the major cities. That build is light and covers most of what people type. The CLI and server get the full town depth, where storage is cheap. One builder produces both depths, and you choose which artifact gets which.
A place resolving is also different from a full address parsing. With Kandahar in the gazetteer, the resolver now places the word "Kandahar" in Afghanistan instead of returning no result. Whether our parser reliably extracts "Kandahar" from a raw Afghan address string is a separate question for a separate post. Coverage was a prerequisite, and this work completed it.
Compare your data against a reference you did not build, count the disagreements, and look closely at the zeros. Our gap passed every test for weeks before this audit found it. Your data probably has one too.
