Skip to content

Core Concepts

A handful of terms come up everywhere in the H3 API. This page explains them in plain language so the rest of the docs read smoothly. You don't have to memorize it — come back when a word needs unpacking.

Cells and indexes

A cell is one hexagon in the grid. Every cell has a unique index — a single 64-bit integer that identifies it exactly. When you call latLngToCell, the integer you get back is that index.

The same index has a canonical hexadecimal string form (for example 8928308280fffff). The integer and the string are two views of the same value:

lat, lng, resinteger indexlatLngToCell()
integer indexhex stringh3ToString()
hex stringinteger indexstringToH3()

Resolutions

H3 isn't one grid — it's 16 nested grids, numbered 0 (coarsest) to 15 (finest). The resolution you pass to latLngToCell decides how big the cell is.

  • Low resolutions (0–4) cover continents, countries, and large regions.
  • Mid resolutions (7–10) cover neighborhoods, city blocks, and buildings — the sweet spot for most apps.
  • High resolutions (12–15) cover rooms and sub-meter precision.

Each step finer divides a cell into roughly 7 children, so cell counts grow fast. Picking the right resolution is the most important design decision you'll make — coarser means fewer cells and less storage; finer means more precision and more cells.

Resolution reference table

Average hexagon area and edge length at each resolution (cells vary slightly by location — about ±15% from the equator to the poles):

ResolutionAvg Hex AreaAvg Edge Length
04,357,449.416 km²1,281.256 km
1609,788.441 km²483.057 km
286,801.780 km²182.512 km
312,393.434 km²68.979 km
41,770.347 km²26.071 km
5252.903 km²9.854 km
636.129 km²3.724 km
75.161 km²1.406 km
80.737 km²531.414 m
90.105 km²200.786 m
100.015 km²75.863 m
110.002 km²28.663 m
12307.092 m²10.830 m
1343.870 m²4.092 m
146.267 m²1.546 m
150.895 m²0.584 m

Choosing a resolution

Pick the resolution where one cell is about the size of the thing you're modeling. Tracking vehicles to a city block? Resolution 9–10. Drawing service areas across a city? Resolution 6–7. Aggregating demand for a national heatmap? Resolution 4–5. You can always roll a fine cell up to a coarser parent with cellToParent later.

Base cells

At resolution 0 the world is tiled by exactly 122 base cells. Every finer cell descends from one of them, and a cell's getBaseCellNumber (0–121) tells you which one. Base cells are useful for coarse partitioning — for example, sharding a global dataset across 122 buckets.

You can list every resolution-0 cell with getRes0Cells.

Pentagons

Hexagons cannot perfectly tile a sphere — geometry forces a small number of pentagons. H3 has exactly 12 pentagon cells at every resolution, positioned over the oceans to minimize their practical impact.

Pentagons have 5 neighbors instead of 6, which makes them a genuine edge case:

  • A gridDisk touching a pentagon returns fewer cells than the usual formula predicts.
  • Some operations near a pentagon can raise a pentagon-distortion error.

Test for one with isPentagon, and list them with getPentagons.

Never hard-code disk sizes

Because of pentagons, do not assume gridDisk($cell, $k) returns exactly 3 * k * (k + 1) + 1 cells. Always iterate the returned array rather than relying on a fixed count.

String vs integer representation

Both forms identify the same cell. Use the one that fits the context:

FormLooks likeBest for
Integer617700169958293503Database columns, grouping, joins, in-memory work
Hex string8928308280fffffJSON / APIs, logs, anything that might lose 64-bit precision

Convert freely with h3ToString and stringToH3.

Why the string matters across boundaries

A 64-bit integer is too large for some systems to represent exactly — JavaScript numbers, for instance, lose precision above 2⁵³. When a cell index leaves PHP for a browser or an external API, send the string form to keep it intact.

Res Class III

Resolutions alternate between two orientations of the hexagonal grid. The odd resolutions (1, 3, 5, …) are called Class III; even resolutions are Class II. The two classes are rotated relative to each other, which is why cell boundaries look slightly different between adjacent resolutions.

You rarely need to think about this, but two cases matter:

  • A Class III cell's boundary may have extra vertices where it meets Class II neighbors.
  • Some algorithms (and the local IJ coordinate system) behave differently across the two classes.

Check a cell with isResClassIII.

Next steps

With the vocabulary in hand, dig into the API:

H3 PHP — Hexagonal geospatial indexing for PHP. Released under the MIT license.