# Imposm3 loads OpenStreetMap PBF files into a PostGIS schema built for tiles

> Imposm3 is a Go command line importer that reads OSM PBF extracts and writes them into PostGIS with mapping files, a LevelDB node cache and diff updates. It suits operators who need a rendering-oriented database, and it is a poor fit for anyone who needs a general purpose GIS schema or end-user support.

**omniscale/imposm3** — Imposm imports OpenStreetMap data into PostGIS

- Repository: https://github.com/omniscale/imposm3
- Website: http://imposm.org/docs/imposm3/latest/
- Stars: 774 · Forks: 161
- Language: Go
- License: Apache-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/omniscale-imposm3

## Imposm3 targets one narrow job: a database shaped for rendering

Imposm3 is a command line importer for OpenStreetMap data, written in Go, that reads PBF files and writes the result into PostgreSQL with the PostGIS extension. Its purpose is stated plainly in the project documentation: it creates databases that are optimized for rendering, which the same text defines as generating tiles or serving WMS services. That is a much narrower goal than building a general purpose GIS database, and it explains most of the design choices that follow.

The audience is operators who already run PostGIS, already have an extract, and need imports they can repeat rather than a one-off load into an existing multi-purpose schema. The tool is a single binary whose only runtime dependencies are common libraries, GEOS and LevelDB. Omniscale, the company that sponsors the development, uses the importer in production, and the project states plainly that there is no capacity for end-user support and that no new features will be developed beyond the existing scope.

## The node cache is the reason ways and relations can be assembled at all

Two mechanisms carry most of the speed. First, parsing is distributed to all available CPU cores from the ground up rather than being a single threaded pass over the file. Second, the write path uses bulk inserts into PostgreSQL with COPY FROM instead of individual INSERT statements.

Between those two stages sits a file-based key-value cache of OSM nodes. The reasoning is documented plainly: every node has to be stored, because ways and relations are built by joining their member nodes, and keeping that intermediate data out of the main database reduces IO load while geometries are assembled. The cache directory is set through the cachedir key in the configuration file.

Value normalisation happens on the way in. The boolean-like strings 1, on, true and yes all become TRUE in the target tables, so a styling layer never has to handle four spellings of the same condition. Imports can also be limited to specific tags and values so that only data you intend to render is loaded at all.

## Getting the binary onto a server, and what it needs once it is there

Binary releases are published on GitHub for x86 64bit Linux, and those builds carry no further dependencies. They are compatible with Debian 10 and other distributions from 2022 or newer. Building from source is the route when you need an older distribution, and the quick version is a single go install call that places the tool in ~/go/bin/imposm:

```bash
    go install github.com/omniscale/imposm3/cmd/imposm@latest
```

The build you are likely to want in production is the one that stamps version information into the binary:

```bash
    git clone https://github.com/omniscale/imposm3.git
    cd imposm3
    make build
```

Even a static Go binary still needs the C and C++ libraries, libleveldb and libgeos, and GEOS 3.2 or newer is recommended because geometry handling became far more reliable at that version. LevelDB newer than 1.21 is recommended for performance, while a build tag exists for older LevelDB versions. A Dockerfile in the repository root shows how standalone Linux binary packages are assembled, using podman build against a Debian 10 base image.

## The mapping file decides which tables exist and which columns they hold

A first import is driven by a JSON mapping that describes the target tables, and the repository ships example-mapping.json and example-mapping.yml as starting points. The basic form of the command takes a connection string, a mapping, a PBF path and the write flag:

```bash
    imposm import -connection postgis://user:password@host/database \
        -mapping mapping.json -read /path/to/osm.pbf -write
```

Tables are created inside a schema named import, which gives you names such as import.osm_roads. If you want the tables in the public schema instead, the deployproduction flag handles that, and it also sets up the indexes and generalisation tables needed for rendering:

```bash
    imposm import -connection postgis://user:passwd@host/database \
        -mapping mapping.json -deployproduction
```

Options can live in a JSON configuration file so that connection strings and paths stay out of shell history:

```json
    {
        "cachedir": "/var/local/imposm",
        "mapping": "mapping.json",
        "connection": "postgis://user:password@localhost:port/database"
    }
```

Pass that file with the config flag and add any extra arguments after it, and run imposm import -help for the rest of the surface. One security detail deserves attention: TLS and SSL are disabled by default, so set the PGSSLMODE environment variable or the sslmode connection option to require or verify-full before pointing the importer at a database that is not on localhost.

## Diff mode and the imposm run service keep the database close to current

The importer has two modes, and the difference matters for how you plan capacity. A full import reads an extract from scratch. A diff import applies only the changes needed to bring a database up to date, which is what makes repeated updates cheap enough to run on a schedule.

The same command line handles both, and a background service called imposm run is included for the update case. It downloads the latest OSM changes and imports them, so an operator can keep a database current without hand-running imports.

Two other constraints shape what you can import. Geometries can be limited to polygons taken from GeoJSON, which is the mechanism behind city, state and country level extracts rather than a whole planet file. And generalised tables are created automatically at lower spatial resolutions, which is what makes rendering a large road network at low zoom levels practical. The importer also handles all relation types, including routes, and supports a table namespace so that imported tables can live in a PostgreSQL schema of your choosing.

## The documented planet import needs a machine, and the clock matters

The performance figures in the project documentation are specific and worth reading closely, because they set the hardware floor. A diff-mode import of a 78GB planet file dated 2024-01-29, with generalised tables and spatial indices, took roughly 7 hours and 30 minutes on a Hetzner AX102 server with an AMD Ryzen 9 7950X3D, 256GB of RAM and NVMe storage. The same documentation states that the non-diff mode is faster.

The memory rule is stated as a ratio rather than a table: budget roughly twice the size of the PBF extract you are importing. That works out to 192GB of RAM or more for a 78GB planet file, and 8GB for a 4GB regional extract. Imports on spinning disks take significantly longer and are explicitly not recommended.

The limits are real as well. The documentation does not describe a rollback path for a failed or interrupted import, so a partial load leaves you comparing tables by hand. There is no end-user support channel beyond a mailing list, and the stated policy is that no new features will be developed beyond the current scope. TLS is off unless you turn it on. And the convenient binaries exist only for x86 64bit Linux.

## Licensing separates the source build from the binary you download

The project itself is released under the Apache License 2.0, which is the permissive licence most Go projects use and which keeps commercial use and redistribution straightforward, subject to the usual notice and patent conditions.

The dependencies complicate the picture slightly. Dependencies that are included as source code are released under a BSD-ish licence, and the same holds for dependencies bundled in the binary releases, with one exception: the GEOS package is released under LGPL3 and is linked dynamically. That distinction matters for redistribution. Copying a self-built binary that statically embeds GEOS is a different legal situation from shipping the published tarball where GEOS stays a separate shared library. The repository keeps LICENSE, LICENSE.deps and LICENSE.bin for the three cases.

On maintenance, the last push to the repository was on 2026-08-05 and the project is not archived, so the code is still receiving fixes. The releases tell a slower story than the commit activity: v0.14.0 on 2024-07-22, v0.14.1 on 2025-02-24 and v0.14.2 on 2025-05-12. The project describes its own focus as resolving future incompatibilities with dependencies such as PostGIS, which is a maintenance stance rather than a feature roadmap.

## Conclusion

Imposm3 is the right choice for a team that renders tiles or WMS layers from OpenStreetMap and controls its own PostGIS instance, and the wrong choice for a project that wants a general purpose GIS database, needs a supported product, or must run the importer on something other than x86 64 Linux. Before the first import, check the mapping file against the columns your style expects, set the sslmode option if the database connection leaves the host, and confirm the server has roughly twice the memory of the PBF file you plan to load.

## FAQ

### How do I install imposm3 on Linux?

Binary releases for x86 64bit Linux are published on GitHub and need no further dependencies, and they are compatible with Debian 10 and other distributions from 2022 or newer. From source, the quickest route is go install github.com/omniscale/imposm3/cmd/imposm@latest, while git clone followed by make build is the recommended way because it adds version information to the binary. Either way the C and C++ libraries libleveldb and libgeos are still required at runtime.

### How much memory do I need to import a large OpenStreetMap extract?

The recommendation is roughly twice the size of the PBF extract you are importing, so a 78GB planet file calls for 192GB of RAM or more, and a 4GB regional extract needs about 8GB. Imports on spinning disks take significantly longer and are not recommended. A diff-mode import of a 78GB planet file took around 7 hours and 30 minutes on a server with 256GB of RAM and NVMe storage.

### Does imposm3 keep a PostGIS database up to date automatically?

Yes, the project includes a background service called imposm run that downloads the latest OSM changes and imports them. The importer also supports diff mode, where only the changes since the previous import are applied, which is much cheaper than a full import.

### Is the database connection encrypted by default in imposm3?

No. TLS and SSL support is disabled by default, so you have to enable it yourself. Set the PGSSLMODE environment variable or the sslmode connection option to require or verify-full for an encrypted connection.

## Sources

- [License: Apache-2.0](https://github.com/omniscale/imposm3/blob/master/LICENSE)
- [omniscale/imposm3 on GitHub](https://github.com/omniscale/imposm3)
- [Project website](http://imposm.org/docs/imposm3/latest/)
- [README](https://github.com/omniscale/imposm3/blob/master/README.md)
- [Releases](https://github.com/omniscale/imposm3/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/omniscale-imposm3
