Data / Freshness

Data freshness

How old the data can be, per category, measured against the running system. Nothing here is near-real-time, and we do not describe it as if it were.

No real-time claims

There is no millisecond path, no streaming socket and no sub-second guarantee anywhere in this system. The fastest category updates hourly. Publishing that plainly is more useful to anyone building on the layer than a "real-time" label that falls apart on contact with a timestamp.

The three classes

Every category falls into one of three classes, and the class determines what you can legitimately do with it.

  • Near-real-time — sub-minute freshness. Moonlytics has no category in this class. Stated explicitly so it is not inferred from silence.
  • Periodic — updated on a fixed schedule, hourly or daily. Every live category is here.
  • Historical — written once, never changed. The retained series.

Measured cadence per category

CategoryClassCadenceCollection windowAge of newest value
Market observationsPeriodichourlytop of the hour, UTC0–60 min
Social observationsPeriodichourlytop of the hour, UTC0–60 min
SentimentPeriodichourlytop of the hour, UTC0–60 min
ScorePeriodichourlytop of the hour, UTC0–60 min
News flowPeriodichourlyevery hour, 00–23 UTC0–60 min
Narrative snapshotsPeriodichourlyshared timestamp per snapshot0–60 min
Asset metadataPeriodicdaily~11:00 UTC0–24 h
Repository activityPeriodicdaily~11:00 UTC0–24 h
Channel reach (X)Periodicdaily~13:00 UTC0–24 h
ContributorsPeriodicdaily~15:00 UTC0–24 h
Community (Reddit)Periodicdaily~16:00 UTC0–24 h
Topic mentionsPeriodicdailydaily bucket0–24 h
Historical seriesHistoricalappend-onlysince November 2025immutable

Cadences measured against the production store on 2026-08-31 by counting rows per hour and per day rather than by reading a configuration file.

Why the hourly categories are hourly

The market ingest job runs several times an hour, but a persisted observation is written once per asset per hour. Two different things are therefore true at the same time, and it matters which one you are relying on:

  • the system polls the upstream provider every few minutes;
  • the system records one immutable row per asset per hour.

Everything downstream — every score, every chart, every historical join — reads the recorded rows. So the freshness figure that matters is the hourly one, and that is the figure published here. Quoting the polling interval instead would be technically true and practically misleading.

Why the daily categories are daily

Follower counts, repository statistics and contributor totals do not change meaningfully within a day. Sampling them hourly would multiply storage and upstream load without adding information. Each daily series is collected at its own fixed hour, which keeps day-over-day differences comparable and spreads collection load.

When data is late

Upstream providers fail, and when they do the layer does not invent a row. A missed hour stays missing: no forward-fill, no interpolation, no carrying the previous value forward under a new timestamp. A gap in the series is a truthful statement that nothing was observed, and it is far less damaging than a fabricated one.

What that means for a consumer: check observedAt, do not assume the newest row is the current hour, and treat absence as absence. See data quality for how gaps and stale values are detected.

A freshness endpoint

Planned

A machine-readable freshness endpoint — last write timestamp and age per category — is planned as part of the public Data API. Until that exists, this page is the reference, and it is maintained by measurement rather than by memory.