Current as of August 21, 2026.This article reflects the public Poolstatis contracts available on its publication date.

Product analytics should normally assign behavior to event time, the moment an action actually happened. It should retain ingestion time, the moment the analytics system received the event, to measure delivery delay, troubleshoot pipelines, and define reproducible data cutoffs.

Those timestamps answer different questions. Event time tells you what users did during a period. Ingestion time tells you what the analytics system knew during that period. Treating them as interchangeable can shift activity into the wrong day, conceal late delivery, duplicate retries, and make historical reports change without explanation.

A trustworthy implementation stores both, validates implausible client timestamps, preserves retry identity, and defines when a reporting window is considered complete.

What is the difference between event time and ingestion time?

Event time is when the underlying action occurred. Ingestion time is when the analytics service accepted or recorded the event. Processing time, a third concept used in streaming systems, is when a particular computation handles the record.

Time conceptWhat it representsTypical ownerBest use
Event timeWhen the user or system action occurredClient or producing serviceTrends, funnels, cohorts, attribution
Ingestion timeWhen the analytics system received the eventAnalytics serverDelivery lag, throughput, operational monitoring
Processing timeWhen a pipeline stage processes the eventStream processorPipeline execution and performance diagnostics

Consider a user who completes onboarding at 23:58, loses connectivity, and reconnects at 00:07. The completion belongs to the previous day when measuring user behavior, but the analytics system did not receive it until the next day.

If a report groups that event by ingestion time, the action moves into the wrong behavioral period. If an operations dashboard groups it by event time, it hides the fact that delivery was nine minutes late.

Apache Flink’s official documentation defines event time as the time at which an event occurred on its producing device and notes that arrival order may differ from event order. That separation lets event-time computations remain consistent across replays, provided the necessary data eventually arrives. Apache Flink: Time

Which timestamp should product metrics use?

Use event time for questions about user behavior:

  • How many users activated on Monday?
  • Which signup cohort retained after seven days?
  • How long did it take users to complete onboarding?
  • Did a conversion occur within an attribution window?
  • What sequence of actions preceded an outcome?

Use ingestion time for questions about the measurement system:

  • How many events did the collector accept per minute?
  • Is data arriving later than normal?
  • Did a client stop sending events?
  • What data was available when a report was generated?
  • Which records arrived after a reporting cutoff?

Google Cloud Dataflow defines data freshness as the difference between processing time and an event’s timestamp. A growing difference indicates increasing delay between the occurrence and processing of events. Google Cloud Dataflow monitoring metrics

A single chart should not silently switch between these meanings. Label operational metrics as receipt-time or ingestion-time metrics. Label behavioral reports as event-time metrics. When both matter, show them separately.

Why do analytics events arrive late or out of order?

Late arrival does not automatically mean the data is corrupt. Common causes include:

  • A mobile or desktop client worked offline.
  • The operating system suspended a background process.
  • A request timed out after the server accepted it.
  • The client retried a buffered batch.
  • A queue or worker accumulated a backlog.
  • Events from several devices took different network paths.
  • A historical import intentionally submitted older activity.
  • A device clock was wrong.

Arrival order is therefore not a reliable behavioral sequence. Event A can reach the collector after event B even when A happened first.

Sequence analysis should sort eligible events by their validated event timestamps and use a deterministic tie-breaker where timestamps are equal. Operational diagnostics should preserve receipt order as separate evidence.

This distinction also prevents a common analytical mistake: interpreting a retry storm or queue recovery as a sudden surge in product usage. Ingestion volume may spike while the underlying user actions remain distributed across earlier event-time periods.

How should product analytics handle clock skew?

Client timestamps cannot be trusted without limits. A device can be minutes, days, or years ahead or behind the server. At the same time, replacing every late timestamp with receipt time destroys valid offline history.

A defensible policy has four parts:

  1. Require an unambiguous timestamp format with an explicit UTC offset.
  2. Define an acceptable future-skew tolerance.
  3. Define the oldest accepted event according to retention policy.
  4. Record when the server corrects or rejects a timestamp.

RFC 3339 provides an interoperable Internet timestamp profile and requires the relationship to UTC to be represented through a UTC designator or numeric offset. IETF RFC 3339

The tolerance itself is a product decision, not an industry constant. It should account for expected client behavior and the cost of assigning activity to an incorrect period.

Poolstatis currently applies different policies to live ingestion and deliberate historical backfills. For live ingestion, a missing timestamp receives server receipt time. A timestamp more than five minutes in the future, or older than the project retention boundary, is replaced with receipt time and marked with $clock_skew. The ingest response includes a warning.

That behavior keeps a live batch usable while making the correction observable. It should not be presented as a universal five-minute rule for every analytics system.

Historical backfills are stricter: their timestamps are required, and out-of-range records fail validation instead of being silently reassigned to the present.

What happens to reports when late events arrive?

A late event can revise an event-time bucket that someone has already viewed.

Suppose a hypothetical dashboard shows 98 onboarding completions for Monday at 09:00 Tuesday. Two offline clients then deliver three valid Monday completions at 09:15. An event-time query can now return 101 for Monday.

This is not necessarily a calculation error. The underlying evidence changed.

Teams should make that behavior explicit by choosing one of these reporting contracts:

Reporting contractBehaviorAppropriate use
Continuously updatedPast periods change as valid events arriveProduct exploration and near-real-time dashboards
Delayed finalizationA period stays provisional for a stated delayDaily operational reviews
Frozen cutoffA report includes only data received before a recorded cutoffFinance, release comparisons, reproducible decisions
Revision-awareCorrections and late arrivals produce a new report versionAudited or regulated workflows

The important point is not to eliminate change. It is to identify which snapshot was used for a decision.

A report intended to be reproduced later can record both its event-time range and its maximum ingestion-time cutoff. Re-running it with the same constraints prevents newer late arrivals from silently changing the answer.

When is an event-time window final?

There is no universal moment when an event-time window becomes absolutely complete. A system needs an explicit completeness policy.

Streaming systems often use a watermark, an estimate of how far event time has progressed. Apache Beam explains that events arriving for a window after its watermark has passed are considered late. Triggers can produce early, on-time, and late results rather than pretending that every window closes once and never changes. Apache Beam programming model

Waiting longer can improve completeness, but it increases reporting latency. Flink describes this as a tradeoff between waiting for out-of-order events and producing results promptly. Apache Flink: Time

A product analytics team can implement a simpler policy without operating a full streaming watermark engine. For example:

  • Mark today’s data as provisional.
  • Finalize daily operational reports after a documented delay.
  • Reopen a period when late volume exceeds a threshold.
  • Freeze decision-critical reports using a recorded ingestion cutoff.
  • Show the latest event time and ingestion time included in an export.

Poolstatis should not be described as providing general-purpose Beam-style watermarks. Its current model stores event and receipt time separately, which supplies the evidence needed for explicit reporting policies.

How should retries avoid duplicate analytics events?

A retry must preserve the identity of the original write attempt. Generating a new batch identifier on every retry turns one logical delivery into several unrelated deliveries.

A safe client pattern is:

  1. Construct the complete batch.
  2. Assign a stable batch_id.
  3. Serialize and retain the payload until delivery is confirmed.
  4. Send the batch.
  5. If the result is uncertain, retry the same payload with the same identifier.
  6. Create a new identifier only for a new logical batch.

The server should claim the identifier and write the associated events atomically. Otherwise, a failure between “identifier accepted” and “events stored” can lose data, while a failure after storage but before confirmation can create duplicates.

Poolstatis live ingestion applies a 24-hour idempotency scope to caller-provided batch identifiers. If the caller omits batch_id, the server can still process the request, but the client no longer has a stable identifier for a safe retry of an uncertain response.

Idempotency protects delivery. It does not correct a wrong event timestamp. These are separate controls.

When should teams use backfill instead of live ingest?

Use live ingest for ongoing telemetry that is expected near the time it occurs. Use a dedicated backfill workflow for deliberate historical imports, migrations, or repairs involving older events.

A backfill needs stronger safeguards because it can rewrite historical metrics across many periods:

  • Every event should have an explicit timestamp.
  • The entire batch should be validated before storage.
  • The payload should have a canonical hash.
  • The request should include a stable batch identifier.
  • The operator should provide a reason.
  • The system should record an audit entry.
  • Reusing an identifier with different content should fail.

In the current Poolstatis implementation, backfill preview validates the complete payload and calculates a canonical SHA-256 hash. Commit requires the expected hash, a batch_id, and a reason. The batch is stored only if all events are valid.

An exact replay can be recognized as a duplicate. Reusing the same identifier for different content returns a conflict. This idempotency binding is permanent for the backfill workflow, unlike the shorter live-ingest retry window.

Sending historical imports through ordinary live ingestion would also trigger the live clock-skew policy and could move old events to receipt time. The dedicated workflow prevents that semantic error.

How should an incorrect event timestamp be corrected?

Do not silently update the analytics database by hand. A timestamp correction can change daily totals, funnel order, attribution, cohort membership, and experiment analysis.

A correction workflow should:

  • Preview the proposed change.
  • Validate the corrected timestamp against retention and future-skew rules.
  • Re-run event classification and property validation.
  • Require the expected current revision.
  • Bind approval to a hash of the previewed change.
  • Require a human-readable reason.
  • Preserve before-and-after evidence.
  • Return a conflict if the event changed after preview.

Poolstatis follows this model for eligible events. A correction updates the current materialized fact, increments its revision, and retains append-only revision history. The original receipt time remains separate from the corrected event time.

This gives product queries a corrected current record without erasing the evidence needed to explain how it changed.

What does Poolstatis implement today?

As of the source snapshot reviewed on August 21, 2026, Poolstatis Core implements these timestamp-related controls:

  • Events store both timestamp and server-controlled ingested_at.
  • Product trend queries group and filter by event timestamp.
  • Accepted-ingest operational trends group by ingested_at.
  • Missing live timestamps default to server receipt time.
  • Live timestamps outside the allowed range are replaced with receipt time and produce $clock_skew evidence.
  • A live batch can contain up to 500 events.
  • Invalid individual live events do not automatically sink every valid event in the batch.
  • Historical backfills require timestamps and use all-or-nothing validation.
  • Backfill commits bind a stable identifier to a canonical payload hash.
  • Eligible event corrections use preview hashes and optimistic revisions.
  • Revision history preserves correction evidence.

These claims were checked against Poolstatis Core commit c223efc0677995db278f233d6b69c9d43c708470, including the HTTP API documentation, live ingest service, and event-management service.

This is source verification, not proof that a particular Poolstatis Cloud deployment currently runs that commit.

For related implementation details, see the Poolstatis data model, HTTP integration guide, measurement guidance, and troubleshooting guide.

What should teams check before trusting event timestamps?

Use this checklist during instrumentation and analytics reviews:

  • Every event timestamp includes a timezone or UTC offset.
  • Event time and ingestion time are stored as separate fields.
  • Behavioral reports use event time by default.
  • Delivery and pipeline reports use ingestion time.
  • Future-skew and retention boundaries are documented.
  • Corrected timestamps produce visible warnings or audit evidence.
  • Offline and delayed delivery have been tested.
  • Retries reuse the original batch identifier and payload.
  • Historical imports use a dedicated backfill workflow.
  • Report snapshots record an ingestion cutoff when reproducibility matters.
  • Dashboards say whether recent periods are provisional.
  • Corrections preserve revisions instead of erasing history.

The reliable rule is simple: use event time to describe behavior and ingestion time to describe evidence arrival. Keep both, because trustworthy analytics needs to answer both questions.