A backend team renames a field from `shippedAt` to `dispatchedAt` because the new name matches what the warehouse system calls it internally, runs its own test suite, watches every test pass, and ships the change. Two hours later, three unrelated consumer teams' integrations start throwing errors in production, because each of them was reading `shippedAt` and none of them were in the room when the rename happened. The producing team's tests passed honestly — they tested the producer's own behavior in isolation, which is all a producer's own test suite can ever verify. What broke was an expectation the producer never knew existed, held by code the producer had never seen.
The obvious fix — full end-to-end tests that spin up every service and run a real request through the whole chain — does not survive contact with more than a handful of consumers. Every additional consumer team roughly doubles the coordination cost: someone has to keep every team's environment aligned, every suite waiting on every other team's deploy schedule, and one flaky downstream service can block a release that has nothing to do with it. Teams that try to scale this way past a certain size quietly stop running the integration suite at all, not because they stopped caring about breakage, but because keeping it green became more expensive than the breakage it prevented.
Consumer-driven contract testing closes the gap without needing every service running at once. Each consumer writes down, as an executable contract, exactly what it expects from a provider — which fields it reads, which values it depends on, which endpoints it calls with which parameters — and the provider verifies its own code against every consumer's contract independently, without ever running a single line of the consumer's actual code. The `shippedAt` rename fails a contract check in seconds, on the producer's own machine, before a single request ever leaves a real environment.