Somewhere in your system the same fact is stored twice. A count in a column and the rows it is counting. A status on the order and a status on the payment. An email in the profile service and the same email in the list you send from. Today they agree. They will not agree forever. Drift does not need a bug. It needs one write that lands and one that does not, one job that failed quietly at three in the morning, one migration that touched the table and not the cache. After that the two numbers are simply different, and nothing in the system is unhappy about it. The report is unhappy. The customer is unhappy. You find out weeks later in a message that says "these two screens do not match", and you cannot tell which one is lying. So decide who owns the fact. One place holds it. Everything else derives it, or asks for it, or caches it with an obvious expiry and an obvious name. A field called total is a claim. A field called cached_total_at_midnight is a confession, and confessions are easier to debug. Sometimes you cannot avoid the copy. Two services, two databases, a boundary you do not control. Then do not pretend. Write the reconciliation job on the same day you write the copy, not after the first mismatch. And make it report the difference before it corrects it. A job that silently repairs drift hides the thing you most need to see: how often, and from where. The version of this that hurts most is the one nobody designed. Somebody denormalised a column for a slow page in 2022. It was a performance fix and it worked, and it quietly became a second truth that nobody agreed to maintain. Every duplicated fact is a promise that two pieces of code will stay in step for as long as the system lives. They will not. Store it once. Everything else is a copy, and copies age. – Serguey Asael Shinder