Dashboard

What goes in an ETL monitoring dashboard in Metabase?

An ETL monitoring dashboard is the operational failure-watching view: failed runs and their error taxonomy, retry outcomes, runtime anomalies, late-arriving data, and the on-call queue. Where the ETL dashboard reviews the portfolio weekly, this one is read by whoever is on call, today — built from the same orchestrator run records, sliced for the last 24 hours.

For: on-call data engineers. Grain: one row per run attempt, including retries. Refresh: every few minutes — this dashboard is a queue, not a report.

What does an ETL monitoring dashboard look like?

Here’s the layout this guide builds. The open-failure counts sit at the top because they are the work queue; failure volume, taxonomy, and retry behaviour come next to answer “what kind of failures are these”; anomalies, late data, and the queue table sit at the bottom, where diagnosis happens.

ETL monitoring dashboard in Metabase showing failed runs, error taxonomy, retry outcomes, runtime anomalies, late data, and the on-call queue.
An example ETL monitoring dashboard in Metabase, built from per-attempt pipeline run records. Figures are illustrative.

Which cards belong on an ETL monitoring dashboard?

The eight below cover detection, classification, and recovery — what broke, what kind of broken it is, and whether it is healing.

  • Failed runs per day (bar)
  • Failures by error type, last 7 days (row)
  • Retry outcomes per day — recovered versus exhausted (stacked bar)
  • Failure rate by pipeline, last 7 days (row)
  • Runtime anomalies — latest runtime against 28-day baseline (scatter)
  • Tables with late-arriving data per day (line)
  • Time to recovery, weekly (line)
  • On-call queue — open failures with attempts, age, and owner (table)

What data does the dashboard need?

  • Per-attempt run records — pipeline, attempt number, status, failed_at, resolved_at, runtime, and the raw error_class string.
  • An error-taxonomy mapping table — class_pattern → bucket — so classification is data, not card logic.
  • A rolling runtime baseline per pipeline (28-day median), for the anomaly scatter.
  • Event-time watermarks per destination table — max event timestamp versus load timestamp — for the late-data card.
  • A pipeline dimension with owner and escalation target, so the queue table can say whose problem each row is.

How do you build it?

  1. Sync run attempts (not just final outcomes) from the orchestrator into reporting.pipeline_runs — retry analysis needs every attempt, with error class and timestamps.
  2. Create the error_taxonomy pattern table and join it in a shared model, keeping an Unclassified bucket you review weekly.
  3. Materialize a per-pipeline 28-day median runtime, and compute each run’s deviation from it for the anomaly scatter.
  4. Add watermark tracking — max event time per load — and flag tables whose event-to-load gap exceeds their threshold.
  5. Add filters for pipeline, error type, and owner, set the dashboard to auto-refresh, and wire threshold alerts to the team channel — paging stays in PagerDuty.

Example card SQL

The on-call queue: open failures by age PostgreSQL
SELECT
r.pipeline,
COALESCE(t.bucket, 'Unclassified')                    AS error_type,
MIN(r.failed_at)                                      AS first_failed_at,
COUNT(*)                                              AS attempts,
ROUND(EXTRACT(EPOCH FROM (now() - MIN(r.failed_at))) / 3600.0, 1)
                                                      AS age_hours,
p.owner
FROM reporting.pipeline_runs r
JOIN reporting.pipelines p ON p.pipeline = r.pipeline
LEFT JOIN reporting.error_taxonomy t
ON r.error_class LIKE t.class_pattern
WHERE r.status = 'failed'
AND r.resolved_at IS NULL
GROUP BY r.pipeline, t.bucket, p.owner
ORDER BY age_hours DESC;

Metrics

Integrations

Dashboards

FAQ

What is an ETL monitoring dashboard?
An ETL monitoring dashboard is the operational view of pipeline failures: what is failing right now, what kind of error it is, whether retries are rescuing it, which runs are behaving anomalously, and what data is arriving late. It is read by whoever is on call, refreshed continuously, and organized so the top of the page is a work queue rather than a report. Everything on it comes from the orchestrator's run records — one row per run attempt with status, error class, and timestamps — landed in the warehouse.
How is this different from the ETL dashboard?
Direction of attention. The ETL dashboard is the portfolio and SLA view — weekly trends, cost per pipeline, freshness commitments — for a lead planning work. This one is the failure-watching view — the last 24 hours, the error taxonomy, the open queue — for an engineer fixing things today. The split matters in practice: mixing them either buries the on-call signal under trend charts or turns the weekly review into incident archaeology. Build both from the same pipeline_runs table so the two views can never disagree about what happened.
How do I build a useful error taxonomy?
Map raw exception classes to a small set of buckets with a pattern table — error_class LIKE pattern → bucket — and keep it under about eight buckets: source API errors, schema changes, timeouts, permissions, resource exhaustion, data-quality rejections, unclassified. The taxonomy exists to answer "what kind of week are we having": a spike in schema changes points at an upstream release, a spike in timeouts points at warehouse contention. Review the Unclassified bucket weekly and promote recurring patterns — an error rate that is 40% Unclassified isn't a taxonomy yet.
What does the retry rescue rate tell me?
It separates transient from persistent failure. A high rescue rate — most failures recovered by automatic retry — means the failures are flaky infrastructure and rate limits: annoying, but self-healing. A falling rescue rate, like the slide from 74% to 61% in the example, means failures are becoming deterministic — schema changes and permission errors that no retry will fix — and a human queue is building. Alert on the trend, not on individual retries. Also cap retries with backoff: a pipeline retrying a deterministic failure every five minutes is spending compute to generate alert noise.
How do I detect runtime anomalies?
Compare each run against its own pipeline's baseline, not a global threshold. Compute a rolling 28-day median runtime per pipeline, then flag runs above roughly twice the median (or three median absolute deviations for noisy pipelines). The scatter card plots latest runtime against baseline — points near the diagonal are normal, points far above it are the anomalies worth a look. Runtime anomalies are the leading indicator on this dashboard: a pipeline that suddenly runs twice as long usually fails or misses its window within days, so catching the drift beats catching the failure.
What counts as late-arriving data?
Data whose event time is much older than its load time — records for Monday landing on Wednesday. Detect it by tracking a watermark per table: the maximum event timestamp each load carries, compared with the load's own timestamp. A growing gap means an upstream buffer is draining late, and downstream aggregates built on the affected dates are quietly wrong until they're rebuilt. That is why the late-data card sits on the monitoring dashboard: the pipeline run itself succeeded, so nothing else will alert. Pair detection with a reprocessing routine for affected partitions rather than ad-hoc backfills.
Can Metabase page the on-call engineer?
Use each tool for its job. Metabase alerts can notify a channel or email when a card crosses a threshold — good for "failed runs exceeded 30 today" going to the team channel. Actual paging with escalation policies and acknowledgement belongs in PagerDuty, fed by the orchestrator's own failure callbacks. The dashboard's role is the shared queue between pages: the on-call engineer works down the open-failures table, and the whole team sees the same state without asking. Keep the queue card's refresh interval short; a stale queue is worse than no queue.