Skip to content

Time Distribution Size Check Examples

Three real-world scenarios that show how the Time Distribution Size check is typically used in production: catching a short day in a daily load, spotting an hour ingested twice, and validating a backfill. All three report a Shape Anomaly, because the rule evaluates segment counts rather than individual rows.

The situation: Orders arrive continuously and a normal day holds between 5,000 and 20,000 records. A day well below that means the load stopped partway, which the container's total row count will not reveal because the other days still look normal.

Check configuration

Field Value
Rule Time Distribution Size
Field ordered_at
Filter (none)
Interval Daily
Min Count 5000
Max Count 20000
Owner (check creator)
Anomaly Assignee (Ingestion team)
Description Every day of orders must hold between 5,000 and 20,000 records.
Tags load-monitoring, distribution
Additional Metadata jira: DATA-10900
Status Active

Payload

{
    "description": "Every day of orders must hold between 5,000 and 20,000 records.",
    "rule": "timeDistributionSize",
    "fields": ["ordered_at"],
    "container_id": 145,
    "filter": null,
    "properties": {
        "interval_name": "Daily",
        "min_size": 5000,
        "max_size": 20000
    },
    "tags": ["load-monitoring", "distribution"],
    "additional_metadata": {"jira": "DATA-10900"},
    "template_id": null,
    "status": "Active",
    "owner_id": 7,
    "default_anomaly_assignee_id": 12
}

Sample Data (the daily segments the field produced)

Time segment Records
2026-03-09 11,240
2026-03-10 12,905
2026-03-11 1,430
2026-03-12 10,880

What gets flagged

The 11th holds 1,430 records against a normal eleven or twelve thousand: the load was interrupted early that morning. One of four segments is outside the range, so the anomaly reports 25% of the daily segments. The other three days pass, which is exactly why the container's total row count would not have raised anything.

Shape Anomaly

For the field 'ordered_at', 25.000% of the Daily time segments have record counts outside the range of 5000 to 20000

Flowchart

graph TD
    A["Group rows into Daily segments<br/>by ordered_at"] --> B["Count the records in each segment"]
    B --> C{"Is every count between<br/>5,000 and 20,000?"}
    C -->|Yes| D["Check passes"]
    C -->|No| E["Shape Anomaly reporting<br/>the failing segments"]

Equivalent SQL

-- The daily segments the check would flag.
SELECT date_trunc('day', ordered_at) AS time_segment,
       count(*) AS records
FROM orders
GROUP BY date_trunc('day', ordered_at)
HAVING count(*) < 5000 OR count(*) > 20000;

The situation: An event stream is written hourly and a normal hour holds between 150 and 1,200 events. When a replay reprocesses an hour without clearing the previous load, that hour holds roughly double, and every metric derived from it is overstated while the daily total still looks plausible.

Check configuration

Field Value
Rule Time Distribution Size
Field event_time
Filter (none)
Interval Hourly
Min Count 150
Max Count 1200
Owner (check creator)
Anomaly Assignee (Streaming Platform team)
Description Every hour of events must hold between 150 and 1,200 records.
Tags streaming, duplication
Additional Metadata jira: DATA-10918
Status Active

Payload

{
    "description": "Every hour of events must hold between 150 and 1,200 records.",
    "rule": "timeDistributionSize",
    "fields": ["event_time"],
    "container_id": 512,
    "filter": null,
    "properties": {
        "interval_name": "Hourly",
        "min_size": 150,
        "max_size": 1200
    },
    "tags": ["streaming", "duplication"],
    "additional_metadata": {"jira": "DATA-10918"},
    "template_id": null,
    "status": "Active",
    "owner_id": 7,
    "default_anomaly_assignee_id": 47
}

Sample Data (the hourly segments the field produced)

Time segment Records
2026-03-11 07:00 640
2026-03-11 08:00 812
2026-03-11 09:00 1,905
2026-03-11 10:00 735

What gets flagged

The 09:00 hour holds 1,905 events, more than double the surrounding hours and above the 1,200 ceiling: a replay reprocessed that hour on top of the original load. An oversized segment and a short one produce the same message, so the failing segments listed on the anomaly are what tell you which of the two happened.

Shape Anomaly

For the field 'event_time', 25.000% of the Hourly time segments have record counts outside the range of 150 to 1200

Flowchart

graph TD
    A["Group rows into Hourly segments<br/>by event_time"] --> B["Count the records in each segment"]
    B --> C{"Is every count between<br/>150 and 1,200?"}
    C -->|Yes| D["Check passes"]
    C -->|No| E["Shape Anomaly reporting<br/>the failing segments"]

Equivalent SQL

-- The hourly segments the check would flag.
SELECT date_trunc('hour', event_time) AS time_segment,
       count(*) AS records
FROM events
GROUP BY date_trunc('hour', event_time)
HAVING count(*) < 150 OR count(*) > 1200;

The situation: A backfill is repopulating three years of monthly transaction history from an archive. Each month should land between 40,000 and 90,000 records. A month far outside that means the archive for that period was partial or was read twice. Cancelled transactions are excluded, because the archive keeps them and the target table does not.

Check configuration

Field Value
Rule Time Distribution Size
Field transaction_date
Filter status <> 'cancelled'
Interval Monthly
Min Count 40000
Max Count 90000
Owner (check creator)
Anomaly Assignee (Migration team)
Description Every backfilled month must hold between 40,000 and 90,000 transactions.
Tags backfill, distribution
Additional Metadata jira: DATA-10937
Status Active

Payload

{
    "description": "Every backfilled month must hold between 40,000 and 90,000 transactions.",
    "rule": "timeDistributionSize",
    "fields": ["transaction_date"],
    "container_id": 733,
    "filter": "status <> 'cancelled'",
    "properties": {
        "interval_name": "Monthly",
        "min_size": 40000,
        "max_size": 90000
    },
    "tags": ["backfill", "distribution"],
    "additional_metadata": {"jira": "DATA-10937"},
    "template_id": null,
    "status": "Active",
    "owner_id": 7,
    "default_anomaly_assignee_id": 41
}

Sample Data (filtered to status <> 'cancelled', monthly segments)

Time segment Records
2025-11 61,400
2025-12 18,250
2026-01 58,900
2026-02 55,120

Why the filter matters

The filter runs before the grouping, so cancelled transactions never reach a segment. Without it, the counts would include rows the target table is not meant to hold and the range would have to be widened to accommodate them.

What gets flagged

December 2025 came back with 18,250 transactions against a normal fifty to sixty thousand: the archive file for that month was truncated. The three other months land inside the range. The message ends with the filter that scoped the evaluation. Note that a month the archive skipped entirely would produce no segment at all and would not be reported here, which is why a backfill is also worth checking against the source's own period list.

Shape Anomaly

For the field 'transaction_date', 25.000% of the Monthly time segments have record counts outside the range of 40000 to 90000 [filter: status <> 'cancelled']

Flowchart

graph TD
    A["Apply filter: status <> 'cancelled'"] --> B["Group rows into Monthly segments<br/>by transaction_date"]
    B --> C["Count the records in each segment"]
    C --> D{"Is every count between<br/>40,000 and 90,000?"}
    D -->|Yes| E["Check passes"]
    D -->|No| F["Shape Anomaly reporting the failing segments.<br/>Message ends with<br/>[filter: status <> 'cancelled']"]

Equivalent SQL

-- The monthly segments the check would flag.
SELECT date_trunc('month', transaction_date) AS time_segment,
       count(*) AS records
FROM transactions
WHERE status <> 'cancelled'
GROUP BY date_trunc('month', transaction_date)
HAVING count(*) < 40000 OR count(*) > 90000;

See Also