Your CRM knows one thing about a customer. Your billing system knows another. Most of the time the two agree, so nobody looks. Then it’s month-end, the numbers don’t tie out, and someone spends an afternoon working out which system was telling the truth. The uncomfortable answer is usually: neither, entirely.
A B2B SaaS company runs its revenue on two systems that were never designed to check each other. The CRM — HubSpot or Salesforce — is the record of intent: deals, stages, owners, forecast. Billing — Stripe, Chargebee, Zuora — is the record of money: invoices, charges, cancellations, failed payments. Each is authoritative for its own half of the world, and each is completely blind to the other. Your CRM never sees a cent of what actually billed. Your billing system never sees a deal stage or a forecast. The gap between them isn’t a bug in either one. It’s the space they were built to ignore.
That space is where the money goes missing. Not in dramatic, obvious ways — in quiet, one-record-at-a-time ways that don’t trip any alarm because no single system is wrong from where it’s standing.
The seam, defined
Think of it as a seam: two pieces of fabric stitched together, holding as long as nothing pulls on them. A customer cancels in Stripe. In that moment, billing is correct and the CRM is now wrong — but the CRM has no way to know, because nothing told it. A rep marks an expansion closed-won. The CRM is correct and billing is now behind — but billing has no way to know, because no invoice was ever raised. Every one of these is a moment where the two systems quietly diverge, and neither is looking at the other to catch it.
- Active in your CRM, canceled in Stripe. The customer is gone, but the account still counts toward ARR and the CSM is still prepping their renewal.
- Closed-won, never invoiced. The deal is booked and forecast, but no charge was ever created — so the cash never arrives.
- Upgrade signed, never billed. The plan changed in the CRM; the subscription in billing is still on the old, cheaper tier.
- Failed payment the CRM never hears about. A card declines, the customer silently lapses, and the account stays green in the pipeline.
None of these show up as an error. Each system is internally consistent. The disagreement only exists when you look across both at once — which, most months, nobody does until the close forces it.
Northwind Systems — active in HubSpot, canceled in Stripe five weeks ago
Northwind is a $48K/yr account. In HubSpot it’s an active, healthy customer: renewal opportunity open, CSM assigned, a QBR on next week’s calendar. In Stripe, the subscription was canceled 37 days ago — a downgrade decision made by a new VP nobody looped the CRM in on.
For five weeks, the forecast has counted $48K of ARR that will never renew, a CSM has spent real hours preparing for a customer who already left, and finance won’t catch it until the quarter is reconciled by hand. One account. Now multiply it by every silent divergence sitting in the seam right now.
Why the drift is invisible by default
The seam is hard to see because everything that would reveal it is expensive to do. To notice that Northwind is active-but-canceled, someone has to hold the CRM record and the Stripe record next to each other and compare them — for every account, on a cadence fast enough to matter. There’s no shared key that lines them up cleanly, no shared event that fires when they disagree. The CRM trusts its own fields. Billing trusts its own ledger. And the raw material on the CRM side is degrading the whole time.
~22.5%
of a B2B contact database goes stale in a year — roughly 2% a month, compounding — as people change roles, companies restructure, and champions leave. The CRM you’re forecasting from is quietly drifting away from reality even when nothing “breaks.”
HubSpot database-decay research, drawing on MarketingSherpa
Layer money on top of decaying data and the cost stops being theoretical. Gartner’s widely-cited figure puts the price of poor data quality at an average of $12.9 million a year per organization — a number drawn from large enterprises, but the mechanism is the same at any size: decisions made on records that no longer match the world. When those records are the ones your forecast and your invoices depend on, the drift shows up directly as revenue you booked and never collected.
The break doesn’t live inside your CRM or inside Stripe. It lives in the seam between them — where neither system is looking, and where nobody is paid to look until month-end.
The core idea behind Junction
What the drift actually costs
Industry estimates of how much subscription revenue quietly leaks out through billing gaps, contract mismatches, and failed collections cluster around 1–5% of revenue — a range echoed by analyses from MGI Research and billing vendors alike. On a $10M ARR business, the low end is $100K a year; the high end is half a million. That’s not fraud and it’s not incompetence. It’s the accumulated cost of two systems that never compare notes.
The cost lands in three places, and rarely on the same desk:
- The forecast. Active-but-canceled accounts inflate ARR. You’re steering off a number that includes customers who already left.
- The cash. Closed-won-never-invoiced and upgrades-never-billed are revenue you earned, reported, and simply never charged for.
- The trust. When the board deck and the billing system report two different ARRs, every number you present afterward carries an asterisk — and reconciling them by hand eats a day you’ll never get back.
That last one compounds. The failed-payment version of the seam is especially costly because it’s a churn event your CRM never hears about — we pulled that thread on its own in the churn you never see. And the recurring manual comparison that finance runs to find all of this has its own price tag, which we break down in the month-end reconciliation tax.
Closing the seam without touching either system
The instinct is to fix this with process — a rule that reps must update billing, a checklist at close, a quarterly clean-up. Process helps at the edges, but it’s asking two systems that can’t see each other to stay in sync through human diligence, forever. That’s a tax, not a fix.
The other approach is to add a third vantage point that reads both sides and only reports where they disagree. Read-only is the important part: it doesn’t need to write to your CRM or your billing system to find the gaps — it just needs to hold the two records next to each other, continuously, and surface the accounts where intent and money have come apart. Northwind stops being a five-week-old surprise and becomes a line item you see the day it diverges.
That’s the whole idea behind Junction: connect to the CRM and to billing read-only, find every account where the two disagree about money, and return a dollar figure — not a PDF — in minutes. You don’t change how either system works. You just stop taking one system’s word for it. If you want the taxonomy of exactly which breaks to look for first, that’s the four silent revenue breaks.
Sources
- Data Quality: Why It Matters and How to Achieve It ($12.9M average annual cost) — Gartner
- Database Decay research — the 22.5% annual B2B data-decay benchmark — HubSpot (citing MarketingSherpa)
- How billing gaps cost SaaS 1–5% of ARR — Lago
- How to Detect and Prevent Revenue That Leaks Between Quote and Cash — Zuora
- Churn Rate Benchmarks by Industry (voluntary vs. involuntary split) — Recurly Research
