How Uptime Becomes History
In Uptime Kuma, a history chart is not a second stream of reality; it is a reduction of heartbeat events into a form that answers a different question. Understanding that reduction lets the reader know when to inspect an individual event, how a displayed uptime percentage is constructed, and when a stable summary may be old, incomplete, or too coarse for the decision at hand.
An individual check is good at answering, “What happened at this moment?” A trend is better at answering, “How often did the configured observation pass over a period?” Those questions need different data shapes. Uptime Kuma keeps detailed heartbeat records for immediate diagnosis, then maintains aggregate buckets so recent behavior and longer-term patterns can be calculated without repeatedly scanning every event.
A heartbeat is richer than a percentage
A heartbeat is the event at the center of this historical layer. It identifies the monitor, records its status and time, and can carry a message, response duration, retry count, whether the event was important, and a bounded response payload when response saving is enabled. For a failed HTTP assertion, the message may explain the rejected status or content. For a DNS check, it may contain the returned records. For a push monitor, the timestamp and duration help show whether the report arrived within its window. The event preserves the circumstances that a single percentage cannot show.
The heartbeat also records the difference between an ordinary observation and a state transition. Repeated successful checks are still useful when an operator is investigating timing or a later failure, but they do not all represent a new incident. An important flag identifies first observations and meaningful changes such as an outage or recovery. That distinction supports both the dashboard's event view and the cleanup policy that protects selected history for longer.
A raw record is therefore the right place to investigate questions such as:
- Did the target fail once or repeatedly?
- Did the failure occur while retries were still pending?
- What message and response time accompanied the transition?
- Was the event marked important, and did the monitor later recover?
- Was the result a planned maintenance state rather than a failed probe?
A chart cannot answer all of these. It may show that a period contains some down-side observations, but it does not preserve every message, retry step, or causal detail in the same form. The historical design begins by retaining the detailed event, then deliberately creates a smaller representation.
The uptime calculator maintains three resolutions. Recent minute-level data covers the last 24 hours. Hourly data covers 30 days. Daily data covers 365 days. These are not three independent measurements. When a heartbeat arrives, the calculator finds the minute, hour, and UTC day containing its timestamp and updates all applicable buckets. Each bucket keeps counts and successful-check timing information. The database stores the buckets, while the calculator also holds bounded in-memory queues for quick access and reloads recent data from the database when a monitor is first used.
The boundaries are useful because they match different kinds of investigation. Minute buckets preserve short-term changes without retaining an indefinitely large event stream in memory. Hourly buckets make a month legible. Daily buckets make a year practical.