An HTTP Success Is Not an Analytics Event: Test Every Ingestion Boundary

An event upload can receive a successful HTTP response while the eventual report is still missing a row. That does not automatically prove data loss: validation, asynchronous processing, identity rules, deduplication, filters, and query time windows can all change the result. The useful question is which boundary has actually been verified.

I maintain SensorFlow. This AI-assisted engineering note describes a test method, not a production benchmark or a claim that SensorFlow, PostHog, or another tool loses a particular share of events. The sample identifiers below are synthetic.

What does an event capture response prove?

An HTTP response proves only what that endpoint's documented contract says it proves. For example, HTTP 202 Accepted means the request was accepted for processing; completion is not guaranteed by that status. Even a 200 response can represent a capture boundary rather than a finished analytics query. Read the specific product's response and validation semantics before treating it as a durability receipt.

PostHog's ingestion pipeline documentation describes capture, Kafka, processing workers, and ClickHouse as separate stages. Its capture documentation says events typically become usable in queries within a few minutes. These are PostHog's documented boundaries; they are not a statement about SensorFlow's internal pipeline or a measured comparison between the two.

Build an evidence chain, not one total

For a small controlled test, assign each intended business action a safe, unique operation_id and each event a separate event_id. Do not use a real customer's identifier in a public test. Record the expected event name, actor namespace, occurrence timestamp, property types, and which business action justifies the event.

CheckpointEvidence to keepWhat it does not prove
Business outcomeAn application-side successful operation recordThat an event was constructed or sent
Client attemptSanitized event ID and request timeThat the receiver accepted it
Receiver acknowledgementStatus, documented response meaning, server trace ID if availableThat processing and storage finished
Stored rowQuery by test event ID after the documented delayThat the dashboard's metric includes it
Metric resultQuery version, time window, filters, identity policyThat every raw event should count once

If the first three checkpoints agree but the row is absent, inspect validation, queue or worker errors, storage writes, and the query's project and time range. If the row exists but the chart omits it, inspect the metric definition before retransmitting it. A count comparison alone cannot locate the boundary: one missing event and one duplicate can cancel in the total.

Make retries a separate test

Send one test event once, then resend the same event identity under a controlled retry. Also send a deliberately different payload with the same identity and verify how the chosen system reports that conflict. Do not assume that an HTTP client retry is exactly-once delivery.

The storage layer also has its own semantics. ClickHouse documents asynchronous inserts: with wait_for_async_insert=1, the server waits for the buffer to flush before acknowledging; with wait_for_async_insert=0, an acknowledgement can arrive while data is buffered and later flush errors may not be returned to the client. ClickHouse also documents insert deduplication settings. Block-level insert deduplication is not a substitute for a product-level rule about whether two event payloads represent the same business action.

Those ClickHouse options matter only when that deployment actually uses them. Inspect the running configuration and table design. Never infer a product's end-to-end delivery guarantee from the database's feature list.

Keep the comparison fair

PostHog offers a documented capture-to-query pipeline and a broad analytics product. SensorFlow's public repository describes a different self-hosted path: official Sensors Data SDK upload, Go ingestion, ClickHouse, and Apache Superset. Its open-source demo data and dashboard can be explored without a license; receiving real SDK traffic requires the project's commercial activation. Neither architecture makes an HTTP response a universal proof that a particular business metric is complete.

For a migration pilot, run the same synthetic business cases through each candidate's supported ingestion path. Compare separately: accepted requests, persisted rows, duplicates, conflicts, rejected records, and metric output under an identical window and identity definition. Record software versions and configuration. Without a representative load test, do not turn this exercise into a throughput ranking.

The acceptance statement should be narrow: “For these named test operations, the receiver acknowledged these event IDs, the expected rows appeared under this query, and this metric definition included them.” That is useful evidence. “We got HTTP 200, so no events were lost” is not.

评论

此博客中的热门博文

Choosing an Event Analytics Stack Without a Feature Checklist

Event Tracking QA: Why Signup Funnel Numbers Disagree

Event Count Is Not User Count: Define the Metric First