H3 vs S2 vs Geohash — Interactive Comparison
Three spatial-index systems, three maps, one shared control. Drag the cell-size slider and watch S2, H3, and geohash each snap to the level whose cells are closest to your target size. Pan or zoom any map and the other two follow. Click anywhere to see the S2 token, H3 index, and geohash for the exact same point — then jump to the demos that expose where each grid breaks. It all runs in your browser; nothing you do here is uploaded.
Side-by-side comparison
| Property | S2 | H3 | Geohash |
|---|---|---|---|
| Cell shape | Quadrilaterals (curved squares) on a projected cube | Hexagons, plus 12 pentagons per resolution | Latitude/longitude rectangles |
| Subdivision factor | 4 children per cell (÷2 per axis) | ~7 children per cell (aperture-7) | 32 children per character (÷4 lng × ÷8 lat, alternating) |
| Levels | 0–30 (level) | 0–15 (resolution) | 1–12 (precision, characters) |
| Index form | 64-bit integer / base-32 token on a Hilbert curve | 64-bit index, 15-char hex string | Base-32 string (prefix = ancestor) |
| Perfect nesting | Yes — child cells tile the parent exactly | No — hexagons only approximately nest (children overlap edges) | Yes — every extra character subdivides exactly |
| Neighbour uniformity | 4 edge neighbours, equal-ish; distortion at cube-face seams | 6 equidistant neighbours (5 at a pentagon) — the most uniform | 8 neighbours at unequal distances; worse toward the poles |
| Area uniformity | Within ~2× across a level (cube projection minimises it) | Very uniform across the globe | Degrades badly with latitude (constant degrees, shrinking metres) |
| Origin | Uber | Gustavo Niemeyer (2008), public domain | |
| Best for | Spatial indexes, region coverings, containment, DB range scans | Analytics, joins, movement/flow, hex binning | Simple prefix proximity, human-readable IDs, legacy systems |
How each system divides the Earth
S2 projects the sphere onto the six faces of a cube, then recursively splits each face into four quadrilateral cells, quad-tree style. To turn that 2-D hierarchy into a single sortable ID, S2 threads a Hilbert space-filling curve through the cells so that IDs close in value are close in space — which is what makes range queries and coverings efficient. The cost is six face seams where the projection meets: cells rotate and shear as they cross a seam, and the four cube corners are the S2 analogue of a distortion point.
H3 starts from an icosahedron (20 triangular faces) and tiles it with hexagons, refining each cell into roughly seven children per step. Hexagons give the prized property that all neighbours are equidistant, but a sphere cannot be closed with hexagons alone — Euler’s formula forces exactly 12 pentagons, one at each icosahedron vertex, which H3 hides over the oceans. Because the aperture is 7, H3 children don’t nest perfectly inside their parents; the hierarchy is approximate, which is fine for aggregation but means you can’t treat a coarse cell as an exact union of finer ones.
Geohash is the simplest of the three: it takes the binary expansions of longitude and latitude and interleaves their bits (a Z-order / Morton curve), then encodes five bits per base-32 character. Each character therefore zooms into a 32-way finer rectangle, and a shorter string is always a prefix of the cells inside it. That prefix property is geohash’s superpower and its weakness: it is trivial to compute and human-readable, but the Z-order curve jumps at every bit boundary, so physical neighbours can have wildly different strings, and because the cells are fixed in degrees they stretch and squash with latitude.
Which should you use
Reach for H3 when the job is analytics. Hexagons’ uniform neighbours make it the natural grid for binning point data into a surface, joining datasets onto a common cell, and modelling movement or diffusion (ride-hail, delivery, mobility, epidemiology). The usual caveats: handle the 12 pentagons, and don’t rely on exact parent/child containment because the aperture-7 hierarchy only approximately nests.
Reach for S2 when the job is indexing and geometry. If you need to store cells in a database and answer “what’s in this region?”, S2’s Hilbert-ordered 64-bit IDs turn a region query into a handful of integer range scans, and its region coverer builds tight multi-resolution coverings for containment and intersection. The caveat is the six face seams and the fact that raw S2 tooling is heavier than a one-line geohash.
Reach for geohash when you want simple string ops or you’re on legacy rails. The prefix-as-ancestor rule makes “find things near here” a `LIKE 'u10hb%'` query, it’s human-readable, and it’s supported almost everywhere (Elasticsearch, Redis, countless ETL pipelines). Just remember the two standard caveats: always search the eight neighbouring cells because of the boundary discontinuities, and don’t trust cell size near the poles.
The four boundary problems
Every global grid has to pay somewhere for flattening a sphere. The demo buttons above jump straight to a real example of each — here’s what you’re looking at.
- Geohash prefix discontinuity
- Two points a few dozen metres apart, one just west and one just east of the prime meridian, get geohashes that share zero leading characters. The Z-order curve crosses a top-level bit boundary there, so a string-prefix proximity check treats the two neighbours as unrelated. This is why correct geohash search always inspects neighbouring cells.
- S2 cube-face seam
- Near 45° east on the equator, the boundary between two of S2’s six cube faces runs through the view. Watch the cells rotate and shear as they cross the seam — the price S2 pays for projecting a sphere onto a cube and keeping cell areas within about a factor of two.
- H3 pentagon
- Off the Norwegian coast sits one of the twelve pentagons every H3 resolution must contain. It’s highlighted so you can see the odd cell out: five sides, five neighbours, and a small local distortion in the otherwise uniform hexagon grid.
- The poles
- At 80° north the geohash rectangles squash into thin east–west strips — same degree dimensions, far fewer metres of longitude — while the S2 and H3 cells stay close to uniform. It’s the clearest picture of why lat/lng grids struggle at high latitude.