Insights4 March 2026Updated 26 October 20265 min read

Legacy SQL to NoSQL Migration Strategies for Smart Logging Systems

A glowing tree with roots labelled Old Systems, New Systems and Legacy Data in a mystical forest setting.

A SQL to NoSQL migration should preserve what a logging record means, not merely move its fields. In Continuous Architecture in Practice, chapter 6, Murat Erder, Pierre Pureur and Eoin Woods describe database changes as migrations that must establish completeness without changing business meaning. We would make that the acceptance condition before choosing a replacement database.

For a smart logging system, start with a concrete question: can the organisation still reconstruct an inspection after the storage model changes? We recommend proving that with a bounded migration, explicit record ownership and a rehearsed return path. Treat higher throughput or easier development as outcomes to measure, not benefits implied by the word NoSQL.

Establish whether a database change is necessary

SQL does not rule out flexible record payloads. PostgreSQL, for example, provides JSON storage and supports indexing for its jsonb type. We would compare that option with a separate document store before proposing a replacement solely because inspection forms vary.

Write down the workload the proposed design must serve. Include retrieving an inspection with its evidence, listing unresolved defects for a building and exporting a historical report. Ask the prototype to run those operations against representative records, including unusually large inspections. Keep the required result beside the timing measurement so a faster but incomplete response cannot pass.

Set the decision boundary narrowly. A document representation for reading inspection histories need not be a commitment to move every transactional table. We would first test a derived read model while retaining SQL as the agreed write authority. Require an explicit reason before extending the change to the write path.

Define the destination record before copying data

For the migration specification, describe one hypothetical inspection document in full. Give it a stable inspection identifier and list its building reference, recorded answers, evidence references and revision information. Decide which values represent the inspection as recorded and which are current reference data. Ask the operational owner to approve that distinction before transformation code is written.

Require a mapping from each source identifier to its destination representation. Document any fields that are combined, renamed or deliberately excluded. Keep unresolved relationships in a review report rather than silently guessing a building or inspector match. This is our proposed application of the book's requirement to preserve completeness and business meaning.

Also distinguish equivalent values from identical evidence. PostgreSQL documents that jsonb does not preserve whitespace, object key order or duplicate object keys. If the acceptance requirement includes the original submitted bytes, require a separate retained original and test its retrieval. Do not treat a reconstructed JSON document as proof that the original submission was preserved.

Join the initial copy to ongoing changes

A block of light is copied across a bridge to a new structure while a steady trickle of new particles follows it

For a live migration, require a documented connection between the initial copy and subsequent updates. Debezium's PostgreSQL connector illustrates the mechanism: it takes a consistent snapshot, then streams committed inserts, updates and deletes from the snapshot position.

We would record the starting position, transformation version and destination checkpoint for each rehearsal. Include a deletion and a correction made while the copy is running. Require the final destination to reflect both operations before declaring the catch-up complete. For inspections submitted after an offline period, test the agreed handling of the older client payload too.

Do not assume that change capture provides a historical audit archive. The same connector documentation explains that PostgreSQL normally removes older write-ahead log segments. Preserve any required earlier inspection history through a separately specified migration, rather than expecting replication to reconstruct it.

Design for replay and partial failure

Two writes are not an adequate consistency policy. AWS describes how updating a database and then failing to publish an event can leave a system inconsistent. For the first migration phase, we recommend retaining a single accepted write path and deriving the destination from it, rather than asking the mobile application to update both databases independently.

Make repeat processing an acceptance test. Debezium warns that recovery can produce duplicate events and consumers should anticipate them. Require the destination writer to recognise an already applied change using an explicitly specified identity and version policy. Replay the same test batch and verify the agreed result, including that one inspection does not become several.

Monitor the source as well as the destination. Debezium's documentation warns that replication slots retain required log segments during outages and can consume excessive disk space. Assign someone to the connector's lag and retained-log alerts before the pilot starts. Rehearse a stopped consumer and define when the team must pause the migration.

Reconcile before switching authority

Two glowing structures side by side with matching rows linked by fine lines, one point flagged as a mismatch

We recommend making reconciliation a release gate. Compare inspection identifiers, revision history, evidence references and the outputs of the agreed operational queries. Review exclusions separately. Do not use matching record totals as the sole acceptance condition when the specification also requires matching ownership and history.

Before changing write authority, rehearse the cutover with explicit stop conditions. Specify how to stop old writes, confirm the final accepted change and route subsequent requests. Keep the system on the old path if the reconciliation fails. Name the person authorised to approve the switch and preserve their evidence alongside the migration report.

Define rollback just as carefully. Ask how writes accepted after cutover would reach the old representation, and prove that procedure in the rehearsal. If reverse migration is outside scope, state the point beyond which returning requires a separate recovery operation. Do not label a connection-string change as a complete rollback plan.

Update, October 2026: brief the implementer with the same evidence

For teams using coding agents on migration work, we recommend supplying the identifier mapping, ownership decision and failure tests before implementation. Our engineering article What the Agent Does Not Know to Look For describes assembling code structure, dependencies and known gaps into a grounding pack. Use that preparation to give the implementer and independent reviewer the same migration constraints.

Sources

Want this in your team?

Tell us what you're building and where you want to get to, and we'll think it through with you.

Let's have a chat Follow by RSS →

All insights →