Cell & Shape

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 Google 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.

Frequently asked questions

Is H3 better than S2?
Neither is strictly better — they optimise for different things. H3’s hexagons give every cell six equidistant neighbours, which makes it excellent for movement, flow, and nearest-neighbour analytics, and its cells stay close to uniform in area. S2’s quad cells nest perfectly (each splits into exactly four children) and its cells map to sortable 64-bit integers along a Hilbert curve, which makes range queries, coverings, and containment tests very fast. Choose H3 for hex-based aggregation and joins; choose S2 for spatial indexing, region coverings, and database range scans.
Can I convert between H3, S2, and geohash?
Not losslessly — the three systems tile the Earth with different shapes, so no H3 hexagon equals any S2 quad or geohash rectangle. What you can do is convert a cell to a polygon and re-cover it in another system, or map a point to a cell in each system independently. That is exactly what this page does: click any map and it shows the S2 token, H3 index, and geohash that contain the same point. For exact geometry, paste a cell into the universal inspector to get its polygon in WKT or GeoJSON.
Why does geohash have edge problems?
A geohash is a Z-order (Morton) interleave of latitude and longitude bits, so two points that are physically adjacent can fall on opposite sides of a bit boundary and receive geohashes that share no common prefix at all — the classic example straddles the prime meridian or the equator. Because proximity search in geohash relies on shared prefixes, those seams make neighbouring cells look unrelated, so any robust geohash query has to also check the eight neighbouring cells rather than trusting the prefix alone.
Why does H3 have pentagons?
H3 is built on an icosahedron, and it is mathematically impossible to tile a sphere with hexagons alone — by Euler’s formula you always need exactly twelve pentagons. H3 places one pentagon at each of the twelve icosahedron vertices, positioned over ocean so most workloads never touch one. A pentagon has five neighbours instead of six, so code that assumes six neighbours should guard against it. The “H3 pentagon” demo on this page jumps to one.
What is the difference between S2 and geohash?
Both produce hierarchical string/integer cell IDs, but S2 projects the sphere onto the six faces of a cube and walks each face with a Hilbert curve, giving cells of near-equal area and good spatial locality in the sorted index. Geohash simply interleaves lat/lng bits into a base-32 string; it is trivially easy to compute and human-readable, but its cells distort badly toward the poles and its ID space has discontinuities at cell boundaries. S2 is the better spatial index; geohash wins on simplicity and legacy ubiquity.
Which is best for a database spatial index?
For indexing points or regions in a relational or key-value store, S2 is usually the strongest choice: cells are 64-bit integers ordered along a space-filling curve, so a region query becomes a small set of integer range scans, and S2’s region coverer produces tight multi-level coverings. Geohash works too and is simpler (string prefix = ancestor), which is why it is common in legacy systems and Elasticsearch. H3 is less about indexing and more about analytics on a fixed hexagon grid — great for joins and aggregation, less ideal as a raw range index.