Why contracts
Most pipeline breakages come from upstream changes nobody announced: a column renamed, a value meaning changed, a feed moved to a new time. Contracts make those expectations explicit and testable.
What a contract contains
| Section | Content |
|---|---|
| Identity | Name, version, owner team, contact |
| Schema | Fields, types, nullability, keys |
| Semantics | Meaning of each field, units, time zone, allowed values |
| Quality | Rules and thresholds (uniqueness, completeness) |
| Service levels | Freshness, availability, support hours |
| Access | Classification, who may consume, how |
| Change policy | What counts as breaking, notice period, deprecation |
# Illustrative contract (format inspired by open data contract standards)
name: orders
version: 2.1.0
owner: team-checkout
schema:
- name: order_id
type: string
required: true
unique: true
- name: amount
type: decimal(18,2)
description: Order total including tax, in currency_code
- name: currency_code
type: string
pattern: "^[A-Z]{3}$"
quality:
- rule: row_count_daily
min: 1000
sla:
freshness: "available by 06:00 UTC daily"
changes:
breaking_notice_days: 30
Breaking vs non-breaking
| Change | Usually |
|---|---|
| Add an optional field | Non-breaking (minor version) |
| Remove or rename a field | Breaking (major version) |
| Change type or meaning | Breaking |
| Tighten nullability | Breaking for producers |
| Change delivery time | Breaking if it violates the SLA |
Breaking changes get a new major version, a notice period and a period where both versions are served.
Enforce, don't just document
| Where | How |
|---|---|
| Producer CI | Validate schema changes against the contract; fail the build on breaking changes |
| Streams | Schema registry compatibility rules (see the schema registry post) |
| Tables | dbt model contracts (contract: {enforced: true}), table constraints, expectations |
| Runtime | Quality checks on publish; alert the producer when violated |
Rolling it out
- Pick the 3–5 interfaces where breakage has caused real incidents.
- Write contracts with both producer and consumer teams in the room.
- Add CI checks on the producer side.
- Make the contract part of the definition of done for new data products.
Warning
A contract without an owner on the producer side is only documentation. The producing team must accept responsibility, otherwise enforcement just moves the failure.
Checklist
- High-impact interfaces chosen first
- Contract template agreed
- Breaking change rules and notice period defined
- CI and runtime enforcement in place
- Producer ownership accepted
- Contracts versioned and discoverable