OpenStreetMap is a global, openly licensed map database built by contributors. That description is accurate and hides everything a developer needs to know, because the interesting properties of OSM are not that it is free but that it is structured in an unusual way and that its quality varies enormously by place.
Two facts shape every project that touches it. The data model is minimal, three element types and arbitrary key-value pairs, which means the schema is not enforced anywhere. And the data is contributed rather than surveyed, which means completeness follows contributor attention rather than population, economy, or importance.
Both facts are manageable. Neither is discoverable from a sample of a well-mapped city, which is where most evaluations start and why most OSM projects underestimate the work.
The data model: nodes, ways, relations
Everything in OSM is one of three element types, and every element carries tags.
A node is a point with a coordinate. Nodes serve two purposes that are easy to conflate. Some are features in their own right, a tree, a postbox, a shop, and carry tags describing them. Most are untagged and exist only as vertices for ways.
A way is an ordered list of node references. If the first and last references are the same node, the way is closed. A closed way is either a polygon or a loop, and which one it is depends on the tags rather than on the geometry: a closed way tagged as a building is an area, a closed way tagged as a roundabout is a line. There is no separate area type. This is one of the first things that surprises people converting OSM into standard geometry.
A relation is an ordered list of members, which may be nodes, ways, or other relations, each with a role. Relations express structure that a single element cannot. A multipolygon relation combines outer and inner ways into an area with holes, which is how a lake with an island or a building with a courtyard is represented. A route relation groups the ways that make up a bus line or a long-distance path. A turn restriction relation ties together the from-way, the via-node, and the to-way of a prohibited manoeuvre.
Relations are where naive extraction breaks. A tool that reads ways and ignores relations will render a lake as a solid shape with the island painted over, will miss administrative boundaries entirely in most countries, since they are relations assembled from many boundary ways, and will produce a routing graph that permits illegal turns.
Tags apply to all three types. A tag is a key and a value, both free text. There is no type system, no required key, and no constraint that any particular combination makes sense.
Tags are a folksonomy, not a schema
The tagging vocabulary is documented by convention and adopted by usage. A tag becomes standard because enough contributors use it, not because it was specified. This has consequences that no amount of careful querying eliminates.
The same concept has several encodings. A feature may be described by one key in one region and a different key elsewhere, and both may be widely used. Values may be free text where a controlled list would be expected. Numeric values arrive with and without units, in several unit systems, and occasionally as ranges or as prose.
Vocabulary evolves. New keys are introduced, old ones are deprecated, and deprecation does not mean removal: elements tagged years ago retain their original tags until someone edits them. At any moment the database contains several generations of tagging conventions in parallel, and the older conventions concentrate in the places that have seen the least recent editing, which are also the places with the weakest coverage.
Regional practice diverges. Communities in different countries settle on different conventions for the same physical thing, particularly for road classification, address components, and land use. A query calibrated on one country will return a systematically different picture in another, and the difference will look like a real geographic difference rather than a tagging one.
Meaning is not always what the key suggests. Some widely used keys have narrow technical meanings that differ from their everyday reading, and some have meanings that shifted as usage settled. Reading the community documentation for any key before depending on it is not optional.
The practical stance is to write tolerant queries. Match on sets of keys rather than single ones. Treat absence of a tag as unknown rather than as a negative value. Normalise values rather than comparing raw strings. And validate the result of any extraction against a region you know well before trusting it in a region you do not.
The access routes, and when each applies
There are several ways to get OSM data, and choosing wrongly is the most common early mistake.
The full planet dump is the complete database as a single file, distributed in a compact binary format and in a verbose XML format. It is large enough that processing it needs deliberate tooling and meaningful disk and memory. It is the right choice only when the work genuinely spans the world or requires elements that regional cuts would sever.
Regional extracts are pre-cut subsets by country or sub-country region, produced by several providers on a regular cadence. For almost all work confined to one country, this is the correct starting point. Extracts handle the boundary problem for you by including the elements that cross the cut, though how they do so varies by provider and is worth checking if boundary-crossing features matter.
The editing API is for editing. It supports reading, but it is scoped for editor clients fetching a small area to modify, and using it as a data source is both a misuse and impractical for anything but tiny reads.
The query API, the overpass-style interface, is designed for selective extraction: give me the features matching these tags in this bounding box. It is genuinely useful for small live reads, for exploratory work, and for keeping a small area current. It is not a production data backend, and treating it as one is the single most common way that projects end up rate limited or blocked.
Change feeds are the mechanism for staying current without re-downloading. Minutely, hourly, and daily diffs are published, and the standard processing tools can apply them to a local database. Any system that needs fresh OSM data should be built on an initial extract plus applied diffs, not on repeated full downloads.
A decision procedure that covers most cases:
- One-off analysis of a country or smaller: a regional extract, processed locally.
- A live feature that needs a handful of features near a user's position: the query API, cached aggressively, with a fallback for when it is unavailable.
- A production service serving many users: a local database built from an extract and kept current with diffs, or a preprocessed distribution.
- Global analysis: the planet file, with a realistic estimate of processing time before starting.
Do not hammer the public endpoints
The public query endpoints are volunteer-funded shared infrastructure. They are not a content delivery network, they have no commercial support relationship with any caller, and they are used by many people simultaneously.
The behaviours that cause problems are predictable. Firing one query per user request, so traffic scales with your product. Running a loop that walks a grid of bounding boxes across a country. Retrying aggressively on timeout, which converts a slow response into a load spike. Sending queries with no bounding box or with tag filters loose enough to match a significant fraction of the database. Running from a service with no identifying user agent, so nobody can contact you before blocking you.
The consequences arrive in order: slow responses, then rate limiting, then a block on the address range. None of them are negotiable, and none of them are the operator being unhelpful.
The correct posture is straightforward. Identify your client honestly. Bound every query in space and in tags. Cache results and set the cache lifetime by how fast the underlying data actually changes, which for most features is slowly. Rate limit yourself well below whatever the published limit is. And if your usage is anything more than occasional, run your own instance or use a preprocessed distribution, which is cheaper than it sounds and removes an external dependency from your critical path.
Completeness varies enormously
The most important property of OSM for anyone building analysis on it is that coverage is not uniform, and the variation is not random.
Coverage follows contributor activity. Areas with active local communities, university mapping groups, organised import projects, or humanitarian mapping campaigns can be extraordinarily detailed, down to individual trees, bench positions, and building levels. Areas without any of those can have a road network and almost nothing else.
The variation is not only between countries. Within a single city, the central districts are frequently mapped in far more detail than the periphery, and formal settlements in far more detail than informal ones. Building footprints may be complete in one district and absent in the next.
Different feature classes have different coverage profiles in the same place. Road networks tend to be the most complete, since they were the first priority and have been the target of imports. Buildings are highly variable. Addresses are patchy nearly everywhere. Points of interest reflect what contributors found interesting, which skews towards amenities that mappers use.
The failure this produces is the one that matters. An analysis that counts features per area will report low counts where mapping is thin and interpret them as low real-world density. A comparison between two regions will measure the difference in contributor attention and present it as a difference in the world. This is not a subtle statistical issue, it can invert the conclusion.
Two defences. First, never compare raw feature counts between regions without a coverage control: compare against an independent measure, or restrict comparison to areas with similar mapping maturity. Second, treat absence explicitly. In an OSM-derived dataset, no data and none of that thing are different states, and any schema that collapses them into a zero has destroyed the distinction permanently.
The ODbL obligation
OSM is published under the Open Database Licence, and the obligations are real, workable, and frequently misunderstood as either more or less onerous than they are.
Attribution is required wherever the data is shown. The requirement is that credit is visible to the person seeing the map or the derived output, not buried in a legal page. In practice this means a visible line on the map itself, or in the immediate surrounding interface.
Share-alike applies to derivative databases. If you produce a database derived from OSM and distribute it publicly, that derived database must be offered under the same licence. Internal use, and use that only produces images or individual query results, is treated differently from distributing a database.
The distinction that matters most in product work is between a produced work and a derivative database. A rendered map, a report, or a visualisation is a produced work, and the obligation there is attribution. A database that mixes OSM with your own data and is then distributed is where share-alike bites, and the question of whether your data has become part of a derivative database depends on how it was combined.
The engineering response is to design for this from the start rather than to seek an opinion at launch. Keep OSM-derived attributes in identifiable columns or tables. Record per-field provenance rather than per-dataset. Decide early whether the product distributes a database or serves results, because the answer changes what is permissible. And where a customer requires that no share-alike data touches their pipeline, that is a sourcing decision to make before building, not a licence question to litigate afterwards.
Use a preprocessed distribution in production
Raw OSM is a contribution database, not a query-ready dataset. Turning it into something a product can use means resolving relations into geometry, converting closed ways into polygons according to their tags, normalising the tag vocabulary into a stable schema, validating and repairing geometry, building indexes, and handling the elements that were cut at the extract boundary.
Doing that work well is a real project, and doing it badly produces a dataset with subtle errors that surface months later. The alternative is a preprocessed distribution: OSM already converted into a conventional schema with typed columns, valid geometry, and defined update cadence, or a derived product that has done the same work and layered quality control on top.
The tradeoffs are worth being clear about. A preprocessed distribution imposes someone else's schema, which will not include every tag, and it lags the source by the provider's update cycle. Processing raw OSM yourself gives full fidelity and full control, at the cost of owning the pipeline, the update mechanism, and every correctness question that comes with them.
The reasonable default is to use a preprocessed distribution unless the project depends on tags outside the standard schema or on freshness measured in minutes. Most projects that begin by writing their own OSM processing pipeline discover halfway through that the pipeline has become the project.
What to check before committing
Before building on OSM, run three checks in the specific regions the product will serve, not in a well-mapped demonstration city.
Extract the feature classes the product depends on and look at them against imagery or a known reference. Count them per unit area and compare across districts within the same city. The spread tells you whether the coverage is usable.
Sample the tags actually present rather than the tags the documentation describes. The gap between documented practice and local practice is where extraction logic fails.
Check when the elements were last edited. A region whose features were all touched in a single import years ago and never revisited is a snapshot of that import, not a current map, and no amount of query sophistication changes that.