Skip to main content

Query historical data

You can query infrastructure data at previous points in time and compare how it changed between them. Use queries with a timestamp to investigate incidents, verify changes during a period, answer audit questions, and inspect how objects and relationships differed at an earlier time.

To query a specific point, specify a branch and timestamp. Infrahub returns the values and relationships that were valid at that time through the same interfaces you use for current data. To compare changes, specify two timestamps.

Specify a branch and a time​

Each query is evaluated for a branch and a point in time. Infrahub uses those two inputs to select which versions of objects and relationships it returns. If you do not set either one, Infrahub returns the current data from the default branch.

State to readBranchTime
Production as it standsdefaultnow
Production during last night's incidentdefaulta time within the incident
The change someone is proposingtheir branchnow
The default branch just before that change mergeddefaulta time before the merge

Queries for earlier data therefore use the same read interfaces as current queries. The difference is that you specify the time to evaluate the data.

How historical queries work​

When you add a timestamp to a query, Infrahub evaluates each requested object using the attribute values and relationships that were valid at that time. You use the same query structure as you do for current data; the timestamp changes which versions Infrahub returns.

Infrahub can return those versions because changes create new attribute values and relationship versions instead of replacing the previous ones. History is tracked per attribute and relationship, so a comparison can identify the specific fields or connections that changed, including the previous values.

The schema is evaluated for the same point in time. If the schema changed after the timestamp you request, Infrahub loads the schema as it was then, so the query sees the attributes and relationships that existed at that point rather than the current ones.

A timestamp applies to reads only. If a query document contains a mutation, Infrahub ignores the timestamp and applies the mutation at the current time.

Once Infrahub records a version, a change made after it does not alter that version. See Immutable history for more detail on how Infrahub preserves those versions and how immutable history relates to branches and the Activity log.

Query data at a specific time​

Use a timestamp when you need the values and relationships that existed at a known point — for example, during an incident or before a change.

You can specify a time when viewing or querying Infrahub data through the web interface, GraphQL, REST API, or Python SDK. Use the web interface for interactive investigation and the APIs or SDK when you need a repeatable or programmatic query.

Select the time selector — the calendar and clock icon beside the branch selector — and choose a date and time in UTC. Until you set a time, the selector displays only the icon; once you set one, the bar beside it displays Current view time with your selection.

The selected time remains applied as you navigate, so objects and relationships are displayed using the values valid at that timestamp. Select the × beside the displayed time to return to the current time.

The time selector, with a past time applied

Compare changes between two timestamps​

Use a diff when you need to identify which objects or attributes changed between two timestamps. DiffTree compares the data at from_time with the data at to_time. The timestamps do not need to align with a branch point or Proposed Change, so you can compare any useful period, such as the four hours around an incident.

# Endpoint : http://localhost:8000/graphql/main
query ChangesBetween {
DiffTree(
branch: "main"
from_time: "2026-03-09T00:00:00Z"
to_time: "2026-03-10T00:00:00Z"
) {
num_added
num_updated
num_removed
nodes {
kind
label
status
attributes {
name
action
}
}
}
}

Behavior to expect:

  • Omit from_time and the comparison starts at the branch's branched_from timestamp.
  • Omit to_time and the comparison runs to the present.
  • Use filters to narrow the result by kind, namespace, or status.
  • Use limit and offset to page through results.
  • Use DiffTreeSummary when you only need counts rather than the full set of changed nodes.
  • The base of the comparison is the default branch. Name a feature branch to compare it with the default branch across the requested period, or name the default branch to compare it with itself over time.
  • If no diff covering the requested period is available, the query returns null rather than an empty result. Treat null as "not calculated," not "nothing changed."

DiffTree retrieves a diff that has already been calculated. To calculate one for a period, send the DiffUpdate mutation first with the branch and, when you need a period other than the default, from_time and to_time. This is why a request for an arbitrary period can return null on the first attempt.

In the web interface, a branch's Branch view shows its diff and lets you refresh it, whether or not a Proposed Change exists for that branch. When you are comparing a branch with its base and also need review, validation, and checks, use a Proposed Change.

Choose an absolute timestamp or relative offset​

Use a relative offset when you are investigating from the current time. Use an absolute timestamp when the query needs to resolve to the same time each time it runs — for example, for an audit answer, post-incident report, or reproducible analysis.

FormExampleResolves to
ISO 8601 with a zone or offset2026-03-09T14:00:00Z or 2026-03-09T15:00:00+01:00The specified instant
ISO 8601 without a zone2026-03-09T14:00:00The same wall-clock time, interpreted as UTC
Date only2026-03-0912:00 UTC on that day
Offset from now30s, 45m, 6h, 2h30mThat interval before the current time

A date without a time resolves to midday rather than midnight, so include an explicit time when a day boundary matters. Relative offsets support seconds, minutes, and hours, including combined values such as 2h30m. They do not support day or week units; use an absolute timestamp for those intervals.

Understand branch history limits​

You can query a branch back to the point where its history begins. If you request a time earlier than that, Infrahub rejects the query rather than returning partial data.

When you create a branch, Infrahub records where it diverged rather than copying the entire dataset. You can query the history available through the default branch, plus the changes recorded on the branch after it diverged.

On the default branch and the global branch, the earliest available time is that branch's creation. On any other branch, the boundary is the creation time of the default branch.

Requested time '2026-01-05T00:00:00Z' is before branch 'main' was created at '2026-02-01T09:14:22.481000Z'.

If you need data from an earlier timestamp than the branch allows, query the default branch instead.

Rebasing a branch moves the timestamps of changes made on it up to the rebase time, so a change recorded on the branch before a rebase is no longer readable at its original timestamp.

  • Immutable history — how Infrahub preserves previous values and relationships
  • Branches — how branches diverge, share history, and merge
  • Activity log — which operations occurred, when, and by whom
  • Proposed Changes — compare a branch with its base with review, validation, and checks