Use cases · 9 min read · October 2026

When to use H3 in analytics.

H3 is useful far beyond ride-sharing. These are the patterns that come up repeatedly across operations, logistics, and spatial analytics once hex indexing is in the stack.

Pattern 1: event density, honestly rendered

You have a stream of geolocated events — pickups, drop-offs, alerts, sightings, complaints — and you want to visualise where they concentrate. The naive approach is a heatmap based on kernel-density estimation, which looks beautiful and quietly lies: the kernel bandwidth is a knob that lets you make density look however you want.

Hexagonal binning is the honest alternative. Index each event to a resolution-8 or 9 cell, count events per cell, colour by count. The map now tells you exactly what the data says, with no smoothing choice buried inside. If you need less visual noise, aggregate to resolution 7 or 6 — the choice of resolution is now a documented decision rather than a buried parameter.

This is the single most common first use of H3, and the one that justifies adopting it on its own.

Pattern 2: service and zone definition

Most operational systems define zones at some point: delivery areas, surge regions, no-go polygons, incentive catchments, airport pickup zones. The traditional way is to draw polygons in a GIS tool and store them as geometry; the H3 way is to store zones as sets of cells.

Why this is better in practice:

The tradeoff: zone boundaries have the stair-step look of a hex grid rather than smooth curves. For visualising to end-users you may want to draw a smoothed polygon on top. But internally, cell sets are easier to reason about.

Pattern 3: demand forecasting

Any forecasting model that predicts "how many events will occur in region X during time window Y" needs spatial buckets. Hex cells are better buckets than lat/lng rectangles because they produce more consistent sample sizes and remove the diagonal-neighbour artifact from any model that uses spatial smoothing.

A typical pipeline looks like this:

  1. Raw events get indexed to resolution 10 or 11 as they stream in.
  2. Hourly or quarter-hourly aggregates per (cell, hour-of-week) are stored for the last 90–180 days.
  3. For each (cell, time slot), a short feature vector is produced: historical mean, weekly seasonality, local neighbour density via a k-ring, weather, event calendar.
  4. A model (gradient boosting or a lightweight neural net) predicts next-hour demand per cell.
  5. Predictions roll up to resolution 8 for the operator-facing map and down to resolution 11 for pricing engines.

Pattern 4: spatial joins at warehouse scale

"Which stores are within 500m of these customers?" is a spatial-join problem that traditionally needs an r-tree, a GIS extension, and some patience. If both sides are H3-indexed, it becomes a hash join on cell ID, scaled by the k-ring expansion you need to cover the distance.

Pseudocode:

-- customers indexed to resolution 10 (~65 m edge)
-- stores indexed to resolution 10

WITH store_coverage AS (
  SELECT store_id,
         h3_grid_disk(store_cell, 8) AS near_cells  -- ~500 m
  FROM stores
)
SELECT c.customer_id, s.store_id
FROM customers c
JOIN store_coverage s
  ON ARRAY_CONTAINS(s.near_cells, c.customer_cell);

This runs in seconds on hundreds of millions of rows in Snowflake or BigQuery. The traditional r-tree equivalent would take an hour and a GIS extension you may not have.

Pattern 5: pricing and surge

Pricing and incentive logic tends to use the same cells as demand forecasting, but with different semantics: rather than "predict demand", you're "compute price multiplier".

A simple surge formula might be: for each resolution-9 cell, compute (open demand) / (available supply within some k-ring). Apply a monotone transform. Clip to a reasonable range. The result is a surge multiplier per cell, updated every minute, driven entirely by H3-indexed aggregates.

Because the cells are hexagonal, there are no diagonal-neighbour artifacts in the smoothing — surge values transition smoothly across cell boundaries rather than jumping diagonally. For a user-facing map this matters: nobody wants to see a chessboard pattern of prices.

Pattern 6: cross-city comparison

If your operation spans many cities, you need a way to compare "comparable" areas across them. Administrative units (districts, zip codes) are useless for this — they're wildly different in area and population density across geographies.

H3 cells, by contrast, are the same area everywhere. "Pickups per resolution-8 cell per hour" is a metric you can roll up across cities and genuinely compare, because the denominator is uniform. If you want to control for population, divide by population at the same resolution (US Census has released H3-indexed population datasets; LandScan is also an option).

When H3 is not the right tool

Getting started

If your warehouse already has H3 UDFs — Snowflake, BigQuery, Databricks, DuckDB with the extension — adoption cost is low. Pick a resolution (9 is a reasonable default for city-scale ops), add a cell column to your events table, and start aggregating by it.

For ad-hoc work, h3-py in a notebook or h3-js in the browser (as H3Split does) covers nearly every scenario.

← Back to blog