Metricward

Features

What happens to an event, as it happens

The live debugger shows every decision the ingestion pipeline made about an event, usually within two seconds of your browser sending it. It is not the same pipeline that fills in your dashboard charts, and this page explains why that is a deliberate design rather than an oversight.

Two paths, not one

An event takes one of two routes out of the ingestion server, and they exist for different reasons.

The debug path, what feeds this screen

While the ingestion server is deciding whether to accept an event, it also pushes a sanitised copy of that decision directly onto a short Redis list for the project, fire-and-forget, so it can never slow down or block the request that is actually storing your data. The debugger polls that list every two seconds. Total time from your browser to a row appearing on this screen is, in practice, the network round trip plus up to two seconds of poll interval. There is no queue, no batching and no database write on this path, which is exactly why it can be fast: it is not carrying the load the rest of the product depends on.

The storage path, what feeds your charts

The event that was actually accepted is separately appended to a Redis stream, read in batches by a writer process, and inserted into ClickHouse. The writer batches up to 10,000 events or two seconds of waiting, whichever comes first, because ClickHouse is efficient with few large inserts and is degraded by many small ones. Materialised views used by most reports then update from that insert. Under normal load that is a few seconds end to end; it is not instant, and nothing in the product claims it is.

The consequence worth stating plainly: for a few seconds after you send an event, the debugger can show it and a report can still not reflect it. That is not a bug in either screen, it is two paths with two different jobs finishing at two different times.

What the debugger actually shows

Accepted events, in full.

Resolved identity (visitor, session, whether this started a new session), resolved context (consent state, channel, country, device, browser, OS, SDK version), every property sent, and whether the event matched your tracking plan.

Rejected and suppressed events, with the reason.

Consent denied, a Global Privacy Control or Do Not Track signal honoured, an excluded path or IP range, an unparseable URL. Each reason carries a plain-language explanation next to it, not just a code.

Post-sanitisation only.

Everything shown is the same data that was, or would have been, stored. This screen never becomes a way to see what the pipeline refused to keep, including on a rejected event: the IP address behind it was used in memory to derive a country and a daily visitor hash, and never written anywhere, including here.

A 30-minute window, not a log.

The debug list holds the last 50 entries per project and expires after 30 minutes. It is a developer convenience for checking that an integration is sending what you think it is sending, not a permanent record. The permanent record is ClickHouse, reached through the storage path above.

Stated plainly

This screen is polled every two seconds by the browser, not pushed. A push connection is planned for when someone leaves the debugger open across a deploy and notices the gap; a poll was the lazier and more robust starting point and it is what ships today.

Nothing here is sampled and nothing is thresholded away. If an event was rejected, it appears exactly as often as one that was accepted.

See the fields and rejection reasons in full on the tracking doc, or read how identity and consent are resolved before an event ever reaches this screen on the privacy page.

Real time