Data engineering, dbt

Irish Property Price Index, mix-adjusted

Year
2026
Role
Solo
Status
797,774 real transactions, validated against the CSO
PythondbtDuckDBSQL
Real Property Price Register sales
+2.22 / -3.91
National vs Dublin index-point gap
31 / 187
Months the two measures disagree on direction

What it is

A mix-adjusted stratified price index built on the full Property Price Register, 797,774 real sales, using dbt and DuckDB, validated directly against the CSO’s own official Residential Property Price Index rather than assumed correct.

The finding

  • Nationally, the raw median that gets reported overstates price growth by 2.22 index points on average versus the mix-adjusted measure. In Dublin it does the opposite, understating growth by 3.91 points, the opposite sign, from the same method on the same data.
  • Across 187 months with a year-on-year comparison, 31 have the raw and mix-adjusted series moving in different directions entirely, one says prices fell, the other says they rose, in the same month. Worst case: June 2013, a 13.05-point gap at the post-crash trough.
  • Not a broken number: both series correlate at 0.99+ over the full period. It’s the standard Simpson’s-paradox mechanism, what gets sold shifts composition over time, and a raw median conflates that shift with genuine price movement.

Getting the pipeline honest

  • First CI run reported nothing at all, because the workflow YAML itself was invalid; the check meant to catch mistakes had never once run a job.
  • Fixed that, then found the fixture job had never actually fetched the CSO benchmark it was supposed to validate against, so it had been silently passing against nothing since it was written.
  • A third fix pinned the parquet engine dependency the export step needs at runtime. None of the three were subtle bugs, they were just never checked, a different failure mode from a bug and a more common one.