<@U088WCP3B4P> Subject: Handling `volume_anomaly` ...
# ask-elementary-ai
a
@kapa.ai Subject: Handling
volume_anomaly
and
freshness_anomaly
tests for business-day-only Airflow orchestration Question: Is it possible to implement Elementary's
volume_anomaly
and
freshness_anomaly
tests on a dbt model that is orchestrated via Airflow with a business-day-only schedule (12 PM)? The logic of the pipeline is to process all "pending" data since the last successful run. This creates an uneven distribution of data per execution: • Monday Run: Ingests data from Friday, Saturday, and Sunday. • Holiday Scenario: If Friday was a holiday, the Monday run ingests data from Thursday, Friday, Saturday, and Sunday. • Tuesday Run: Ingests only Monday's data. Considering the Elementary documentation for these tests: 1. Can these ingestion "bursts" be handled using the standard dbt YAML syntax for Elementary tests? 2. How should I configure the
time_bucket
or the
event_timestamp
to avoid false positives on Mondays (volume spikes) or over the weekend (freshness delays)? 3. Or, given this specific business logic, is it necessary to design a custom test instead?
k
Elementary can support this kind of “bursty” business‑day ingestion, but you’ll need to be deliberate about how you use
timestamp_column
/
time_bucket
, and you may want to combine multiple tests rather than rely on a single configuration. Below I’ll separate guidance for
volume_anomalies
and
freshness_anomalies
, and then address whether you really need custom tests. ------------------------- 1. Volume anomalies for business‑day bursts Option A – Treat each run as a snapshot (no timestamp) If your Airflow DAG runs only on business days and each run ingests “all pending data since last success”, the simplest and most robust pattern is: • Do not use
timestamp_column
on the
volume_anomalies
test. • Let Elementary record the total row count per run and compare those snapshots over time. [Weekly load example; Overwrite-table guidance] This way: • Monday’s “big” run (Fri+Sat+Sun, or Thu–Sun on holidays) is just “a typical Monday snapshot” and will be learned as such. • Tuesday’s smaller run (only Monday) is “a typical Tuesday snapshot”. • You’re not forcing Elementary to reason about per‑day volume; it just learns the pattern of per‑run volume. YAML example:
Copy code
models:
  - name: your_model
    tests:
      # Snapshot-per-run volume anomalies
      - elementary.volume_anomalies:
          # no timestamp_column here
          # optional: seasonality by day_of_week if you want Mon vs Tue patterns
          seasonality: day_of_week
This is the same “no timestamp” mode recommended for weekly loads and overwrite tables. [Weekly load example; No‑timestamp volume] Option B – Use
timestamp_column
+
time_bucket
only if you truly need per‑day volume
If you must detect anomalies per event day (e.g., “Sunday volume is off”), you can: • Set
timestamp_column
to the event date. • Use
time_bucket
with
period: day, count: 1
. [time_bucket docs] • Optionally add
seasonality: day_of_week
so Mondays are compared to Mondays, etc. [seasonality docs] However: • Elementary only evaluates *full buckets*; with daily buckets, that means “up to yesterday”. [Full‑day behavior; Day‑of‑week + full day requirement] • It still expects each calendar day’s volume to be comparable to previous same‑weekday days; your “bursty” ingestion is fine as long as the event timestamps reflect the true event day and the pattern is stable. Given your description, Option A (snapshot per run) is usually more stable and avoids Monday “spike” false positives. ------------------------- 2. Freshness anomalies with business‑day ingestion There are two different “freshness” needs that show up in your scenario: 1. “Did we run on time today?” (pipeline recency) 2. “How old are the events we just ingested?” (event‑to‑now lag) Elementary has multiple ways to handle this, but the knowledge sources don’t fully spell out all configuration details for
freshness_anomalies
in this exact pattern. I’ll stick to what is documented. A. Use standard dbt freshness tests for “did data arrive?” Several users combine Elementary with dbt’s built‑in freshness tests to answer “did the table get updated when expected?” and then let Elementary handle anomalies on other metrics. [Freshness combo discussion] In your case: • dbt freshness can be configured to expect updates only on business days. • Elementary will still surface alerts for those dbt tests, even though they’re not Elementary tests per se. [Freshness combo discussion] This avoids weekend “false delays” because you simply don’t expect runs on weekends. B. Event‑level freshness anomalies (lag between event time and now) Elementary added
event_freshness_anomalies
specifically for cases where loading happens later than the event time, and you want to measure the lag between event timestamp and now. [event_freshness_anomalies intro] This is a good fit if: • Events from Fri–Sun are all loaded on Monday, but you want to detect if that lag suddenly grows (e.g., you start loading events 5 days late instead of 2–3). • You care about “event recency” rather than “table last updated at”. The docs link in the thread is generic, but the intent is clear: this test is designed for delayed ingestion patterns like yours. [event_freshness_anomalies intro] ------------------------- 3. Handling weekends / holidays and avoiding false positives From the knowledge sources: • Seasonality (
day_of_week
,
hour_of_day
,
hour_of_week
) is the main built‑in way to handle recurring patterns like weekends. [seasonality docs] • There is no built‑in way to “skip” specific days (e.g., weekends) from detection while still using
fail_on_zero
for weekdays; this is a known limitation. [Weekend exclusion limitation] • For cases where you don’t want to evaluate the very latest data (e.g., partial loads), you can use
detection_delay
to exclude the most recent period from detection. [detection_delay suggestion] Applied to your setup: • If you use snapshot‑per‑run volume anomalies (no timestamp), you don’t need to worry about weekends at all; there are simply no runs on those days. • For event‑based tests (volume or freshness with
timestamp_column
), use: ◦
seasonality: day_of_week
if you want Monday patterns vs Tuesday patterns. ◦
detection_delay
if you need to ignore the most recent partial period (less relevant if you only run once per business day at noon). ------------------------- 4. Do you need a custom test? Based on the knowledge sources, you can stay within standard dbt YAML + Elementary tests: •
volume_anomalies
without
timestamp_column
to learn per‑run volume (handles Monday bursts and holiday shifts). [Weekly load example; No‑timestamp volume] • dbt freshness tests for “did we run on time on business days?”. [Freshness combo discussion] •
event_freshness_anomalies
if you also want anomaly detection on event‑to‑now lag. [event_freshness_anomalies intro] The knowledge sources do not indicate that a custom test is required for your pattern; they instead show how similar “non‑daily / bursty” or “weekly” ingestion patterns are handled via: • No‑timestamp mode •
time_bucket
•
seasonality
•
detection_delay
• Combining Elementary with dbt’s own freshness tests If you find that you must exclude specific calendar days from detection while still using
fail_on_zero
and timestamp‑based buckets, that’s where current capabilities hit a limitation and a custom approach (or upstream modeling change) might be needed. [Weekend exclusion limitation] ------------------------- Recommended minimal setup for your case 1. Volume anomalies (per run):
Copy code
models:
  - name: your_model
    tests:
      - elementary.volume_anomalies:
          seasonality: day_of_week   # optional but helpful
2. Freshness (pipeline recency): • Use dbt’s built‑in freshness test on the model or source, configured for business‑day expectations; Elementary will still alert on it. [Freshness combo discussion] 3. Optional: event‑lag anomalies:
Copy code
models:
  - name: your_model
    tests:
      - elementary.event_freshness_anomalies:
          timestamp_column: event_timestamp  # your event time column
This combination should handle your business‑day‑only Airflow orchestration without needing custom tests. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.
Yes, you can handle this pattern with standard Elementary tests in dbt YAML; you don’t have to build a custom test. The key is to choose the right mode for each test type. ------------------------- 1. Can these “burst” ingestions be handled with standard YAML? Yes. Similar non‑daily / bursty patterns (e.g., weekly loads) are handled using: •
volume_anomalies
without a
timestamp_column
(snapshot‑per‑run mode). [Weekly load example] • dbt’s built‑in freshness tests + Elementary alerts. [Freshness combo] • Optionally,
event_freshness_anomalies
for delayed ingestion. [Event freshness config] So your business‑day‑only schedule can be covered with standard configuration. ------------------------- 2. How to configure
volume_anomalies
and freshness to avoid false positives?
A. Volume anomalies – avoid Monday “spike” noise Recommended: treat each Airflow run as a snapshot; don’t bucket by event day. • Omit
timestamp_column
on
volume_anomalies
. • Elementary will store the total row count per test run and compare those snapshots over time. [Volume config] • This is the same pattern recommended for weekly loads and overwrite tables. [Weekly load example] That way: • Monday’s “big” load (Thu/Fri/Sat/Sun) becomes a typical Monday snapshot. • Tuesday’s smaller load (only Monday) becomes a typical Tuesday snapshot. • Elementary learns the per‑run pattern instead of per‑calendar‑day volume, so you don’t get Monday spike false positives. YAML example:
Copy code
models:
  - name: your_model
    data_tests:
      - elementary.volume_anomalies:
          arguments:
            # no timestamp_column -> snapshot-per-run mode
            seasonality: day_of_week   # optional, to distinguish Mon vs Tue patterns
seasonality: day_of_week
is supported and will compare Monday runs to previous Mondays, etc. [Seasonality docs] > Only use
timestamp_column
+
time_bucket
if you truly need per‑event‑day volume anomalies; otherwise snapshot‑per‑run is more robust for your pattern. [Weekly load example] ------------------------- B. Freshness – avoid weekend “delay” noise You likely have two different needs: 1. “Did the table get updated when expected?” (pipeline recency) 2. “Are events arriving later than usual?” (event‑to‑now lag) 1) Pipeline recency → use dbt freshness tests Users commonly use dbt’s built‑in freshness tests for “is data arriving on time?” and still get alerts via Elementary. [Freshness combo] • Configure dbt freshness to expect updates only on business days. • Elementary will surface alerts for those tests even though they’re not
freshness_anomalies
. This avoids weekend “false delays” because you simply don’t expect runs on weekends. 2) Event‑to‑now lag → use
event_freshness_anomalies
If you also care about “how old are the events when they land?”, use `elementary.event_freshness_anomalies`:
Copy code
models:
  - name: your_model
    data_tests:
      - elementary.event_freshness_anomalies:
          arguments:
            event_timestamp_column: event_ts   # when the event happened
            # optional tuning:
            # detection_period, training_period, time_bucket, seasonality, detection_delay, etc.
This test is designed for delayed ingestion patterns and focuses on the lag between
event_timestamp_column
and now. [Event freshness config] Because you only run on business days, there is no test execution on weekends, so you don’t get weekend “delay” alerts from this test either. ------------------------- 3. Do you need a custom test? Based on the docs and community examples: • Bursty / non‑daily ingestion is handled via: ◦
volume_anomalies
without
timestamp_column
(snapshot‑per‑run). [Weekly load example] ◦ dbt freshness tests for schedule‑based expectations. [Freshness combo] ◦
event_freshness_anomalies
for event‑lag anomalies. [Event freshness config] The knowledge sources do not indicate that a custom test is required for your business‑day‑only Airflow pattern; they show similar patterns solved with these configurations. You’d only need something custom if you require more complex calendar logic (e.g., dynamically skipping specific holidays inside timestamp‑based buckets), which is not described in the available docs. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.