How to Communicate Breaking Changes and Deprecations

Somewhere right now a finance team is running a Monday morning report through an integration that will stop working in three weeks. They do not know it yet.

Somewhere right now a finance team is running a Monday morning report through an integration that will stop working in three weeks. They do not know it yet. The engineering team that made the call knows, the ticket closed a month ago, and the only public trace is a line in a changelog nobody on that team reads.

That gap is where the damage happens. Removing software is normal, healthy work. Every product carries features a handful of customers depend on and most never touch, and hauling them along forever slows everything down. The failure is almost never the removal. It is the customer finding out on cutover day.

A good deprecation notice does one job. It gives the people who built something on top of your product enough time, enough detail, and enough repetition to move before the ground shifts. It takes a severity call, a lead time that matches the work you are asking of them, six questions answered up front, and a run of messages carrying through the week after the change lands.

The work splits into four decisions. How severe the change is. How much lead time that severity earns. What the announcement has to say. And how many times you say it.

Breaking changes, deprecations, and ordinary updates are three different problems

The difference comes down to one question. What does the customer have to do, and by when? An ordinary update asks nothing of them. A deprecation asks for work on a schedule you set. A breaking change takes the choice away and sets the schedule itself.

Teams collapse these categories constantly, usually in the direction of comfort. A removal gets written up as an improvement because improvement is a nicer word. The customer does not care what you filed it under. They care whether their Monday still works. The habits that make an ordinary update easy to skim still apply, but the sorting decision comes first.

Sort correctly and everything else follows. Severity sets lead time, lead time sets the message sequence, and the sequence sets who has to be in the room. Sort wrong and every downstream choice is wrong by the same margin, which is how a three week notice ends up attached to a change that needed three months.

What makes a change breaking

A change is breaking when code or a workflow that works today stops working after you ship, with no action from the customer. The 200 response becomes a 404. A field that returned a string now returns an object. The saved view an ops team built its weekly process around is gone.

Renaming a field breaks things. So does tightening validation on an input you used to accept, adding a required parameter, changing a default sort order, and lowering a rate limit. None of those feel like removals from the inside, and all of them produce a customer whose integration fails without warning.

The test is to ask what happens if a customer does nothing at all. If everything keeps working the way it did, the change is additive and belongs in your normal update flow. If the answer involves an error, a silently different result, or a workflow that dead ends, the change is breaking and earns the full treatment no matter how small the diff was.

What deprecation signals to a customer

Deprecation is a countdown, and the thing being deprecated keeps working the whole time it runs. You are telling customers that a feature, endpoint, or plan has a known end date, that it will function until then, and that they should stop building anything new on top of it now.

Python made this legible at a scale most teams never reach. The core team announced in 2008 that Python 2 would sunset in 2015, then moved the date to January 1, 2020 when adoption of Python 3 lagged. Anyone installing a package with pip on Python 2.7 got a line in their terminal naming the end of life date, which found people inside their workflow instead of waiting for them to check a page.

Two things make a deprecation work. The end date has to be real, and the replacement has to exist before you announce. A removal announced with no migration path is not a deprecation. It is a warning that you are about to take something away.

How much lead time each severity level needs

Lead time should match the work you are asking the customer to do, not the size of the change on your side. Deleting an endpoint might be a one line pull request. Rewriting the integration that depends on it, testing it, getting it past a change advisory board, and scheduling the deploy can take a quarter at a company with real process.

Atlassian ran the extreme version. It announced the end of support for its Server products in October 2020 and set the final date at February 15, 2024, then staged the middle with hard milestones. New Server license sales stopped in February 2021 and new Marketplace app sales for Server in February 2023. Each step was announced and then repeated, including countdown posts at 100 days and 30 days out.

Most teams are not retiring a twenty year product line, so the shape matters more than the numbers. Set the date from the customer's side of the work, publish it once you are certain you can hold it, and put the rule in your standing plan for release communication rather than relitigating it per change.

Lead time by severity

What follows is a starting scale, not an industry standard. No published rule sets a universal minimum, and your contracts and support tiers will pull these numbers in both directions. Use it to make the severity call visible, then argue the specific dates with the accounts who will feel them.

Change typeWhat the customer has to doStarting lead timeReminder cadence
Additive or cosmetic changeNothingAnnounce at shipNone
Behavior change with a fallbackCheck a setting14 to 30 daysOne reminder
Feature removal with a replacementMigrate a workflow by hand60 daysTwo reminders
Breaking API or integration changeWrite, test, and ship code90 days minimumThree reminders plus in-product warnings
End of life for a product, plan, or versionReplan, budget, sometimes recontract6 to 12 monthsQuarterly, then monthly in the final 90 days

Two adjustments come up constantly. Anything touching billing, authentication, or data export moves up a tier however simple the change looks, because those three break quietly and expensively. And anything a customer had to write code against gets the API row, whether or not you think of it as an integration.

Six questions your announcement has to answer

Every deprecation notice has to answer six questions, and the order matters because readers stop early. What is changing. What is not changing. Whether this particular reader is affected. How to prepare. What happens if they do nothing. When it takes effect.

Most drafts answer the first and the last and leave the middle four to support. That is backwards. The first thing a reader wants to know is whether this is their problem, and if your announcement makes them work that out from a feature name, plenty will guess wrong in both directions. Some panic over a change that never touches them. More decide it does not apply and go back to work.

Answer all six in plain language and in that order. If you would rather start from a fill-in version than a blank page, there is a ready-made deprecation format you can copy with the same six questions built in as section headings. Two of the six carry most of the weight and get the least attention.

Am I affected, and how do I check

Tell the reader exactly how to find out, in a way they can act on in under a minute. Name the endpoint, the setting, the plan, the report type. Then give them somewhere to look. A settings page showing whether the feature is on. A search string for their own codebase.

The version that fails reads like this. "Customers using legacy exports may be affected." The reader has no idea whether that is them, because the export they set up eighteen months ago is called the Tuesday report in their head.

Better still, run the check for them. If your usage data shows which accounts called the endpoint in the last 90 days, send those accounts a different message than everyone else, and say plainly that you are writing because their account used the feature on specific recent dates. Targeted notices get read because they are obviously not a broadcast. They also cut the support load, since the biggest category of tickets after any deprecation is people asking whether it applies to them.

What happens if I do nothing

Say what breaks, how it breaks, and whether anything catches them. Customers read this line to size up risk, and vague wording makes them assume the worst or, more dangerously, the best.

There are three honest answers. The call starts failing with a specific error, which is the cleanest outcome and the easiest to plan around. The call keeps working but returns something different, which is the most dangerous, because a report that quietly changes its numbers does more damage than one that stops. Or the system falls back on its own, which is what Shopify does when an app targets a retired API version, serving the request with the oldest version still supported instead of refusing it.

Fallback behavior buys real goodwill and is worth building when the change allows it. It carries a cost worth naming. Customers quietly falling forward have no reason to migrate, so you will still be carrying them at the next deadline. Keep the warnings running anyway.

Warn, remind, cut over, follow up

Four messages, minimum, and the same four every time. The warning announces the change and the date. The reminders repeat it to people who have not moved. The cutover message confirms it landed. The follow up mops up whatever the first three missed.

Repetition is the part teams skip, because announcing something twice feels like nagging. It is not. Your announcement competes with every other message a busy admin got that week, and one send reaches a fraction of them. This is the same dynamic behind customers tuning out product updates they technically received, and the fix is the same, which is fewer broadcasts and more messages aimed at people with a reason to care.

Change the channel as the date gets closer. Start with the public announcement and an email to affected admins, move to in-product warnings for anyone still using the feature, and for the last stretch have account teams reach out to the heaviest users directly. Those are the accounts where a surprise turns into a renewal conversation.

Cutover day and the week after

Publish on the day, even when nothing new is happening. A short note confirming the change is live, naming what customers on the old path will see, and pointing to the migration guide closes the loop for everyone who missed the first four messages. It also gives support one link to send.

Brownouts are worth the trouble on anything with a large integration footprint. Turning the feature off for a few hours a week or two before the real date turns an abstract deadline into a visible failure, which is the only thing that reliably moves the last holdouts. Announce the windows in advance and keep them short.

Then watch for a week. Track error rates on the retired path, ticket volume mentioning the change, and any account that called the old endpoint in the final days. That last group is your call list. Most of them are not ignoring you. They lost the thread.

Sample 30, 60, and 90 day timelines

Pick the track by what you are asking the customer to do. Thirty days works when the action is a setting change or nothing at all. Sixty days fits a workflow migration a person can do by hand. Ninety is the floor when someone has to write, test, and ship code.

The 60 day version covers most feature removals. Day 1, announce to everyone and send a targeted email to accounts with usage in the last quarter. Day 15, add an in-product banner for those accounts. Day 30, remind with the migration guide and the number of accounts already moved, which lands better than a generic nudge. Day 50, reach out one to one to the remaining heavy users. Day 60, cut over and publish the confirmation. Day 67, close the loop.

Whichever track you pick, put the dates in the first announcement and hold them unless something genuinely forces a change. A date that slips twice teaches customers to ignore the third one.

The 30 day track for low impact removals

Thirty days is enough when the customer's total work is a click or a conversation with support. A deprecated setting with a sensible new default. A report type nobody has scheduled. A beta that never graduated.

Day 1, announce it in your update feed and email the accounts with recent usage. Day 15, add an in-product notice on the screen where the feature lives, the one place someone using it is guaranteed to look. Day 25, send a short reminder to the accounts still on it. Day 30, remove it and publish a confirmation.

The mistake at this length is running everything through one channel. On a 30 day clock there is no room to recover from a message that lands in a spam folder or an abandoned inbox. Two channels minimum, one of them inside the product. If enterprise customers are on the feature, move to 60 days however small the change is, because their approval process is longer than your whole timeline.

The 90 day track for API and integration breaks

Ninety days is the floor for anything a customer had to write code against, and the clock starts when the deprecation notice publishes, not when you decided internally. Their calendar has a code freeze, a release train, and a testing window in it, none of which you control.

Day 1, publish the announcement with the migration guide already live, mark the endpoint as deprecated in your API reference, return a deprecation header on every affected call so it shows up in their logs, and email every account with recent traffic on the old path. Day 30, remind, and publish the questions the guide is getting most often. Day 60, contact the remaining callers directly. Day 75 and Day 82, run short brownouts, announced ahead of time. Day 90, retire the path and confirm it publicly.

Shopify's model is worth copying if you version your API. New versions ship quarterly, each stable version is supported for at least 12 months, and consecutive versions overlap by at least nine. Customers stop guessing when the next break lands, because it sits on a calendar.

Questions product teams ask about deprecations

What is the difference between deprecation and end of life?

Deprecation is the announcement that something is going away and should not be used for new work. End of life is the day it stops working. The gap between them is the migration window, and an end of life announcement with no deprecation period ahead of it is just a shutdown notice.

Should you announce a deprecation before the replacement exists?

No. Announcing a removal with no migration path generates fear and tickets and gives customers nothing to act on. Wait until the replacement is live and documented, then announce both together so the first question after "what is going away" already has an answer on the page.

Who should own the announcement?

One named person, with the product manager who made the decision writing the first draft. Support and the account teams review before it ships, because they know which customers will react. The wider question of who owns update communication applies here with one difference, which is that a deprecation needs a single owner across the whole sequence rather than a different owner per message.

What do you do when a deprecation date has to move?

Announce the move as its own message and give the reason in one sentence. Moving a date once with a clear reason costs very little. Moving it twice teaches customers that your deadlines are suggestions, which gets expensive the next time you need one taken seriously.

Where should the announcement live?

On a permanent page you can link to, not only in an email or a chat message. A deprecation notice outlives the message that delivered it, since customers return to it during the migration and anyone joining the customer's team midway needs somewhere to catch up. Put the date, the scope, the steps, and the contact route on one URL.

Do you need a written deprecation policy?

Once you have API customers or enterprise contracts, yes. A short policy stating your minimum notice periods by change type, where announcements get published, and how you contact affected accounts turns every future removal from a negotiation into a process. It also comes up in security reviews and procurement. Put that policy in your communication plan so it is not reinvented per change.

Start the clock before you ship the change

The decision that matters is not how to word the announcement. It is committing to the date early enough that wording is the only thing left to argue about. Sort the change, set the lead time from the customer's side of the work, answer the six questions, and say it four times.

LaunchNotes can give that sequence a permanent home (public feed, email, in-app). Worth a look if warnings still live in four tools.