When tasked with maintaining a legacy application you will, undoubtedly, have to make some difficult compromises: for example, which features should you continue to support and which ones are more hassle than they are worth.
Decommissioning is the process of completely removing a feature or system so that it no longer needs to be maintained. If you have a feature you want to get rid of, the following steps might provide some useful touchpoints in the process.
This post has been forged from my own experiences in decommissioning features in legacy Rails apps, however, most of the steps are really system- and framework-agnostic and will readily apply to other decommissioning projects.
Why bother to decommission a feature?
You have a feature that has become periphery to the main application focus. Some of your users continue to make use of it, but the vast majority don't, and are possibly unaware of it. Why bother to decommission this feature? Undertaking a feature decommissioning is no small task, so committing time and resource to this type of project can often be met with business resistance. So why should we consider it at all?
Discussions about a potential feature removal will often be met with responses such as:
- Some people use it.
- It might be useful down the line.
- We don't have to do any work on it.
- It doesn't cost us anything.
- Can't we just leave it where it is?
These represent some of the legitimate arguments against removing an existing feature, and often they provide sound reasons for not pushing ahead with the decommissioning. However, they can also be used as convenient excuses for not making the difficult but correct decision to decommission.
Usually these anti-decommissioning arguments fail to take account of a number of pertinent factors in the decision-making process:
- The code still needs to be maintained. Any software upgrades, security patches etc. will have to be applied to this existing feature. A particular tricky manifestation of this is when the feature has third-party dependencies which are, themselves, upgraded or deprecated. In such circumstances it can take significant effort just to keep the feature functioning as it was before … running to stand still.
- The feature will still need to be tested in any regression suites. Bugs can potentially surface in this feature on accout of changes elsewhere, e.g. in shared modules. And if these bugs arise, you are still going to fix them, right?
- There is a support cost. Whilst the feature is still available in the wild user support requests will continue to come in. This could potentially drain support resources and/or development resources.
- Any feature that continues to be supported adds some level of cognitive load to the engineers maintaining the system, not to mention new team members becoming acquainted with the system. At best team members can make a conscious effort to ignore the feature. At worst they find themselves actively working around it.
But when is decommmissioning the correct decision? That depends on the specifics of the feature under consideration, how it integrates with the service as a whole and the future business direction for the product. I discuss some of these considerations in greated depth in step 1.
The starting point
As a starting point for these discussions I will make a number of assumptions.
- You have identified a candidate feature for deletion.
- The ultimate goal is to completely remove the feature. If you need some form of restricted access into the future, or access for a subset of users, then you are dealing with a different problem.
- There are no ongoing regulatory reporting requirements assocaited with the data. Again, this case will require alterations to this approach. In particular, how you intend to store and access the legacy data will need to be planned in advance.
Decommission in 10 steps
1. Evaluate feature marked for decommissioning
As already mentioned, you should always start by making an honest assessment of the feature under consideration. At a basic level these three questions can clarify your thinking:
- What level of usage is the feature experiencing? E.g. how many users are making use of it, and how often?
- What is the impact on these users if the feature was to be removed?
- What is the on-going maintenance cost of the feature?
2. Establish removal timeline
With the decision made to decommission this feature, you will need to agree a timeframe, internally, for this removal. Depending upon the feature it may make sense to withdraw the feature in stages.
Staged by access to functionality: For example, you remove the ability to create or update entities on a set date, but users retain the ability to view and export their entities until the final sunset. The idea here is that this decommissioning schedule shepherds existing users away from their use of the feature.
Staged by user cohort: For example, new users will cease to have access to the functionality from an initial date. Next the feature could be withdrawn from existing users who have not been using the feature, or have not used it recently. A final date is then set to remove access to the feature for all users, including those who have been actively using it the feature. The main idea here is to try and ring-fence the users who are actively using the feature (impacted users) and avoid other users adopting the feature and expanding this cohort.
3. Identify impacted users
With an internal plan for how and when the feature is due to be decommissioned, you should try to get a picture of the users who will be most impacted by the feature removal. This will usually take the form of a report listing the user name and email amongst other details. This list will be used in step 5, when we directly communicate the decision to these users. Deciding which users are 'most impacted' is a question of judgement. You might want to consider all users who have used the feature ever. Alternatively you might want to limit to users who have used the feature recently (e.g. within the last N months), or where they have used the feature to a certain threshold level (i.e. if they have created more than N entities). In any case this set of impacted users needs to be much less that the number of users of your system. Again, if this is not the case, why are you removing the feature?
Staging the decommission by cohort can be useful here, as it can help you to firm up on this list sooner - as you have confidence that no new users will enter this cohort of impacted users. In any case you might want to regenerate this report again later in the process to check that no other users have come into scope. If they have you may wish to contact them individually to communicate the changes.
4. Publish timeline to users
Hopefully things should be making sense internally now, and the decision to decommission should feel like the right move. Provided there are no last-minute changes of heart you should go ahead and share the decision with your users, including your proposed timeline for the feature removal. Choose whichever channel works best for your business: perhaps via a blog post or email, or share the news via your company social channels (Facebook, Twitter, LinkedIn etc.). You want to choose whichever combination gives you widest reach to your users.
You might expect some feedback at this point, most likely unhappy users. Whilst it is not what you want to hear, if you are comfortable in the decision to remove the feature then you should be able to deal with this type of (totally expected) reaction.
There might be temptation to do decommissioning-by-stealth. A decommissioning announcement seems like such a negative thing. But it doesn't have to be: the message should focus on how this decision was a necessary one to allow the product to grow and improve. You may wish to tie the news in with some new feature announcement. Helping to emphasise that the decommissioning is all part of a general growth or evolution of the service. My advice would be to get your message out there as wide and as early as possible. As much as some users will be pissed off to learn that their favourite feature is being canned. They will be infinitely more pissed off if you do it without giving them adequate prior warning.
5. Direct communication with impacted users
Using the list of 'most-impacted' users which you generated in step 3 you should now send a direct communication to these users to explain the decision made and how this will impact them. Email will probably work best here. This communication should include a little more technical detail than the general communication you have sent out in the previous step. In particular, this communication should provide details of
- How the user's interaction with the feature will change, and when.
- Any workarounds that are available on the platform (or elsewhere) to mitigate the impact of the decommissioning.
- How the user can extract/export their data in advance of the final decommmissioning date.
- Perhaps an offer of additional support to help in the transition.
6. Implement removals as scheduled in step 2
Just stick to the timeline agreed in step 2 and published in step 4. The code and infrastructure changes required at each phase of the timeline can (and should) be prepared well in advance of the dates, to allow time for proper testing of the changes before their individual release.
If you have opted for a phased decommissioning I would generally advise to switch off access to features at each stage, but keep the underlying data until you have completed the feature decommissioning.
7. Remove all access on scheduled date
On the agreed decommissioning date all access to the feature should be removed. Unless there are other pressures to have the feature removed sooner, it can be good form to leave the feature in place for a short period (e.g. a week) after the published decommissioning date. This delay should give any laggards a final opportunity to get there affairs in order before access is removed.
This deployment should really just be a removal of the feature from the code base, and the supporting data should remain in place at this point. As such it should be relatively easy to roll this change back, in the event that you have completely misjudged the impact!
8. Snapshot data for long-term storage
The long-term handling of the data will be dictated by the type of data you are holding for this feature.
Some financial or contract data may need to be held for a number of years. You may wish to hold some of the data for your own processing going forward. If the data has any personally-identifiable information relevant privacy laws may dictate that the easiest thing for you to do is to permanently delete the data.
Regardless of what the long-term future is for this data, I would advise taking a snapshot at this point. This snapshot will serve as a further safety net over the next few weeks, in case the feature removal had some unintended consequence and needs to be rolled back.
You should hold this snapshot for a number of weeks/months, until you feel that the feature removal has been properly digested by your users. After this point, if you have no further use for the data, you should delete it permanently.
9. Complete removal of feature data
After taking the snapshot of the data you should complete the removal of the feature by running any database schema migrations required to delete the data and update the schema.
Whilst it really should not get to this point, but if you do become aware of a critical problem with the feature removal you should be able to work on restoring the feature, starting from the data snapshot taken in step 8.
10. Enjoy life without the burden of an unloved feature
Now that the feature has gone and support issues have died down (hopefully!), you can can focus on how to drive your project forward, without the unwanted baggage.
Good Luck