A provider service has 40 consumers and a 15-minute pipeline. Contract tests already exist and the provider still breaks consumers in production. Which change actually fixes it?
Show the full answer Hide the answer
The deciding property
Contract tests that run and are not consulted at the deploy decision are documentation. The missing piece is a query at deploy time: "can this provider version safely go to this environment, given what is running there right now?"
That requires three facts to be recorded rather than assumed: which provider version is being deployed, which consumer versions are live in that environment, and whether each of those pairs has a successful verification. A contract broker holds that matrix and answers the question in under 2 seconds, which matters because a gate that adds 10 minutes to a 15 minute pipeline gets disabled within a month.
Why the other options fail
- A nightly integration environment. It tells you something was broken between 6pm and 6am, with every team's changes mixed together, and the signal arrives after merge. Shared environments also become a queue: at 40 consumers the environment is the constraint, and its failures are attributed to whoever is unlucky.
- An OpenAPI backward-compatibility check. Worth having, and it catches structural breaks — removed fields, narrowed types. It cannot see semantic breaks, which are the ones that hurt: an enum gains a value a consumer switches on, a field that was always present becomes optional, a list that was ordered stops being ordered, an error code changes meaning. The schema is still valid and the consumer is still broken.
- Consumers re-running against a release candidate. This is the old integration problem with extra coordination: 40 teams asked to run something on your schedule. It fails for organisational reasons before it fails technically.
What breaks at this scale, and what to add
- Verification against every contract ever recorded grows without bound and eventually blocks the pipeline over expectations from a consumer version nobody runs. Scope verification to deployed versions, with a tag per environment.
- Pending contracts. A new consumer expectation must not fail the provider's build before the provider has implemented it, or consumers learn to stop publishing. The expectation is recorded as pending, reported, and becomes blocking once satisfied once.
- A stated compatibility window, so old consumer versions age out of the matrix rather than constraining the provider forever.
When this is over-engineering
Below roughly five consumers inside one repository, prefer a build that compiles everything together: it is cheaper and stricter than any broker. Contract testing earns its cost when consumers deploy independently and on their own schedule; if they cannot, you have a distributed monolith and the contract machinery hides that fact rather than fixing it.