DEV Community

Cover image for Data Quality & Reconciliation Report: Template and How-to
beefed.ai
beefed.ai

Posted on • Originally published at beefed.ai

Data Quality & Reconciliation Report: Template and How-to

  • What a Complete Reconciliation Report Must Contain
  • How to Automate Checks, Comparisons, and Dashboards
  • A Practical Method to Investigate and Prioritize Exceptions
  • How to Communicate Findings and Track Remediation
  • Hands-on Template: Reconciliation Report and Playbook

Reconciliation is the bedrock proof that your analytics are trustworthy: without a repeatable reconciliation report that shows coverage, exceptions, root cause, and remediation, every downstream number is a hypothesis. A focused Data Quality & Reconciliation Report converts noisy "mismatch" conversations into a single source of evidence that owners can act on.

You know the symptoms: dashboards that disagree with source systems, stakeholders debating "which number is right", analysts maintaining manual Excel reconciliations, late-night fixes before board meetings, and a growing backlog of undocumented exceptions. These are the operational signatures of weak ETL reconciliation and sparse exception reporting—slow detection, long resolution windows, and eroded trust in metrics.

What a Complete Reconciliation Report Must Contain

A reconciliation report must be an evidence package, not just a scoreboard. Build the report so a reviewer unfamiliar with the pipeline can answer: what ran, what was compared, what differed, why it differed, and what was done about it.

  • Header & context
    • Report ID (recon_YYYYMMDD_<pipeline>), run_id, environment, operator, etl_job_version.
    • Scope: source(s), target(s), and date/partition covered.
  • Run metadata
    • Start/finish timestamps, runtime, and upstream job IDs.
  • Coverage checks (high-level)
    • Row counts and basic aggregates (COUNT, SUM, MIN, MAX) by partition/key.
  • Column-level sanity checks
    • Null rates, value ranges, pattern/format tests, referential integrity.
  • Reconciliation diffs
    • Missing rows, orphan rows, and value mismatches with sample PKs.
  • Exception catalogue (sortable)
    • Rule ID, rule description, severity, row-count impacted, top example PKs.
  • Root Cause Analysis (for top exceptions)
    • Evidence, suspected root cause category, timeframe when issue began.
  • Remediation tracking
    • Owner, remediation action, expected fix-by date, validation query, status, resolution timestamp.
  • KPIs and metrics
    • pass rate, exception rate, mean time to detect (MTTD), mean time to remediate (MTTR), SLA breaches.
  • Lineage & audit links
    • Link to source extract files, transformation script/commit, and orchestration run.
  • Attachments
    • Small sample files (CSV), failing-row extracts, full SQL diffs.
Section Example fields Why it matters
Header & context report_id, run_id, scope Reproducibility and audit trail
Coverage checks src_count, tgt_count, count_delta Fast indicator of major data loss
Exceptions rule_id, severity, rows_affected Prioritization and triage
RCA + Remediation root_cause, owner, validation_query Closes the loop and prevents recurrence

Contrarian note: rather than chasing 100% coverage of every low-impact column, prioritize reconciliation rules that affect business-key metrics (e.g., revenue, balances, headcount). Track coverage by business impact and instrument cost-to-fix vs. value.

Practical verification queries (examples)

-- Basic row-count reconciliation
SELECT 'source' AS side, COUNT(*) AS cnt
FROM src.sales.orders
WHERE load_date = '2025-12-16'
UNION ALL
SELECT 'target' AS side, COUNT(*) AS cnt
FROM dwh.fct_orders
WHERE load_date = '2025-12-16';

-- Find missing/orphaned rows and value mismatches (Postgres-ish syntax)
SELECT COALESCE(s.order_id, t.order_id) AS order_id,
       s.total_amount AS src_amount,
       t.total_amount AS tgt_amount
FROM src.sales.orders s
FULL OUTER JOIN dwh.fct_orders t ON s.order_id = t.order_id
WHERE s.order_id IS NULL
   OR t.order_id IS NULL
   OR s.total_amount IS DISTINCT FROM t.total_amount;
Enter fullscreen mode Exit fullscreen mode

Hash-based reconciliation scales: compute a deterministic row_hash on business columns for source and target, then compare hashes to find changed rows quickly. Partition-level hashes (one hash per date/partition) let you triage at scale and then drill to row-level when mismatches appear .

Important: always capture sample failing rows (PK + raw values) and the exact SQL used to extract them. Those three artifacts (sample, SQL, timestamps) are the minimal evidence an owner needs to reproduce and fix an issue.

How to Automate Checks, Comparisons, and Dashboards

Automation turns reconciliation from a monthly ritual into operational guardrails.

Automation pattern (recommended):

  1. Pre-load validations (schema, file presence, row counts).
  2. ETL run with instrumentation (run_id, batch_id, source_snapshot_ts).
  3. Post-load reconciliation tests (counts, aggregates, row/column hashes).
  4. Persist test results in a recon schema (JSON payloads + structured rows).
  5. Drive dashboards and exception feeds (BI tool + incident system).

Tools and integrations

  • Use dbt for data tests and to run dbt test in CI/CD — dbt returns failing records and can store failures for quick debugging .
  • For assertion-driven validation and human-readable Data Docs, Great Expectations produces executable expectations and an HTML report of results (Data Docs), ideal for packaging into a reconciliation artifact .
  • Enterprise ETL/validation platforms such as QuerySurge automate large-scale ETL testing and take you beyond the "stare and compare" approach .

Store a structured test-result artifact for each run. Example JSON payload for the reconciler:

{
  "report_id": "recon_20251216_fct_orders",
  "run_id": "etl_20251216_03",
  "table": "dwh.fct_orders",
  "source_count": 1234567,
  "target_count": 1234560,
  "exceptions": 7,
  "top_rules": [
    {"rule_id":"R001","rows":5},
    {"rule_id":"R012","rows":2}
  ],
  "status": "PARTIAL",
  "started_at": "2025-12-16T03:12:00Z",
  "finished_at": "2025-12-16T03:15:22Z"
}
Enter fullscreen mode Exit fullscreen mode

Dashboards should expose:

  • Real-time summary (pass/fail counts per pipeline),
  • Top failing rules and impacted tables,
  • Trend lines for MTTR and exception recurrence,
  • Click-through links to raw evidence (failed-rows extracts, SQL, run logs).

Integration tips:

  • Push results to a reconciliation schema and surface via BI (Looker, Power BI, Tableau) or an observability stack (Prometheus + Grafana) for operational alerts.
  • Emit structured incidents to your ticketing system (Jira, ServiceNow) with the report_id and validation_query pre-filled.
  • Keep a human-readable Data Docs artifact for each run (e.g., via Great Expectations) linked from the report.

A Practical Method to Investigate and Prioritize Exceptions

Triage must be fast, objective, and repeatable. Use instrumentation to answer: how many rows, which business keys, who owns the fix, what’s the likely impact?

Step 1 — quick classification (automated)

  • Auto-classify exceptions into: missing rows, value mismatch, duplicates, schema drift, late arrival, format/validation error.
  • Record frequency and first-seen timestamp.

Step 2 — impact scoring

  • Compute a priority score (example):
priority_score = severity_weight * severity + freq_weight * log(1 + rows_affected) + impact_weight * business_impact_pct
Enter fullscreen mode Exit fullscreen mode

Sample weights:

  • severity_weight = 50 (Critical=3, High=2, Medium=1, Low=0)
  • freq_weight = 5
  • impact_weight = 100 (percentage impact on a business metric)

Step 3 — evidence collection

  • Extract N=100 failing PKs and full row payloads.
  • Capture upstream file identifiers / message offsets and the transformation SQL/commit hash that touched the data.
  • Capture relevant orchestration logs (Airflow task logs, timestamps).

Step 4 — root cause process (concise)

  1. Reproduce the mismatch with the same run_id and partition.
  2. Compare source raw extract vs. staging vs. final (triage across hops).
  3. Check for schema changes, trimming/rounding rules, timezone shifts, and null-to-default conversions.
  4. If the source is wrong, tag owner=source_team. If transform or mapping incorrect, tag owner=etl_team. If platform/performance causes partial loads, tag owner=ops_team.

Root cause categories and owners

Root cause category Typical owner
Upstream source data error Source system / product team
Transformation logic bug ETL / ELT developer
Schema drift or mapping change Data modeler / schema owner
Late-arriving data / timing Scheduling / ops
Duplicate/inconsistent keys Source or ingestion layer

RCA template (one-line summary + evidence)

Field Content
Exception ID R-20251216-001
Symptom COUNT(src) - COUNT(tgt) = 7
Evidence sample_orders.csv (100 rows), etl_run_20251216_03.log
Suspected root cause Upstream file truncation at 03:00 UTC
Immediate mitigation Re-run source extraction for partition 2025-12-16
Permanent fix Add file-size check + fail-fast upstream
Validation query (SQL to confirm re-run restored counts)
Owner etl-oncall
Target fix-by 2025-12-17T12:00:00Z

Contrarian insight: prioritize errors by business impact not purely by row count. A mismatch of 100 rows containing high-value transactions can be far worse than 10k low-value rows.

How to Communicate Findings and Track Remediation

Communication must be concise, evidence-first, and action-oriented. Your reconciliation report is the primary incident summary used by engineers, analysts, and product owners.

Executive summary (top of report)

  • 1–2 lines: overall status (Pass / Partial / Fail), number of exceptions, top impacted metric and estimated delta.
  • Bullet: top remediation actions and owners.

Example executive sentence:

  • "Partial — 7 exceptions across 3 tables; revenue delta ≈ $18,400 (source > target). Owner: ETL team (etl-oncall); mitigation: re-run extract for 2025-12-16."

Exception tracking (structured ticket fields)

  • exception_id, rule_id, rows_affected, business_metric_impact, owner, priority_score, first_seen, status, validation_query, evidence_link, resolved_at.

Recommended lifecycle statuses:

  • Open → Investigating → Fix Implemented → Validation → Closed
  • Add Reopened state when an exception recurs after being closed.

Validation after remediation

  • Every remediation must include a validation_query and a validation_run_id. Capture before/after snapshots and link them in the ticket.
  • Use the reconciliation report to show a "delta timeline": when exception was opened, when fix deployed, when validation passed.

Report sections to include for stakeholders

  • Data steward view: table-level summary + business impact.
  • Engineer view: failing-rule detail + SQL + sample rows + logs.
  • Audit view: timeline, approvals, and resolution evidence.

Important: pair every remediation action with an automated validation step that becomes part of the CI/CD pipeline. The presence of a reproducible validation_query is the difference between "we think it's fixed" and "we proved it's fixed".

Hands-on Template: Reconciliation Report and Playbook

Below is a compact template you can copy into a Markdown/HTML report or generate programmatically from automated results.

Report header (meta)

  • Report ID: recon_<env>_<pipeline>_<YYYYMMDD>
  • Run ID: etl_<YYYYMMDD>_<runseq>
  • Environment: prod/staging
  • Scope: src.sales.orders -> dwh.fct_orders
  • Run started/finished: timestamps

Summary metrics

Metric Value Note
Source row count 1,234,567 Partition = 2025-12-16
Target row count 1,234,560 DWH load
Count delta 7 Negative = data lost
Exceptions 3 rules R001 (missing rows), R007 (null currency), R012 (duplicate key)
Pass rate 99.999% (rows passing / total rows)

Top exceptions (sample)

rule_id description rows severity owner status
R001 Missing rows after MERGE 7 Critical etl-oncall Investigating
R007 currency null for revenue rows 2 High src-team Open
R012 Duplicate PK in staging 15 Medium ops Fix Implemented

Standard remediation ticket template (Jira fields)

  • Summary: R-<id> [recon] Missing rows in dwh.fct_orders partition=2025-12-16
  • Description: symptom + evidence + suggested validation query (paste SQL).
  • Priority: calculated priority_score.
  • Assignee: owner.
  • Due date: based on SLA.
  • Labels: recon, etl, data_quality, <pipeline>.
  • Attachments: sample_rows.csv, etl_run_<id>.log, recon_report_<id>.json.

Operational checklist (run after each failed reconciliation)

  1. Capture run_id and copy recon_report JSON into the ticket.
  2. Extract 100 example PKs and attach sample CSV.
  3. Run row-hash diff on the impacted partition and capture results. (Use partition-level then row-level as needed.)
  4. Identify owner and set status and due date in ticket.
  5. After fix, run validation_query and append results to ticket.
  6. Update reconciliation dashboard with resolved_at and recalc MTTR.

Test-case matrix (example rows)

Test ID Description Source query Target query Expectation Tolerance
TC-ORD-01 Row count per day SELECT COUNT(*) ... FROM src SELECT COUNT(*) ... FROM dwh equal 0
TC-ORD-02 Revenue sum per day SUM(amount) SUM(amount) equal 0.1%
TC-ORD-03 Unique order_id COUNT(DISTINCT order_id) COUNT equal 0

Automated SQL snippet to store a reconciliation summary (example)

INSERT INTO ops.recon_summary(report_id, run_id, table_name, src_count, tgt_count, exceptions, status, created_at)
VALUES('recon_prod_orders_20251216', 'etl_20251216_03', 'dwh.fct_orders', 1234567, 1234560, 3, 'PARTIAL', now());
Enter fullscreen mode Exit fullscreen mode

Measure what matters: track the percentage of exceptions that reoccur within 30 days (recurrence rate), and display a Pareto of rule failures — those represent the most leverage for long-term improvement.

Sources:
What Is Data Quality Management? — IBM - Descriptions of the common data quality dimensions (accuracy, completeness, consistency, timeliness, uniqueness, validity) and why they matter for metrics and reconciliation.

Great Expectations OSS — Introduction - Explanation of Expectations, Data Docs, and how GE produces human-readable validation artifacts for automated reporting.

Add data tests to your DAG — dbt Documentation - How dbt test asserts data conditions, returns failing records, and stores failures for debugging and CI integration.

What is QuerySurge? — QuerySurge product overview - Description of enterprise ETL testing automation and the contrast with manual "stare and compare" methods.

Calculation of hash values — Microsoft Docs (Q&A) - Practical guidance on row-level and partition-level hashing strategies for scalable reconciliation and change detection.

Top comments (0)