Maintenance Matters: Timely Upgrades
In this entry of our Maintenance Matters series, we'll cover the importance of timely website upgrades.
This article is part of a series focusing on how developers can center and streamline software maintenance. The other articles in the Maintenance Matters series are: Continuous Integration, Code Coverage, Documentation, Default Formatting, Building Helpful Logs, Code Reviews, and Good Tests.
As Annie said in the series introduction article:
Upgrades can only be put off until they can't. It can be hard for someone whose main concern is functionality to prioritize time for invisible changes like keeping dependencies and tool versions updated. But these tasks are important for the health of a codebase, and it often falls to developers to make time for them.
Supporting a complex website for the long haul takes work. Not a ton of work, but creating a digital product is a major investment that is best served by a certain amount of routine upkeep. For most websites, that means regular software updates for servers and application code. This is important, even if you're no longer adding new features! How important are they? Prioritizing timely upgrades has at least three key benefits:
- Staying Secure
- Improving Performance
- Preserving Development Experience
Timely upgrades mean better security. Why? Hackers often exploit out-of-date code to gain unauthorized access to applications. Sites that don't receive regular updates are vulnerable to common attacks using publicly-disclosed vulnerabilities as entry points. Luckily, you don't have to be a leading security expert to stay current. Regular updates go a long way.
To reiterate, staying on top of security updates is critically important. If you’re going to focus on one thing in this article, this is it.
Keep your programming language versions current. If that version is no longer getting security patches, it's past time to upgrade!
Follow major framework releases that your site(s) depend on, like Rails or Django, and upgrade promptly.
Take advantage of well-known tools, like Dependabot, that can issue PRs for insecure packages in your GitHub repositories. These tools can be noisy, but in a lot of cases, the output is worth sifting through.
Can regular software updates make your product faster? In a word, yes. Performance is an evergreen development goal. Successful projects, like the libraries and frameworks you depend on in your app, prioritize performance over the long haul and it's pretty cyclical over time. Programmers write code, measure the performance in different environments, and optimize as needed. You stand to benefit from optimizations when you make regular updates.
To be fair, not every update is a notable performance improvement. For those that do boast performance improvements, the optimizations may not be all that perceivable, especially in isolation. Every little bit helps, though.
When you find a performance issue in a dependency, subscribe to the relevant issue(s) in the project's issue tracker. When it's resolved, you'll be notified so you can apply that performance optimization as soon as it becomes available.
Consider tracking your performance metrics over time. If you’re disciplined with your releases, you can use those metrics to measure the impact of your software updates in isolation.
Preserving Development Experience
In the software world, things move pretty fast. If you put off upgrades for too long, eventually you'll find yourself with a development environment that no longer does what it needs to do. Maybe a package manager is deprecated and no longer adds new packages. Or a remote dependency has been removed without warning (:scream:), and you can no longer install or add packages. Stuff happens! When you get to this point, though, you may have a pretty significant blocker on your hands. Depending on the issue, deployments could be off the table. Resolving the issue will become a top priority, which may or may not fit into your scheduled plan for the day/night/weekend.
Upgrading to new features
Last, but certainly not least, upgrades bring exciting new features. Giving project developers access to the latest and greatest encourages good habits for long-term maintenance and keeps things running at peak efficiency.
Need an example? Let's imagine we have a developer working on two different projects. Projects "Alpha" and "Bravo" use a similar tech stack. Project Alpha is in long-term maintenance, while Bravo is in active development. A few weeks ago, on project Bravo, our developer used a newly-released framework feature—let's call it "Doodads"—to build something new. Doodads ended up being easy to work with and the task took less time than expected. Now, fast forward to this week. On Project Alpha, our developer has been asked to build something similar. Unfortunately, Alpha has a significantly out-of-date version of the same project and Doodads is just out of reach. It's a morale hit for our developer, sure. More importantly, on Alpha, it will take more time to do the same task.
Keep an eye on new package manager releases. For major releases, look for upgrade guides that are often published right after major versions become stable, then use those for a smoother process.
Don't ignore warning text and similar notices from your development console or continuous integration services. If something is going to stop working soon, make a note in a ticket and prioritize the switch.
Consider prioritizing large framework updates that provide new features, even if you don't have any immediate plans to use them. At some point, you're probably going to want one (or more) of those on hand.
Prioritizing timely upgrades cultivates a product that is inherently more secure, performant, and maintainable over time. If your team doesn't already have an internal process for performing timely upgrades, why not?
The next article in this series is Maintenance Matters: Code Reviews.