Skip to main content
Back to Blog
Technology22 min read15.06.2026Max Fey

Your systems are drifting apart, and nobody is reconciling them

Your CRM says 1,180 active customers. Your billing system says 1,224. Both numbers come out of the same automation. Why every integration drifts over time, and how a reconciliation job finds the gap before a customer does.

When the numbers stop agreeing

I was looking at two dashboards with a managing director a few weeks ago. One said 1,180 active customers in the CRM. The other said 1,224 paying subscribers in billing. Same customers, same contracts, and between the two systems an automation had been running for two years with exactly one purpose: to keep those numbers the same.

A gap of 44. Nobody in the room could tell me which 44. Nobody knew whether the CRM was short by 44 or billing was over by 44. And nobody knew since when.

This is not some rare edge case. This is the default. I have spent a lot of time inside automation accounts over the past few years, and almost everywhere two systems are wired together through an automation, the data drifts apart over time. Slowly, quietly, without a single error. The workflow runs green every day, and the two sides still end up disagreeing.

This piece is about the thing that prevents that, and that almost nobody builds. It is called reconciliation, and the word is a good one, because it really is about getting two parties who disagree to settle. It is the least glamorous part of any integration, and in most cases the only part that tells you whether the rest is actually working.

"Synced" and "the same" are not the same thing

When someone builds an automation that connects two systems, they think in events. New customer in the CRM, so create them in billing. Cancellation in billing, so flip the CRM status to inactive. Every event triggers an action, and as long as every event runs cleanly, the two sides end up identical.

That is the theory, and it rests on one assumption: that every single event arrives and gets processed correctly. Forever. Every charge, every cancellation, every address change, no exceptions, for years.

That never happens. A sync is a chain of assumptions that nothing got lost. A reconciliation is the check on whether those assumptions held. Those are two very different jobs, and most companies only build the first one.

The mistake is treating "synced" as a state. "The systems are in sync" sounds like a property you establish once and then keep. It is not. Syncing is an ongoing process that constantly produces small errors. Without something that collects those errors, they pile up.

How drift happens while everything runs green

The question is not whether your data drifts. It is how fast. And that depends on how many ways an event can go missing. In practice there are more of them than you would think.

There is the webhook that never lands. Billing fires a notification about a cancellation, but your platform had a brief hiccup right then, or billing gave up after three failed delivery attempts. The event is gone. No second one is coming. The customer stays active in the CRM forever.

There is the manual change. Someone in support opens billing and cancels a contract by hand because the customer called in. A cancellation done through the interface often fires no webhook at all, or a different one than the normal path. The CRM never hears about it.

There is the run that completes halfway. The workflow grabs the new customer, creates them in billing, and the next step, updating the CRM status, times out. The customer now exists in both systems with two different states. No red run, because plenty of platforms count a partially successful execution as a success.

There is ordering. Two events arrive close together, an address change and a correction right behind it, but the automation processes them in parallel and the older one overwrites the newer one. The CRM now holds the wrong address, and nothing flags it.

There is the quiet assumption about fields. A year ago someone added a required field in billing. Since then, creating new customers occasionally fails, but only for the ones missing that field. The automation catches the error and moves on, and you quietly lose a fraction of every batch of new customers.

Each of these on its own is rare. Maybe one record in a thousand. But at a thousand charges a month, that is one a month, twelve a year, and after two years you are staring at 44 customers nobody can account for. That is how drift happens. Not through one big outage everyone notices, but through a lot of tiny gaps that each stay under the radar.

What reconciliation actually is

Reconciliation answers one question: do the two systems agree right now, and if not, exactly where do they differ?

It works in a fundamentally different way from a sync. The sync reacts to events, one trigger after another, trusting that the sum of all triggers ends up as the right state. Reconciliation ignores events entirely. It takes both systems at a point in time, looks at the complete set of records on each side, and compares them record by record.

That is the key difference. A sync cannot detect that an event slipped past it, because it only knows about the events it saw. What it never saw does not exist as far as it is concerned. Reconciliation does not have that blind spot, because it does not follow the events, it follows the actual data. It does not ask "did I process everything," it asks "is the result correct."

In traditional software this is a familiar pattern. Any serious integration between two systems has a periodic reconciliation job that runs overnight and reports what does not line up. In the no-code world that pattern is almost always missing. The platforms make it easy to react to an event and hard to hold two full datasets against each other. So nobody builds it, and the drift stays invisible until a customer calls.

The anatomy of a reconciliation job

A reconciliation has five steps at its core, and each one is worth understanding on its own, because most failures live in exactly one of them.

The first step is pulling both sides. You fetch the complete relevant set from system A and from system B. Not the last hundred records, not the last week, but everything that is supposed to match. Sounds trivial, but this is where most reconciliations fall apart, because the platform hands you the data in pages of a hundred and the workflow only grabs the first page.

The second step is the key. You need a field that uniquely maps a record in A to one in B. A customer number, an email address, an external ID. Without a reliable key you are not reconciling, you are guessing. And the key has to be stable. An email address changes. A customer number, ideally, never does.

The third step is the comparison. You walk both sets and sort each record into one of three buckets: in both and equal, in one side only, or in both but with different values. That sorting is the actual heart of the job.

The fourth step is judgment. Not every difference is an error. A customer created two minutes ago that has not reached the second system yet is not a problem, it is the normal lag of the sync. A customer missing on one side for three weeks is a problem. The reconciliation has to tell those two apart, or you will drown in false alarms.

The fifth step is the response. What happens to the differences that remain? There are several options here, and the choice decides whether your reconciliation helps you or becomes a hazard of its own. More on that below.

Three kinds of difference, and what they mean

When you hold two datasets against each other, every difference falls into one of three buckets, and each tells a different story.

The record is missing in B but present in A. Usually that means an event got lost that should have carried it over to B. The customer was created in the CRM but never in billing, because the create step failed back then. This is the dangerous one, because real money often sits here. A customer who uses the product but never pays, because they never reached billing.

The record is missing in A but present in B. The reverse, and it often points the other way: something was deleted or deactivated in A, but the information never reached B. The customer canceled, the CRM shows them inactive, and billing keeps charging. This variant reaches a lawyer faster than the first one, because someone is paying for something they ended.

The record exists in both, but the values differ. Different address, different status, different plan. This is the subtle one, because both systems know the customer and everything looks fine on the surface. Only a field-by-field comparison reveals that one side holds a different state than the other. These come from ordering problems, from manual edits, or from updates that only ever ran in one direction.

The practical value of this split is that each bucket has a different cause and demands a different response. A missing record can often be pulled across automatically. A value conflict needs a decision about which side is right, and an automation cannot always make that call.

What to do with a difference, and what not to

The obvious idea is this: if the reconciliation finds a difference, have it fix the difference right away. Missing in billing, create it. Wrong status, correct it. A reconciliation that heals itself sounds like the elegant answer.

I would be careful here. A reconciliation that corrects automatically is a powerful tool and just as quickly a dangerous one. If your reconciliation has a flaw in its logic, it does not repair, it damages, at scale and all at once. I saw a case where a self-healing reconciliation set hundreds of customers to inactive overnight, because it had briefly loaded only half of one dataset and treated everyone missing as canceled. The sync had been doing tiny damage for months. The reconciliation did one large piece of damage in a single evening.

So I keep the three responses cleanly separate. The first is report. The reconciliation finds the differences and writes them to a list a human reviews in the morning. That is the right starting point for almost any reconciliation, because you want to see what it finds before you let it do anything.

The second is fix automatically, but only for the cases that are unambiguous and harmless. A missing record that clearly just needs creating can be pulled across safely. A value conflict where it is unclear which side is right never belongs in automatic correction.

The third is quarantine. Some differences are odd enough that the right response is to stop, set the record aside, and do nothing until a human has looked. If a customer holds a completely different plan in each system, that is not a case for an automatic rule, it is a sign that something is broken further upstream.

My rule of thumb: at the start, let the reconciliation only report. Once you have spent a few weeks watching what kinds of differences actually show up, and you understand where they come from, you switch on automatic correction for the few genuinely unambiguous cases. Everything else stays with a person.

The most common mistake: the reconciliation that lies

There is one particularly nasty way to build a reconciliation wrong, and it is more dangerous than having none at all. It is the reconciliation that always reports "all good," because it never sees one side in full.

The usual story: the reconciliation pulls the full set from A, but from B only the first page of a hundred records, because the API paginates and the workflow misses it. Now it compares a thousand records from A against a hundred from B. It should raise an alarm, because nine hundred appear to be missing. Instead it is often built to only check whether every record from B also exists in A, and all hundred of them do. Result: green. All matched. In reality it never looked at ninety percent of one side.

That is the worst possible state. You now not only have drift, you also have an early warning system actively assuring you that everything is fine. The confidence a green reconciliation creates is more dangerous than an honest admission that nobody is watching.

This is why every reconciliation needs a sanity check on itself. The simplest is a count comparison: if A reports 1,224 records and B reports 130, then the plausible conclusion is not "no differences," it is "the reconciliation is broken." A reconciliation that does not know how many records it saw on each side is not a reconciliation, it is a placebo.

How often, and over what window

A reconciliation that runs every minute is usually wasted. One that runs once a year arrives too late. The right frequency depends on how expensive a difference is per day that nobody notices.

For billing data, where every day of wrong charges costs money and trust, daily is a good rhythm. An overnight run that puts a short list on the desk in the morning catches most problems before they grow. For data that rarely changes and costs little when it drifts briefly, weekly is enough.

More important than raw frequency is the question of the time window. If you pull both datasets at three in the morning every day, you will inevitably catch records that are mid-processing. The customer was created in A at 02:59 and is not in B yet at 03:00. That is not a real difference, it is just the normal lag.

The clean fix is a tolerance threshold. You ignore differences younger than a set window, say an hour. Anything that has been out of step for more than an hour is suspect. Anything under that is probably just a sync that has not finished. Without that threshold your reconciliation produces a handful of ghost differences every morning that resolve themselves, and within a week nobody looks at the list anymore.

A concrete build: CRM against billing

So this does not stay abstract, here is the build I put together for the case at the top, in the shape you would implement it in Make or n8n.

The job starts once a day at four in the morning, after the main overnight sync. Step one pulls all active customers from the CRM, across every page, and remembers the total count. Step two pulls all running contracts from billing, also in full, and remembers that count too.

Step three is the sanity check: if either side returned less than eighty percent of the records it had on the last run, the job aborts and reports "reconciliation not trustworthy." Better no result than a false one.

Step four builds a lookup from each dataset on the customer number and compares them. Out come three lists: CRM only, billing only, and present in both with a different status. Step five strips out of all three lists the records younger than an hour.

Step six writes the result to a table and posts a message to the team channel, but only if anything remained. A reconciliation that reports "zero differences" every morning gets ignored within two weeks. One that only speaks up when there is something keeps its audience. And once a week, on Monday, a short summary goes out with the counts on both sides, so the team can see the job is still alive even when it found nothing.

On its first run this reconciliation found not 44 but 61 differences. Seventeen were short-lived lag that was gone on the next run. The 44 that remained split into two groups: 31 customers canceled in the CRM but still running in billing, and 13 created in billing but never carried over to the CRM. The first 31 cost the customer nothing, quite the opposite. The 13 used the product without ever being invoiced.

Reconciliation as an early warning system

The real value of a reconciliation is not that it cleans up the 44 old cases. That is the one-time inventory at the start. The lasting value is that from now on it catches every new case while it is still small.

Once the reconciliation runs, the meaning of each new difference changes. A single difference that suddenly appears is often the first symptom of a problem that just started. Three new missing records in one morning can mean someone changed something on the webhook yesterday. A wave of value conflicts can mean a required field was added. The reconciliation translates a technical change you would otherwise have noticed weeks later into a visible number the next morning.

That turns the inventory into a sensor. The sync does the work. The reconciliation measures whether the work is correct and trips when it stops being so. A workflow without a reconciliation is a car without a fuel gauge. It runs until it suddenly does not, and then you are on the shoulder of the road with no idea why.

Who owns the drift

To close, the uncomfortable part that has nothing to do with technology. In most companies where I have found drift, the real problem was not in the workflow. It was the question of who is responsible for the two systems agreeing. And the answer was almost always: nobody.

The CRM belongs to sales. Billing belongs to finance. The automation in between was built at some point by someone who may no longer be at the company. As long as everything runs green, nobody feels responsible. And that is exactly why nobody notices the drift, because the drift lives in the gap between the two, and the gap belongs to no one.

A reconciliation changes that, and not only technically. It makes the drift visible, and visible drift demands an owner. The list of differences that lands every morning needs a person who decides what happens to it. The moment that person is named, the gap finally has someone who feels responsible for it. That is often the more important effect than the code itself.

What you can do this week

You do not need a full reconciliation job to start. You need a single number from each side. Count how many active customers sit in your CRM. Count how many running contracts your billing has. Write the two numbers next to each other.

If they match, you have bought yourself a good feeling in ten minutes. If they do not, you have just found a problem that was invisible before, and that is the more useful outcome. The gap was there the whole time. You just looked at it for the first time.

If you are not sure whether your systems are quietly drifting apart, that is worth checking. Our free Automations Check goes through your workflows and tests whether the numbers you rely on are really the same on both sides.

#Reconciliation#Datenabgleich#Datenqualität#Sync#Webhook#CRM#Automatisierung#Idempotenz