Use case · Migrations
Migrate with receipts.
Limen runs your old and new systems side by side against the same rules, so you can show the new one delivers what the old one promised before you cut over.
See all six checks
| Check | Old system | New system |
|---|---|---|
| row_count | 412,884 | 412,884 |
| sum(revenue_usd) | $8,114,902.40 | $8,114,902.40 |
| null(refund_at) ≤ 0.25% | 0.21% ✓ | 0.34% ✗ |
| distinct(customer_id) | 71,402 | 71,402 |
| join.orders→items | no orphans | no orphans |
| freshness | 04:12 UTC | 03:41 UTC |
Parallel run · orders_daily · 2026-06-14. Five of six checks pass on both systems. One fails on the new system and is flagged for review before cut-over.
What goes wrong today
Migrations break the same four ways.
- Hidden dependencies.A report relied on a column being sorted, a string being trimmed, or a join ignoring case, and nobody wrote it down.
- Quiet drift.Row counts match, but a null rate, a percentile, or a rare value has changed.
- Timing changes.The new system delivers 31 minutes earlier on weekdays and 2 hours later on weekends.
- Changed definitions.A vendor changes what an “active customer” is, and the two systems start to disagree about who counts.
How it works
Every difference becomes a decision, not a surprise.
01
List what people rely on.
We work with your team to write down what downstream teams depend on: row counts, null rates, joins. Those become the rules both systems are checked against.
02
Agree the rules.
The data team reviews them. The teams that use the table approve them.
03
Run both side by side.
Old and new run against the same rules, checked on every batch, every day.
04
Decide, then cut over.
Each difference is shown with the check that failed. You fix it or accept it, then cut over with a record of the result.
A small first step
One table. Two weeks.
We take one critical table in your old system, write down what it is relied on for, and run it against your new system side by side for two weeks. The record is what you keep.
