We use analytics cookies.We use cookies to analyze site traffic and improve your experience.
Loading...
System Design Masterclass · Devops Cicd
Free preview: the first 2 parts of this 7-part lesson.
Already bought the course? Sign in to read the whole lesson.
this lesson is part of
System Design Masterclass
Unlock this lesson and the 751 other paid lessons
$25 once, by PayPal
See the System Design courseread the rest of this lesson in
System Design Masterclass
Unlock this lesson and the 751 other paid lessons
$25 once, by PayPal
See the System Design coursein Devops Cicd
This lesson is part of the full System Design Masterclass. Unlock it along with 769 other lessons for a one-time payment.
One-time payment by card or PayPal
Get Lifetime AccessOne-time payment: UPI, card or netbanking
Get Lifetime Access18 Foundation lessons are free, no payment needed. Try them now
It is easy and good
“It is really nice and good Please join the course”
A backend team renamed an API field from user_name to username for consistency. A small, clean change. But 200,000 mobile app installations were still using the old field name. Mobile apps cannot be force-updated. Users update when they want to (or never). The renamed field caused the app to crash for every user who had not updated. The team had to emergency-revert the API change and maintain both field names for the next 18 months.
Backward compatibility means new versions continue to work with existing clients, data, and integrations. You add the new field (username) alongside the old one (user_name) and return both. The old app works. The new app works. After enough users have updated (months, sometimes years), you deprecate the old field.
Stripe is the gold standard here. Their API has been backward-compatible since 2011. They version using dates (2023-10-16). Every API version they have ever shipped still works. If you pinned your integration to a 2015 version, it still returns responses in the 2015 format today.
| Change Type | Backward Compatible? | Safe Alternative |
|---|---|---|
| Add a new optional field to the response | Yes | N/A |
| Add a new optional parameter to the request | Yes | N/A |
| Remove a field from the response | No | Deprecate, keep returning it with default/empty value |
| Rename a field | No | Add new name, keep old name, return both |
| Change a field's type (string to int) | No | Add a new field with the new type |
| Add a required parameter to the request | No | Make it optional with a sensible default |
| Change the response structure (flat to nested) | No | Version the API (v1 returns flat, v2 returns nested) |
| Change error codes or error format | No | Add new error fields alongside old ones |
The general rule: you can add, but you cannot remove, rename, or change. Additive changes are safe. Subtractive or transformative changes break consumers.
API versioning strategies:
| Strategy | Example | Used By | Trade-offs |
|---|---|---|---|
| URL path versioning | /api/v2/users | Twitter, GitHub, Stripe (legacy) | Clear, but URL pollution |
| Header versioning | Accept: application/vnd.api.v2+json | GitHub (modern) | Clean URLs, less discoverable |
| Date-based versioning | Stripe-Version: 2023-10-16 | Stripe | Precise, but complex routing |
| Query parameter | /api/users?version=2 | Rarely used | Simple, but easy to forget |
The two-version rule: Support the current version and one previous version. When v3 launches, v2 is supported, v1 enters a deprecation period (3-6 months for internal APIs, 12-24 months for external APIs). This gives consumers a full version cycle to migrate.