Cache & Freshness
Last verified: 2026-05-03 (Task #334 — docs accuracy pass).
The Weather Intelligence API is fronted by a shared geohash cache. Multiple users (and external developers) calling for the same neighborhood and the same forecast hour collapse to a single upstream provider call, which is what makes the per-request billing units sustainable.
Two pieces of metadata expose what happened on every call:
meta.cache_statusand theX-Cache-Statusresponse header.meta.snapshot_idand theX-Weather-Snapshot-Idresponse header.
Cache statuses
| Status | What it means |
|---|---|
HIT | The cached snapshot was within its freshness band; no provider call was made. |
MISS | No suitable snapshot was cached; we fetched fresh data from the provider. |
STALE | The cached snapshot was past its freshness band but inside the stale-while-revalidate window. We returned it immediately and queued a background refresh. |
MIXED | (Timeline only) Different items resolved to different statuses. Each item's individual weather.cache_status still reports HIT, MISS, or STALE. |
X-Cache-Status carries the same value as meta.cache_status.
Snapshot IDs
Every weather row in our DB has a stable snapshot_id (UUID). When a
response is backed by a single snapshot, it appears in both
meta.snapshot_id and the X-Weather-Snapshot-Id header. For
endpoints that aggregate over multiple snapshots (timeline, route),
the meta carries the primary snapshot — usually the centroid
item's snapshot — so you have at least one stable handle to log
against.
Freshness bands
Different forecast horizons are allowed to live in cache for
different amounts of time. The bands below are pinned to PRD section
13.1 and are applied in the cache layer when deciding HIT vs
STALE vs MISS.
| Forecast horizon | Freshness band | Stale-while-revalidate window |
|---|---|---|
| Current weather (now) | up to 1 hour | up to 6 hours |
| Hourly forecast (1–24h) | up to 1 hour | up to 6 hours |
| Hourly forecast (24–48h) | up to 3 hours | up to 12 hours |
| Daily forecast (2–7 days) | up to 6 hours | up to 24 hours |
| Daily forecast (8 days+) | up to 12 hours | up to 24 hours |
A snapshot inside its freshness band returns HIT. A snapshot past
its freshness band but inside the stale window returns STALE and
triggers a background refresh. A snapshot past the stale window is
discarded; the request waits for a fresh provider fetch (MISS).
Cache key shape
Every cell in the cache is keyed by:
provider:{provider}:geohash:{geohash}:date:{local_date}:hour:{hour_bucket}:layer:{forecast_type}
provider— e.g.openweather.geohash— geohash of the point at the precision implied by the point'splace_type(city = 5, neighborhood = 6, address = 7, …).local_date/hour_bucket— the time bucket in the location's local timezone.forecast_type—current,hourly, ordaily.
You don't need to construct cache keys yourself — they're computed by the service. The key shape is documented because it's what governs which calls collapse together.
Tips
- Don't request 1,000 nearby points in a route call to "warm" the cache. The polyline sampler already dedups same-cell same-hour segments.
- Repeat-calls within minutes of each other for the same cell are
almost certainly
HIT. - A
STALEresponse is still a perfectly valid current snapshot — the provider's data hasn't necessarily moved. Ship the response; ignore theSTALEflag unless you specifically need the very latest data.