Why is it critical to upgrade .NET applications to a later version?
“Why change anything if it works?” If the answer to migrate or not to migrate from an older .NET version was that simple, this topic would not come up. But it constantly does. Why? Because nothing stands in its place. Things change, technology runs forward and gets better and better all the time. It becomes harder to get oldies – engineers actively familiar with older technologies, while new developers are hot on the newer tech.
Same with DevOps people, QA and support engineers, and other technical experts. And overall, the cost of maintaining an outdated, worse-performing, less cost-efficient software stack is not something an organization can wave away. So, when and how to make this decision and make it rationally?
Why change anything if it works?
This is the number one question technological and business stakeholders ask when approached with a suggestion to upgrade an application or service written in .NET some years ago. And honestly, this is a very relevant question. After all, any type of software development is a costly initiative, and it should bear good reasons to undertake any effort if you have a working application. But as usual, it is not that simple. Let’s take a look.
Now, we think the most critical differentiator in handling this question is the following one: “Do you plan to change anything in this application? Or is it purely in the maintenance mode and no software changes are planned for it?”. And based on your response, let’s review two paths here.
Applications in maintenance mode only
These are .NET applications, for which no additional development is planned. They are deployed and used by business customers and there are only two main concerns: uptime and security.
And before approaching these two topics, let’s consider the key aspect here: Microsoft .NET Support Policy.
On Microsoft .NET and .NET Core Support Policy page, we can read the following things:
“Every Microsoft product has a lifecycle. The lifecycle begins when a product is released and ends when it’s no longer supported. Knowing key dates in this lifecycle helps you make informed decisions about when to upgrade or make other changes to your software. ”
It is also important to be aware of this statement from the Microsoft .NET Support Policy page:
“Major .NET versions are released annually in November. Each .NET release is defined as either Standard Term Support (STS) or Long Term Support (LTS), at the beginning of the release.
STS releases are released in even-numbered years and LTS releases are released in odd-numbered years.
The quality of all releases is exactly the same, the only difference is the length of support. LTS releases get free support and patches for 3 years.
STS releases get free support and patches for 18 months.”
The provided information is followed by this diagram:
The next piece comes from the Microsoft .NET Framework Support Policy:
“Many products both within and outside Microsoft rely on .NET Framework. Beginning with version 4.5.2 and later, .NET Framework is defined as a component of the Windows operating system (OS). Components receive the same support as their parent products, therefore, .NET Framework 4.5.2 and later follows the lifecycle policy of the underlying Windows OS on which it is installed.“
And one more piece is taken from Microsoft Overview – Product end of support page:
“Once a product reaches the end of support, or a service retires, there will be no new security updates, non-security updates, or assisted support. Customers are encouraged to migrate to the latest version of the product or service. Paid programs may be available for applicable products.”
Takeaway: Once the .NET Framework / .NET Core / .NET version of your application reaches the end of its lifecycle, no more functional and security patches will be issued by Microsoft, and also no support will be given in case anything goes wrong. And that’s, of course, not the best case to be for mission-critical software.
It’s worth mentioning that for .NET Core 1.0 end of support was on June 27, 2019. For .NET Core 3.1, it happened on December 13, 2022, and for .NET 5, it was on May 10, 2022. At the same time, the newer LTS .NET 6 version (3 years of patching) will reach its end of support only on November 12, 2024 (source).
Our suggestion: Upgrade your .NET to at least version 6 to be on the safe side, avoid security risks and be open to receiving support if needed.
If you are looking for a reliable partner to migrate to a newer version of .NET, our team will help you to plan your successful upgrade with minimal risks, and financial and time investments.
You can also check out a case from our practice: Updating web modules written in ASP.NET Core 2.1 to ASP.NET 6.0.
Actively developed applications
And if you actively develop your .NET application or service, some other issues and problems arise when you stick to an older, outdated, deprecated, or obsolete version of it.
Availability of software developers
As it turns out, software engineers, architects, DevOps, and other technical specialists tend to be in larger abundance when you mention modern technologies. People like feeling relevant and on the edge, plus – they expect higher salaries when they show knowledge of the most modern languages and tooling.
That’s why, year after year, it will become harder and harder to find programmers, who still develop solutions using .NET Core 3.1 or earlier versions, or .NET Framework 4 and its older versions. They become an extinct species, their availability is highly rarefied and they might also be an “older generation”, who would expect higher remuneration to support an older code.
Also, these days, it is more and more acceptable to have an outsourced team of collaborative developers overseas, who either complement your in-house team or serve as the core development team for the company. And there, clearly, people also tend to strive towards more modern development stacks, so it is easier to find such a team for a newer .NET version, than for the one dead for 3 years or more.
In a brief, do yourself a favor, and invest some amount of effort to migrate your application to a modern, Long Term Support (LTS), 3-year lifespan .NET version, like .NET 6. It would make it substantially easier to find relevant developers and also bring your development stack to a higher level, which is known to increase developers’ productivity, team velocity, and overall quality of the code.
Ease of finding answers and samples
Here we have a very interesting question: is it easier to find answers and samples for coding needs when you’re looking for these things for an older or newer .NET version?
On the one hand, of course, if you’re dealing with Release Candidates, like it was in the case with .NET 7 just a few months ago, probably it would be harder to find answers when anything goes wrong. But closer to the release, and thanks to the open-source nature of the .NET Core framework, the number of answers, tutorials, sample codes, and StackOverflow threads explodes.
For example, let’s take a very interesting .NET 7 feature – the ability to call an existing .NET library from React code running in the browser. If you follow the link, you will see a great community contribution of code samples and GitHub projects:
All the trials to find a code sample or assistance from the community for something happening in .NET Core 2.0 or .NET Framework 3 would most probably result in frustration and failure to reach the set goal.
Performance, performance, performance
When reviewing the “What’s New” sections of different .NET versions, it became obvious that from version to version, Microsoft and the open-source community worked hard on making .NET more and more performant.
Just let’s have a look at the major versions:
What’s New in .NET Core 2.0 – 9 occurrences of Performance, including Build time speed-up, incorporation of a new JIT compiler technology called tiered compilation (also known as adaptive optimization), state-of-the-art cryptography hashing RFC2898 15% performance improvement, significant socket performance increase.
What’s New in .NET Core 3.0 – also 9 occurrences of Performance improvements. Among them, we should mention now default JIT tiered compilation, ReadyToRun binaries improving startup performance, Garbage Collection Large Page support, added APIs that allow access to certain perf-oriented CPU instructions, and new built-in high-performance JSON support.
This is followed by .NET Core 5 performance improvements, including Garbage Collection (GC), System.Text.Json, System.Text.RegularExpressions, Async ValueTask pooling, Container size optimizations, and others.
And one more version here is .NET 6, which states to be the fastest full-stack web framework that lowers compute costs if one is running software in the cloud. A list of these improvements can be found in this Performance improvements in .NET 6 blog post.
A second glance at .NET 6 What’s New shows yet another plethora of performance enhancements, with statements like “Performance is a key focus of .NET 7, and all of its features are designed with performance in mind”. Read the Performance improvements in .NET 7 blog post for getting more details.
I hope the overall conclusion is clear: A business that wants to be on par with its competition, spend less on expensive hardware, and be wide open for an explosion of usage, should heavily review its commitment to developing using the most state-of-the-art performance technological stack. In short – move at least to .NET 6.
Support of modern cloud technologies
One additional, but in my opinion critical, aspect of the modern application stack is all about developing cloud-native, containerized, easily scalable, and highly performant services and applications. The keyword here is “Containers”.
Any company developing a Software-as-a-Service or a Cloud-hosted application oriented to high parallel execution by thousands if not millions of users strives toward developing containerized, scalable services, be it pure Microservices Mesh, or independently deployable services in a Service Oriented Architecture.
And here is where .NET Core goes very much in the right direction. There are so many advancements in support for .NET on Linux and Windows containers, in x64 and Arm64 processors, with more and more precise and efficient resource management, that it is hard to list them all.
The screenshot below demonstrates the number of references (22 to be precise) to the term Container in .NET 6 What’s New:
And in .NET 7.0 the count even rises (29):
Last, but not least is observability. Modern services and applications, having a multitude of individual components and distributed calls path, require sophisticated health monitoring, performance observability, and APM (application performance monitoring) support. Modern versions of .NET Core can help us with this.
For instance, .NET 7 added support for OpenTelemetry:
“The goal of observability is to help you better understand the state of your application as it scales and the technical complexity increases. .NET has embraced OpenTelemetry while also making the following improvements below in .NET 7…”
Conclusion: If the company is serious about deploying its highly scalable containerized application to the cloud to ensure growth and cost efficiency, the .NET modernization becomes a must.
by Alexander Stern, senior content contributor at Amberteq