Fuel cost per mile at one distribution hub, Elm Yard, rose 9% over two months. The telematics platform tracking the same trucks over the same window showed no change in mileage, no new routes, and no shift in idle time. Neither number was wrong.
That combination is the failure mode this piece is about: not corrupted data, but two systems that each report accurately from their own source of truth and were never designed to agree with each other. The fuel card platform tracks what a driver’s card charged. The telematics platform tracks where a truck physically went. Both did their job, and the discrepancy lived in the space between them, not inside either one.
The standard comparison is aggregate to aggregate: this month’s total fuel spend against last month’s, this month’s total mileage against last month’s. That comparison hides the exact kind of mismatch at play here, because it never looks at the individual transactions and trips underneath the totals. Two aggregates can drift apart for reasons that have nothing to do with data quality and everything to do with definitions, schedules, and business rules nobody wrote down in one place.
Teams that only compare totals find out about a discrepancy days or weeks after it started costing them. By the time a rollup number looks wrong, the mismatch underneath it has usually been running quietly for a while. That is exactly what happened at Elm Yard.
Why the numbers disagree: the four mechanisms behind cross-system discrepancies
Cross-system discrepancies come from four mechanisms, and nearly every case that looks mysterious traces back to one of them: timing and latency lag, differing business logic between systems, schema or categorization drift, and duplicate or partial records.
Timing and latency lag is the simplest to explain and the easiest to misdiagnose. The Elm Yard fuel card feed posted transactions the same day a driver swiped. The telematics mileage feed refreshed on a nightly batch. A truck that fueled up Monday night would not show matching mileage until Tuesday morning’s batch ran, a one-day lag the team initially read as a real mismatch and spent a full week chasing before anyone compared the two refresh schedules directly.
Differing business logic is quieter and harder to catch, because both systems can be functioning exactly as designed. The fuel-spend rollup query filtered strictly on merchant category codes 5541 and 5542, the two codes marked “fuel.” When the truck stop near Elm Yard added a coffee counter, the card network reclassified the merchant under MCC 5499, “convenience store.” The fuel transactions kept flowing into the raw data feed exactly as before; they just dropped out of the “fuel cost” bucket the finance team’s query was built to catch, because a rule buried in a query no longer matched a rule the card network had quietly changed.
Schema and categorization drift shows up in less obvious places too. The same mechanism, a definition moving without anyone deciding to move it, can turn a shifted geofence boundary into an “off-site” dwell-time flag in a dispatch system overnight. The dispatch platform did not break. Its definition of where the yard ends moved a few feet, and everything downstream inherited that shift.
Duplicate or partial records round out the list, and they behave differently from the other three because two records both exist and neither is technically wrong. Some Elm Yard drivers still hand-log mileage on paper instead of relying on the telematics unit. Those manual entries land close to the telematics figure for the same trip but rarely exact, off by a few tenths of a mile or a rounded start time. Deleting whichever record looks “extra” throws away information; a near-duplicate needs a different fix than a true duplicate does.
Trace any of these four back far enough and they converge on the same root cause. Each one looks like a data quality problem on the surface. Underneath, it is a definition, a schedule, or a business rule that changed in one system and not the other, with nobody watching for the two to drift apart.
Worth sitting with for a second: which of these four is most likely already live, undetected, in the systems your own team compares every month?
What an undetected discrepancy costs before anyone calls it a data problem
The Elm Yard team spent six weeks treating a data artifact as an operational trend before anyone questioned the comparison method itself. That six-week window is where the real cost accumulated, not in the 9% figure itself but in every decision made while the team believed the figure was real.
Maintenance pulled two vehicles in for review after both got flagged as “high fuel consumption” during that stretch. Mechanics found nothing wrong with either truck. The flags had come from the phantom 9% gap between two systems, not from anything happening inside the trucks, and the shop lost hours diagnosing equipment that was never the problem.
The anomaly climbed high enough up the chain that leadership began drafting a case to renegotiate the fuel card vendor’s contract, built on a cost trend that did not exist. A vendor negotiation grounded in a data artifact is expensive to walk back once it is already in motion, and this one nearly went further than a draft.
This is not a problem unique to one fleet team. Gartner estimates the average annual cost of poor data quality to organizations in the millions of dollars, and Forrester’s research on the topic found that a meaningful share of data practitioners report losses of $25 million or more tied to the same root cause: data that looked usable and was never checked against the systems it was supposed to agree with.
The least visible cost outlasts the incident itself. Once a routing or finance team gets burned by a false trend, they start discounting real signals from the same systems too. A legitimate anomaly six months later gets a shrug instead of an investigation, because the last one turned out to be nothing, and that erosion of trust is harder to repair than the original discrepancy was to find.
There is an audit-risk angle here as well, one that matters more to analytics leaders than to the team on the ground. A discrepancy of this size sat undetected for six weeks, drove a maintenance decision, and nearly reached a vendor contract. That is a traceability gap an auditor will eventually ask about, not because anyone did anything wrong, but because nobody could show when the two systems started disagreeing or why it took six weeks to notice. Six weeks is a long time for a phantom trend to run unchallenged, and it is the reason the next section starts with design, not tools.
What a resilient detection design does differently
A resilient detection design compares individual records between two systems and outputs what matched, what did not, and why. It never stops at comparing two aggregate totals, because totals are exactly where the Elm Yard discrepancy hid for six weeks.
Alteryx’s source-to-target mapping guide walks through this kind of system-to-system mismatch directly: how fields move, transform, and sometimes silently drop between one system and another. It is worth reading regardless of what tooling a team ends up using to fix the problem it describes.
Teams already trying to unify data across ERP, warehouse, and fleet systems into one comparable view may also find Alteryx’s supply chain analytics resources useful further reading, not as a fix for the Elm Yard case specifically but as context on what unifying that kind of multi-system data actually involves.
Applied to Elm Yard, record-level comparison means joining the fuel-card transaction feed to the telematics and dispatch event log on vehicle ID and a timestamp window, rather than comparing this month’s total fuel spend to this month’s total mileage. Once that join runs, the unmatched records become the object of investigation instead of the aggregate gap. A tool built to compare records across sources and identify matches and non-matches between datasets produces three outcomes: records that matched, records that existed only in the fuel-card feed, and records that existed only in the telematics feed. That second bucket, fuel-card transactions with no telematics match, is where the MCC-reclassified charges would have shown up directly on day one instead of as a vague trend six weeks later.
The manual mileage logs need a different approach, because they are not missing from either system. They simply never match exactly. Matching driver-entered mileage against telematics records calls for a tool built to identify non-identical duplicates across different input files, using a configurable similarity threshold rather than an exact-match rule. That is the difference between catching “these two records describe the same trip” and demanding “these two records be identical,” which the manual logs will never be.
Not every apparent duplicate is actually one, either. A tool built to separate unique from duplicate records is useful here, but its own documentation includes an honest caution: two records that look identical, same name, same rough figures, may not actually describe the same thing. That is worth flagging for a person to check rather than resolving on its own.
Profiling each source’s fields before any comparison runs is what would have caught the MCC problem early instead of six weeks in. Column-level profiling, covering nulls, uniques, value ranges, and min and max, flags exactly the kind of quiet change that hit the fuel-spend rollup: a field’s set of values shifting without anyone editing a query. Before any of it gets compared, standardizing casing, punctuation, and codes across both feeds means a formatting difference never gets mistaken for a real discrepancy in the first place.
None of this runs on its own. Each piece here, the join, the similarity match, the duplicate check, the profile, is something a team configures for its own two systems, not a feature that scans an environment and reports back unattended. The design principle matters more than any single tool: compare records, not totals, and build the comparison to keep running instead of waiting for someone to notice a number looks off.
How to retrofit detection into systems that already exist
Retrofitting detection does not require replacing the fuel card system, the telematics platform, or the dispatch and maintenance systems around them. It requires a scheduled comparison layer between them that did not exist before, one that runs the join automatically instead of waiting for a person to spot-check totals once a month.
The systems already exist. What is missing is a workflow that runs on a schedule, not a new data source. Building that workflow comes down to three steps.
Standardize merchant and category codes and timestamps on both feeds before joining them first, so a reclassification like the MCC change cannot silently break the comparison a second time. Run the join or fuzzy-match comparison on a schedule tied to how often the underlying data actually refreshes next, nightly to match the telematics batch cycle rather than whatever cadence an audit calendar happens to specify. Route unmatched records to a specific named owner for review last, rather than letting them land in an export nobody opens. That third step separates catching a discrepancy in days from catching it in weeks: an unmatched-records file with nobody’s name attached to it behaves exactly like the export nobody checked at Elm Yard for six weeks.
The case for building this now, rather than later, gets stronger as data volumes grow. McKinsey’s research on enterprise data and AI adoption through 2030 points to the same pressure: as data volumes and AI-driven use cases expand, the discipline of tracking how data moves and is defined across systems becomes more necessary, not less. Ad hoc, manual comparison does not scale gracefully with that growth. A scheduled comparison layer gets more valuable as the number of systems and the volume flowing through them both increase.
Natural-language assistance, like Ask Alteryx, can help a team build or configure a comparison workflow like this faster, particularly for analysts who are not going to hand-code a join. It is worth treating as workflow-building help, not as something that finds the discrepancy on its own; no current tool does that part automatically. Once a discrepancy does get traced back to a workflow or definition change, filterable audit logs can help show what changed and when, which matters more to the analytics leader answering for the six-week gap than to the analyst running the join.
None of this is the only right answer. Teams whose comparison logic is genuinely complex, high-volume, or already owned by data engineering may be better served by a code-based pipeline, Python, dbt, or SQL, than by a low-code comparison workflow. The honest test is who owns the logic today. If that answer is an analyst who gets to it when they can, a scheduled workflow solves a real gap; if a data engineering team already runs its own pipeline, that pipeline is probably the right place to add this comparison rather than a new tool layered on top of it.
Start with the join you haven’t run yet
The fastest way to find out whether this failure mode is already live in your own systems is to run one record-level join between two systems that are supposed to agree, and look at what does not match. Not a full audit. One join, two systems, an honest look at the unmatched output.
Alteryx One is designed to support that kind of cross-system comparison work, joining, matching, profiling, and cleansing data, without writing custom code, which matters most for teams where the comparison logic belongs to analysts rather than a data engineering backlog.
Start a free trial of Alteryx One and run the comparison against your own two systems. The gap, if there is one, will not stay hidden for six weeks.