Modernization Explained: What Changes and Why
Modernization is a change made for a reason
Modernization changes an existing system and its surrounding practices so that they better meet current or anticipated business, technical, and operational needs. The change might improve supportability, reduce a recurring failure, enable a required integration, or make a process easier to operate. Migration moves something from one place to another: data, with its meaning intact; a workload, to a different runtime; or users and integrations, to a different system. A migration can be part of modernization, but moving the same fragile process to a different server does not fix it, and modernization does not always require a cloud move or a full rewrite. Sometimes the right change is better maintenance of what already works.
Consider a fictional purchasing service. Its order database still records orders and goods receipts reliably. Each morning a reporting job reads that database and produces the invoice-evidence report that clerks use to match invoices before approval. The reporting job runs on software the supplier no longer supports, fails several mornings a month, and only one employee knows how to recover it. The database meets its service, change, security, and support conditions; the reporting job does not. Replacing the reporting path therefore addresses the actual problem, while replacing the database would move risk into the part that works. The retained database still carries dependencies the change must respect: the reporting job reads its order and receipt tables through a service account, a nightly export feeds finance, an approval workflow writes status back to it, and a month-end reconciliation report runs against it.
Age alone does not make a system legacy. The GOV.UK guidance on managing legacy technology describes legacy technology as systems and processes that are end-of-life, out of supplier support, impossible to update, no longer cost-effective, or above the acceptable risk threshold. By those criteria the reporting job qualifies on support and risk; the older database does not qualify at all. Ask what a system can no longer do safely, how hard it is to change, what depends on it, and what happens when it fails, rather than counting its years. This article uses a fictional example to explain decisions and continuity, not a prescription to move every workload to a particular platform.
Name the benefit and the thing that must survive
Start with the problem and a way to observe improvement, with a baseline, a target, a measurement period, and an owner. For the fictional reporting path: over the last 60 working days the job failed on 7 mornings, the median recovery took 95 minutes, and one person performed every recovery. The service owner sets targets for the first 60 working days after the change: at most 1 failed morning, recovery within 45 minutes by either of two trained operators, and the report available by 08:00 on at least 58 of the 60 days. These figures are invented to show the shape of the agreement. A successful deployment is evidence that software was delivered; it does not establish that any of these outcomes improved, so the operations lead measures them after the change and reports them to the owner.
Measure where the work went, not only where it left. If the new report arrives on time because a finance clerk now corrects the export by hand each morning, the reporting team’s improvement is someone else’s new task. Record the minutes moved to other teams on the same days, and treat an increase as a condition that blocks a success claim rather than as a footnote.
Also state the obligations that continue through the change: authorized users can get the records they need, order identifiers retain their meaning, historical evidence remains accessible under its retention rules, and approvals are not duplicated or bypassed. These are continuity requirements. Some require uninterrupted service; others may permit a planned pause or a limited manual process. Agree on the actual tolerance instead of assuming zero downtime is always possible or necessary.
Choose how much to change
| Choice | What it changes | Question before choosing it |
|---|---|---|
| Retain and improve maintenance | Keep the working system; strengthen support, monitoring, documentation, or controls | Can it meet requirements at acceptable risk, and when will that judgment be reviewed? |
| Retire an unused capability | Remove a function and its operating burden | Have all users, dependencies, and retained-information needs been checked? |
| Move the runtime | Change where the workload runs while preserving much of its behavior | Which problem does the move solve, and which fragility remains? |
| Replace a component or service | Substitute a reporting engine, scheduler, database, or purchased application | Can interfaces, data meaning, permissions, and operation remain compatible? |
| Redesign the workflow | Change how work, data, and responsibility are organized | Which behavior must be preserved, and which differences are deliberately approved? |
These are choices to combine, not a compulsory sequence. The purchasing service might retain its order database, replace its reporting job, and retire an unused export. GOV.UK’s guidance lists options in its own words, such as retain, retire, re-host, repurchase, and re-platform; suppliers publish similar lists with more or fewer entries. Treat any such list as a vocabulary for describing a decision, not as steps every system must climb. A smaller change reduces transition scope but may leave expensive dependencies behind. Compare the expected benefit with the cost of running two paths for a while, the risk of changing, and the risk of staying, including the non-technical parts: who must be trained, who owns the new path, and which operating procedures change. Retaining a system should have an owner and review conditions rather than becoming an indefinite unexamined default.
The change reaches beyond application code
Map the current system before deciding what can move independently. Include source systems, scheduled jobs, stored procedures, files, dashboards, exports, service accounts, and people performing manual steps. Ask users about infrequent work such as month-end reporting; recent traffic alone may miss a dependency that runs only occasionally. A dependency is anything that needs another component’s data, behavior, availability, or decision. Recorded data lineage helps find consumers, but an absent edge does not prove that no dependency exists, so confirm important consumers with their owners.
Preserve meaning as well as bytes. A timestamp stored as local time without its zone may be read as a different hour; an order status may be mapped to the wrong category; an amount kept with four decimals may be copied into a two-decimal column and change a total; a new join may duplicate invoice lines. A technically valid copy can therefore change a report. Record identifiers, types, precision, time rules, relationships, and business definitions, and carry the rules that travel with the rows: who may see each record and how long it must be kept. If a definition should change, treat that as an explicit business change with an owner, an impact review, and a stated expected difference, so that it is not mistaken for a defect later.
AI applications add derived state: document chunks, search indexes, embeddings, prompts, evaluation cases, and model dependencies. Copying documents alone does not recreate the same retrieval behavior. If the embedding model changes, the documents must be re-embedded and the index rebuilt, and queries must be encoded in the way the new model defines as compatible with its document vectors. Some retrieval models encode queries and documents through different prompts or paths by design, and that is fine as long as both land in the same vector space; what does not work is mixing vectors from an incompatible model. A matching vector length does not make two models’ vectors comparable, and OpenAI’s documentation even lets one model’s vectors be shortened to a chosen length, so equal dimensions can hide different spaces. Rerun the evaluation cases before trusting the new index. Keep three access questions apart: what the ingestion account may read from sources, what each end user is authorized to retrieve at query time, and how a deletion at the source is propagated into chunks and indexes. Operations also change when a different team owns alerts, credentials, deployment, or recovery.
Coexistence needs an authority rule
A cutover is the transition of live work to the new path. Before it, old and new paths may coexist. In a shadow comparison, the new reporting path consumes the same agreed inputs and produces a candidate report while users continue to use the old approved report. The shadow path must not send notifications, grant approvals, or execute transactions, or the comparison itself creates duplicate real actions. Specify which system is authoritative for each kind of record and action at each stage. In this example the order database stays the authority for every order and receipt throughout, because the change replaces a read-only reporting path and nothing new writes to order data. That is what makes the change lower-risk than replacing a system that accepts transactions.
Stage 1 - coexistence (order database is the authority for all records; the new path never writes back)
agreed comparison point: snapshot at 06:00, or changes applied up to position N
├─ old reporting path → approved report → users, notifications
└─ new reporting path → candidate report → comparison only (no notifications, no write-back)
Stage 2 - after agreed checks and cutover approval
order database → new reporting path → approved report → users
old reporting path: kept read-only for the defined recovery period, then retired
Writing “same snapshot” on the diagram does not make the two reports comparable. Both paths must have read the same data position: either the same frozen snapshot, or changes applied up to the same agreed position such as a change data capture offset. If the old job read at 06:00 and the new one at 06:20, a difference may be twenty minutes of new receipts rather than a defect. AWS documents the same constraint for its migration validation: rows that are continuously modified during comparison cannot be validated. Freshness is then a separate check: does the new path deliver, by 08:00, data as of the agreed cutoff?
Suppose instead that the scope were the order-entry system itself, so that the new system accepts orders and updates. Two writable systems are much harder than two report copies. First assign write authority by record or group of work. For data that must remain available on both sides, every accepted insert, update, and delete after the initial copy must propagate in the agreed direction; synchronization lags; the same order can be changed in both places; and a retried transfer can apply the same change twice unless the transfer is idempotent. Dual writing does not provide consistency by itself, because one write can succeed while the other fails, and change data capture provides access to changes, not a guarantee that every destination applied each one exactly once and in order. If each group has only one writer, enforce that boundary; permit both systems to update the same record only with an explicit conflict rule. Define the identity rule, ordering, delete handling, and reconciliation before the first record moves.
A phased transition moves bounded groups of work, but cross-group dependencies still need handling. A single coordinated switch may be appropriate when partial operation cannot be made consistent. Neither approach is universally safer. Choose according to how well groups can be isolated, how data changes flow between them, how much interruption is tolerated, and the team’s ability to observe and recover. Budget for the temporary cost and operational complexity of running both paths.
Validate business continuity before switching
Use the same source scope and comparison point when comparing results. Row counts and totals are useful checks, but equal totals can hide swapped values, replaced keys, or offsetting errors. Suppose the old report lists invoices 1001, 1002, and 1003 for \$120, \$80, and \$200, a total of \$400. A new report listing 1001, 1002, and 1003 for \$120, \$200, and \$80 has the same count and the same \$400 total with two amounts swapped; a new report listing 1001, 1002, and 1004 for the original amounts also totals \$400 while 1003 is missing and 1004 is unexpected. Comparing identifiers, then values by identifier, finds both. This is reconciliation against an agreed reference: compare keys, important fields, relationships such as each invoice’s link to its order, permissions on restricted rows, freshness, and the user-visible outcome that a clerk finds the evidence. Test access, peak behavior, and failure handling too. A migration is not validated because the new database accepts a query.
Distinguish an intended difference from a defect. If the old report omitted an approved order status, reproducing it exactly preserves a bug. Document the corrected definition, the expected difference, the affected history, and the approval instead of treating every mismatch as acceptable. The source data and the approved requirements are the basis for correctness; the old system is a comparison point, not an infallible oracle.
Rehearse the cutover with realistic data volumes and a timed runbook, then decide with stated go/no-go criteria and a named decision owner. For the reporting path, an illustrative runbook and its criteria look like this.
Cutover runbook (reporting path) - decision owner: purchasing service owner
Step Time Action Owner Evidence that closes the step
1 05:30 Confirm no schema or job changes are pending on the database operations lead change-calendar check recorded in the cutover log
2 06:00 Record the comparison point: snapshot time or change position N
operations lead position written in the cutover log
3 06:05 Run the old and new paths against that point reporting engineer both run logs with row counts attached
4 06:40 Compare keys, amounts by key, invoice-to-order links,
restricted rows, and run duration data owner comparison report with every difference classified
5 06:50 Go/no-go: zero unexplained key or amount differences;
approved differences documented; recovery rehearsal completed
this week; both trained operators on duty today decision owner signed go/no-go entry
6 07:00 Go: redirect users and notifications to the new report;
keep the old job runnable with notifications off operations lead redirect confirmed; old job status logged
7 08:00 Verify the report reached users by the deadline service owner delivery evidence and user confirmation
Before 07:00: any unexplained difference or failed step is a no-go - keep the old report, retry another day.
After 07:00: a failure is an incident, not a no-go - notify users and the decision owner, stop further changes,
start the 45-minute recovery clock at detection, and apply the tested rollback to the old report
or the controlled repair of the new path, whichever the recovery plan names.
A missed 08:00 deadline is recorded as a separate event from a failed job run.
Each step names the role that acts and the record that closes it, so a reviewer can later see that step 4 was a classified comparison report rather than a verbal “looks fine.” Step 4 checks how long the new path takes to run; step 7 checks the business deadline itself. In this example, the 45-minute recovery target starts when a failure is detected and ends when a usable report reaches users. Record the failure onset, detection, and restoration separately: a failure at 06:30 detected at 06:50 and recovered at 07:35 meets that 45-minute target but spans 65 minutes from failure to recovery. The service owner must also check that full interruption against the business tolerance. Whether the 08:00 deadline was still met is recorded separately, so a failed job run and a missed deadline are two events rather than one. The criteria are agreed before the rehearsal, not adjusted on the morning to admit a result. A rehearsal that reveals a step nobody can perform in the allotted time is a success of the rehearsal, not a reason to skip it.
Recovery is more than switching the path back
For the reporting path, rollback is comparatively simple: point users and notifications back to the old report. It works only if the old job can still run, its service account is still valid, and its output is still trusted, which is why the runbook keeps the old job runnable during the recovery period. Even here, rollback does not unsend a notification that the new report already triggered.
For the broader scope in which the order-entry system itself was replaced, rollback has to answer harder questions. What happens to orders created, updated, or deleted in the new system since the switch? Which external effects, such as confirmation emails sent, approvals granted, or payment requests issued, have already happened and cannot be reversed by restoring data? Returning to the old system without carrying that work back discards valid business activity. Define the point beyond which the tested rollback procedure can no longer preserve accepted work and external commitments. For example, external use of new identifiers rules out rollback if the old system cannot preserve or map those identifiers; external use alone does not make rollback impossible. Plan forward recovery for that case: keep the new system authoritative and repair it in place with controlled, reviewed corrections rather than attempting a return.
A backup is not a recovery. Google’s reliability engineering guidance puts it plainly: what people actually want are restores. Two agreed conditions describe what a restore must achieve. The recovery time objective is how long the service may be in recovery before the business is harmed; the recovery point objective is the point in time to which data must be recovered, which fixes how much recent work may be lost. In the fictional example, 45 minutes is the recovery time target for the report, measured from detection of the failure to a usable report reaching users, not to files being restored. A replaced order system would need a recovery point objective stated as an allowed loss, for example no more than five minutes of accepted orders before the failure. “The last completed synchronization” is then the recovery position actually achieved, and it meets the objective only if that position lies within the five minutes; if synchronization had stopped an hour before the failure, the last completed sync is a failed objective, not a lenient one. The report’s 06:00 cutoff is the data scope the report needs, which is different from the loss tolerance on the source transactions. Meeting one objective says nothing about the other. Test the restore, verify the recovered data position against the objective, and confirm access to the restored service before relying on any of it.
Retirement is part of completion
After cutover, keep the old path only for an explicit purpose and duration. After the stabilization period, confirm that scheduled jobs, exports, users, and downstream systems no longer depend on it, that retained information has a permitted archive or replacement access path under the retention rules that apply to it, and that the recovery conditions no longer require the old job. Test that retained records can actually be retrieved through the replacement path with the required permissions and context. Then remove accounts, credentials, jobs, licences, routes, and resources dedicated to the retired path. For shared resources, remove only the old path’s access or allocation after confirming what the retained services still need. Stopping the main application while its copies, jobs, and charges remain is incomplete retirement. Retiring a system is not the same as deleting its data: records under a retention obligation stay accessible for as long as that obligation requires, in whatever archive the organization has approved.
Check the original outcomes after stabilization. Were morning reports available by the deadline on the agreed number of days? Did failures fall to the target? Can a second operator recover the service within the time objective? Did support burden fall after temporary coexistence ended, without moving work onto another team? Record new limitations and remaining costs. Training, ownership, monitored controls, and planned upgrades keep the new environment maintainable; otherwise the organization can reproduce the old problem with a newer product.
1. Old and new reports have the same total invoice amount. Is the new report ready to replace the old one?
Solution
Not from that fact alone. The swapped-amount and replaced-key examples above both keep a \$400 total. Check that both reports used the same source scope and comparison point, then compare identifiers, amounts by identifier, invoice-to-order links, approved definitions, permissions, freshness, and the user outcome. Cutover also needs operating and recovery evidence under the agreed go/no-go rules.
2. In the broader scenario, the new order-entry system has accepted orders and updates for a day. The team proposes rollback by redirecting users to yesterday’s old database. What is missing?
Solution
A plan for everything that happened since the copy: new orders, updates, and deletions in the new system, conflicts with any changes still made in the old one, retry duplicates, and external effects such as confirmations already sent. Redirecting users alone discards a day of valid work and does not reverse those effects. Use a tested synchronization or recovery procedure that carries the work back, or, if the point of no return has passed, keep the new system authoritative and apply controlled forward recovery.
3. The old reporting server has nightly backups. Does that satisfy the 45-minute recovery target?
Solution
No. A backup shows that data was copied; the target concerns a restore. Check that a restore has been rehearsed by both trained operators, timed from detection of the failure to a usable report reaching users, within 45 minutes; that the restored job can run with valid credentials and access to the order database; and that the restored report covers the data scope it needs, receipts up to the 06:00 comparison point. That scope is a freshness question for the report. It is different from a recovery point objective on the order data itself, which would state how many minutes of accepted orders may be lost: a nightly copy of the reporting server says nothing about that, and if such an objective existed, the age of the actually recovered data would have to be measured against it.
Discover more from Insightful Data Lab
Subscribe to get the latest posts sent to your email.
