Part IV After launch: operations, further development, independence
Chapter 23: Technical debt and system aging
Technical debt arises from shortcuts and postponed modifications to the code. It saves time today, but every further change then takes more work. You can recognize it without reading the code: for example, when comparable changes cost more and more, and parts that used to work fine stop working after deployment. Pay it down continuously, and when the system ages, modernize it piece by piece.
Debt works like a loan
Technical debt is like buying on a credit card. You get the thing right away, but until you pay off the debt, you pay interest. In software, a shortcut might be a missing test, copied code, or a postponed update. The interest is the extra time needed for every further change.
Debt in itself is not a mistake. A deliberate shortcut to meet a deadline is a legitimate decision. The problem is debt that nobody knows about and nobody pays down. McKinsey describes the interest as a complexity tax that every project pays. In a survey, IT leaders of large companies estimated that 10–20% of the budget for new products is consumed by dealing with debt instead, and 60% of them feel that debt has grown over the past 3 years McKinsey, 2020. These are the respondents’ estimates, not direct measurements, but they still point to the scale of the problem.
How to recognize it without reading the code
The best yardstick is in your invoices: how much a comparable change costs today and how much it cost a year ago. Other symptoms are bugs after deployment in unrelated parts, modules that nobody wants to get into, and deployments “over the weekend.” Ask the vendor for DORA metrics DORA, metrics (chapter 17), static code analysis results, test coverage, and the age of components in the regular report. Do not track only the absolute values; also focus on how they develop over time.
How to pay down the debt
- Record: the vendor keeps a record of the debt as a list of tasks with an estimate of how much extra work the individual shortcomings cause.
- Permanent capacity: devote part of every sprint to paying it down, instead of a one-off cleanup campaign every few years. Concentrate the capacity where the system changes the most.
- Boy Scout rule: whoever touches a module leaves it a bit better than they found it.
- Contract: “done” also means tests and documentation, and acceptance includes a code quality check (chapter 20).
- Budget: paying down debt is an item in the annual maintenance budget (chapter 22).
Refactoring, rewrite, or replacement?
A system becomes obsolete when running and changing it costs disproportionately much, its technology has lost support or you cannot find experts for it, and the system cannot handle new requirements, such as round-the-clock operation or integration through an API. Age alone does not decide. But a platform’s end of life means a mandatory and expensive migration: the State Agricultural Interventional Fund (SZIF) has support for its platform secured only until 2027, and the Supreme Audit Office (NKÚ) has pointed out the risk of further high expenditure NKÚ, audit conclusion KZ 20/07. So for every key component, track its end-of-life date and have a plan for what comes next.
| Refactoring | Incremental replacement | Big rewrite | Off-the-shelf product | |
|---|---|---|---|---|
| When | the architecture does not prevent changes, the platform is supported | the platform is nearing end of life, or modules cannot be changed | a small system with few integrations | the system does nothing that sets you apart |
| Risk | low | medium, spread over small steps | high for large systems | a new kind of dependency |
| Extra cost | permanent capacity | parallel running of two systems and data synchronization | parallel development of the old system | data migration, process changes |
| Trap | one-off campaigns | no date for switching off the old system | loss of the knowledge in the old code | custom modifications to the off-the-shelf product |
The default choice is refactoring. Even when a rewrite is unavoidable, plan it piece by piece.
Incremental replacement is known in the trade as the strangler fig, after the fig tree that gradually grows around an old tree until it replaces it Fowler, 2004. The new system takes over one function after another until the old system can be switched off. The steps are small and reversible, you see the benefits along the way, and you can change vendors piece by piece. For a while, however, you pay for two systems. A prerequisite is access to the old system, its interfaces, and its data (chapter 24).
A big rewrite all at once is tempting because it promises a clean slate. With large systems, however, the knowledge stored in the old code gets lost, requirements change in the meantime, and the old system has to be developed in parallel. Large-scale modernization takes years: of the 10 critical federal systems that the US Government Accountability Office identified in 2019, three had been modernized by February 2025 GAO, 2025. A switch-off plan and a budget for parallel running therefore belong in the project from the start. The MZV case in chapter 4 shows what happens without them.
Basic registers: a critical system with 2012 parameters (NKÚ 2024)
The basic registers cost almost CZK 1.8 billion to acquire and another CZK 2.46 billion in 2015–2022, of which CZK 1.76 billion went to operations and CZK 697 million to further development and renewal. The transformation under the ZR 2.0 Concept (Koncept ZR 2.0), with deadlines in 2019–2023, did not materialize, and even expenditure of CZK 67.9 million did not lead to a complete renewal of the infrastructure. Round-the-clock availability had still not been ensured more than 4 years after the deadline, and operation in 2023 matched the parameters of 2012. According to NKÚ, 4 of the 5 registers are dependent on their vendor NKÚ, audit conclusion KZ 23/05. The Ministry of the Interior (MV) disagrees with the conclusions and states that the registers run without downtime MV, June 10, 2024.
The lesson: without a planned and tendered renewal, a system ages even with hundreds of millions a year spent on operations.
Source: NKÚ, audit conclusion KZ 23/05, MV, statement of June 10, 2024
| How it goes wrong | How to do it right |
|---|---|
| How it goes wrongDebt is dealt with “when there is time.” | How to do it rightDebt is recorded with an estimate of the interest and has permanent capacity. |
| How it goes wrongA one-off cleanup campaign every few years. | How to do it rightContinuous repayment and the Boy Scout rule with every change. |
| How it goes wrongYou know only what the vendor tells you about the health of the system. | How to do it rightDORA metrics and static analysis in the report; you track the trend. |
| How it goes wrong“Done” means that the feature runs. | How to do it right“Done” includes tests and documentation, and acceptance includes a code quality check. |
| How it goes wrongThe old system is rewritten all at once and switched over during a weekend. | How to do it rightIncremental replacement with a switch-off date and a budget for parallel running. |
| How it goes wrongThe platform reaches end of life, and only then is the crisis dealt with. | How to do it rightEnd-of-life dates for all components and a transition plan well in advance. |
- For a public authority, poor-quality and undocumented code also has a legal dimension: it makes it impossible to run a tender for another vendor, and the dependency deepens (chapter 24).
- Modernizing a designated information system is an architectural change and needs a positive opinion from the Office of the Chief Architect of eGovernment (OHA); see chapter 12.
- Put the renewal out to tender well in advance. In the case of the basic registers, NKÚ assessed extending contracts with the original vendors without a tender as a risk to economy (value for money) NKÚ, audit conclusion KZ 23/05.
- The renewal and modernization plan belongs in the authority’s information strategy (informační koncepce) Decree No. 360/2023 Coll..