# uber/h3: a hexagonal hierarchical index for geospatial data

> H3 is Uber's C library for indexing the planet into hexagons at 16 resolutions, with bindings for Java, JavaScript, Python and others. It is a good fit when you need one cell id per point and fast neighbour lookups, and the wrong tool when you need exact polygon coverage.

**uber/h3** — Hexagonal hierarchical geospatial indexing system

- Repository: https://github.com/uber/h3
- Website: https://h3geo.org
- Stars: 6,574 · Forks: 626
- Language: C
- License: Apache-2.0
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/uber-h3

## What problem uber/h3 solves, and who ends up using it

Storing a latitude and longitude pair per row makes spatial joins expensive and makes any question of the form "which points are near this one" a range scan on two columns. H3 replaces the pair with a single 64-bit integer that names a hexagonal cell, and the cell carries its own resolution in its bits. The README describes the project as a geospatial indexing system using a hexagonal grid that can be approximately subdivided into finer and finer hexagonal grids, combining the benefits of a hexagonal grid with S2's hierarchical subdivisions. That sentence is the whole pitch, and it is accurate.

The audience is narrower than the star count suggests. H3 is a C library first; the README points readers at prebuilt bindings for Java, JavaScript, Python and others rather than asking them to link C. In practice the users are backend engineers bucketing ride requests, delivery zones or sensor readings into cells they can group by in SQL, and analysts who want a hexagon layer on a map. If your work stops at drawing polygons, you are not the target reader.

## How the hexagonal hierarchy actually works

An H3 index is an integer. The resolution is encoded in it, between 0 (coarsest) and 15 (finest), so a cell id is self-describing and you do not need a separate column to know its granularity. The hierarchy is the part worth understanding before you design a schema: a coarse cell can be subdivided into finer cells, and the reverse operation rolls a set of fine cells back up. The README is explicit that this subdivision is approximate, which is the honest framing. Hexagons do not tile a sphere exactly, and the library handles the mismatch with pentagons and with cells whose children do not nest perfectly.

That approximation is the trade-off you are buying. In exchange you get neighbours at a uniform distance in every direction, which a square grid cannot offer, and you get a resolution ladder that lets one dataset answer questions at several zoom levels. The examples directory ships small programs named after the operations they demonstrate: compactCells.c, distance.c, edge.c, index.c, neighbors.c. Reading those six files tells you more about the intended API surface than the README does.

## Installing uber/h3 and getting your first cell id

The README recommends prebuilt bindings where they exist, and on macOS a single brew command is the shortest path:

```bash
brew install h3
```

If you are building the C library instead, you need a C compiler (the README says it is tested with gcc and clang), CMake and Make. Check out the released tag rather than the development branch, since the repository defaults to the latest development version:

```bash
git checkout v$(<VERSION)
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make
```

The README notes that all subsequent make commands should run from inside the build directory. You can install system-wide with sudo make install, and clean up by removing the build directory from the repository root.

The command line tools are the fastest way to see what the library does. This converts the coordinates of the Statue of Liberty at resolution 10 into a cell id:

```bash
./bin/latLngToCell --resolution 10 --latitude 40.689167 --longitude -74.044444
```

The README states you should get an H3 index as output, like 8a2a1072b59ffff. Feed that index back in to see the hexagon's corners, or use cellToLatLng to get its center coordinate. Those three tools together are enough to sanity-check that your build works before you write any binding code.

If you prefer to stay in Python or JavaScript, install the binding for your language instead and skip the C build entirely. The README links h3-py and h3-js from the Installing section rather than duplicating their instructions.

## Where H3 is the wrong choice

The approximate subdivision is not a rounding detail you can ignore. If your pipeline needs exact polygon coverage, with no gaps and no overlaps, hexagons are the wrong primitive and H3 does not pretend otherwise. Area and boundary calculations over a region will carry error that compounds as you aggregate cells, and the library gives you cell boundaries, not a boolean predicate for arbitrary geometry.

Version skew between the C library and the bindings is the second trap. The C repository is at v4.5.0, released on 2026-05-21, while h3-java, h3-js and h3-py live in separate repositories with their own release cadences. A function that exists in the C headers may not be exposed in the binding you installed, and the README does not document a compatibility matrix. Verify the binding's version against the C release before you design around a specific call.

Finally, H3 assumes a spherical Earth model. If your application is small enough that a local projected coordinate system would do, a hexagonal global index adds a conversion step and a dependency for no benefit.

## uber/h3 against S2 and geohash

The README itself names S2 as the comparison point, describing H3 as combining a hexagonal grid with S2's hierarchical subdivisions. The difference in approach is the cell shape. S2 subdivides the sphere into quadrilaterals on a cube projection, so its cells have four neighbours and vary in shape across the projection; H3 uses hexagons, which have six equidistant neighbours. If your algorithm is neighbour-based (smoothing, adjacency, k-ring expansion), the hexagon is the more natural fit. If your algorithm is quadtree-based or you already store S2 cell ids, switching costs you a reindex of existing data.

Geohash is the other common comparison and the difference is starker. A geohash is a string prefix on a rectangular grid, which makes prefix matching trivial but gives you anisotropic neighbours: cells to the east and west are a different distance than cells to the north and south. H3 trades that string-prefix convenience for uniform adjacency. The cost is that an H3 index is an integer, not a sortable string, so prefix indexes on your database column do not carry over.

## Maintenance, releases and licence

The repository is not archived. The last push was on 2026-09-18, four days before this article's reference point, and the most recent tagged release is v4.5.0 from 2026-05-21, following v4.4.1 on 2025-11-12 and v4.4.0 on 2025-11-07. That cadence suggests a project that ships when there is something to ship rather than on a schedule, with patch releases appearing shortly after minor ones.

Upgrade cost is mostly the binding question again. The CHANGELOG.md and RELEASE.md files at the repository root are where the project records changes and the release process, and the README does not describe a deprecation policy for the C API. If you pin a binding version, budget time to read the C changelog when you bump it.

H3 is licensed under Apache-2.0, with a NOTICE file at the repository root. Apache-2.0 includes an explicit patent grant and requires that you preserve the NOTICE file when redistributing. That is a permissive licence in the same family as MIT, with the extra attribution obligation; if you ship H3 inside a product, check that your build system carries the NOTICE through to your distribution. This is a description of the licence text, not legal advice.

## Conclusion

Adopt H3 if you need a compact cell id per point, uniform neighbour distance, and a resolution ladder you can roll up or drill down without reindexing. Do not adopt it if your output must be exact polygon boundaries or if your team cannot take on a C build step and the binding version lag that comes with it. Before committing, check the binding you plan to use against v4.5.0, since the C library and the language wrappers release on separate schedules, and confirm the resolution you pick is the one your queries will actually filter on.

## FAQ

### What is H3 by Uber?

H3 is a geospatial indexing system that divides the planet into hexagonal cells at 16 resolutions, from 0 (coarsest) to 15 (finest). The README describes it as combining a hexagonal grid with S2's hierarchical subdivisions, and the core implementation is a C library.

### What is H3 resolution?

Resolution is the granularity of the hexagonal grid, and the README states it runs between 0 (coarsest) and 15 (finest). The resolution is encoded in the H3 index itself, so a cell id carries its own level of detail.

### How does H3 work?

It maps a latitude and longitude to a 64-bit integer identifying a hexagonal cell, and that grid can be approximately subdivided into finer and finer hexagonal grids. The approximation is stated in the README, which is why the hierarchy is described as approximate rather than exact.

### What is the H3 index and how is it used?

The H3 index is the integer returned by a call such as latLngToCell, for example 8a2a1072b59ffff for the Statue of Liberty at resolution 10. You pass that index to other functions to get the cell boundary, the center coordinate, neighbours or distance.

### Is uber/h3 open source?

Yes. The repository is public on GitHub under the Apache-2.0 licence, with a NOTICE file at the repository root, and the README points readers to the h3geo.org documentation site.

### How is uber/h3 different from geohash?

A geohash is a string prefix on a rectangular grid, while H3 indexes hexagons, which have six equidistant neighbours. The practical consequence is that H3 adjacency is uniform in every direction, but an H3 index is an integer rather than a sortable string, so geohash prefix indexing does not carry over.

## Sources

- [License: Apache-2.0](https://github.com/uber/h3/blob/master/LICENSE)
- [Project website](https://h3geo.org)
- [README](https://github.com/uber/h3/blob/master/README.md)
- [Releases](https://github.com/uber/h3/releases)
- [uber/h3 on GitHub](https://github.com/uber/h3)

---

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