Skip to content

Data sources

Reports query pre-aggregated materialised views, not the raw audit log. The views are refreshed on a schedule; this makes reports fast (sub-second for most queries) at the cost of slight data lag.

When you build a custom report, you pick a data source first. The catalogue:

SourceWhat's in itRefresh cadenceTypical lag
audit_eventsEvery audit entry over the retention window5 min< 6 min
signinsSign-in attempts (success + failure) with per-attempt detail5 min< 6 min
usersCurrent user records — id, email, state, MFA enrolment, group memberships1 hour< 2 hours
applicationsCurrent application records1 hour< 2 hours
sessions_activeCurrently-active sessions, per tenant5 min< 6 min
mfa_factorsEnrolled factors across all users; aggregated counts by kind1 hour< 2 hours
webhook_deliveriesRecent webhook delivery attempts; success / failure / retry stats5 min< 6 min
flow_runsRecent Flow + Action executions5 min< 6 min
breach_incidentsOpen + resolved breach incidents1 hour< 2 hours
daily_rollupsPre-aggregated daily stats (sign-ins per day, signups per day, etc.) for time-series chartsdaily<= 24 hours

Most reports map to a single source:

  • "Sign-in failures by reason" → signins.
  • "User growth over time" → daily_rollups for the chart, users for the current count.
  • "Top failing webhooks" → webhook_deliveries.
  • "Stuck flow runs in the last hour" → flow_runs.

The report builder picks defaults; advanced users override.

Live querying the audit log for "give me the sign-in count per hour for the last 90 days" would be slow. The materialised views pre-compute the rollups; the report renders in milliseconds.

The trade-off is data freshness. A report showing "signins in the last hour" sees data with up to ~6 minutes of lag. For real-time, use Audit → Read logs with the Live toggle.

Each materialised view inherits the underlying source's retention:

  • audit_events, signins, flow_runs, webhook_deliveries — retention from the audit log (default 365 days; configurable).
  • users, applications, mfa_factors, sessions_active — current state only (not historical); no retention concept.
  • daily_rollups — typically kept for 3+ years (much smaller; cheap to retain longer).

When the underlying source ages out, the views drop the corresponding rows.

Custom reports support joining across sources. Useful patterns:

  • signins + users — "sign-ins by user group".
  • signins + applications — "sign-ins per application, with application name".
  • flow_runs + signins — "did Action X actually run on the user's sign-in attempt that failed?"

The report builder offers join keys via dropdowns; the underlying join is SQL.

  • Per-report row cap: 100,000. For larger result sets, narrow the filter or use export pagination.
  • Per-tenant query concurrency: 5 in-flight reports. Past that, queries queue.
  • Schedule limits: 50 scheduled reports per tenant. Most tenants use < 10.

If you bump into these, your reports may be too broad. The right pattern is usually multiple narrower reports rather than one giant one.

Each report shows the underlying source's freshness in the corner ("Data as of 14:25 — 4 minutes ago"). For combined sources, the freshness is the LATEST refresh among them (so if both signins and users contribute, the freshness reflects the worse of the two — i.e., users at ~ hourly).

If you need "right now" data, use Audit → Read logs (queries the live event stream).

  • Per-user fingerprint detail — privacy-sensitive; not exposed for aggregation.
  • Password hashes — never; obvious reasons.
  • Webhook payload contents — only delivery metadata, not the payload bodies.

If your reporting need touches sensitive data, it likely belongs in a custom system you operate, not in the platform's reports.