It is the last day of the month. You have Stripe open in one tab and HubSpot in another, two CSV exports on the desktop, and a number that needs to be in the deck by Friday.
Stripe says one thing. Your CRM says another. You annualize the Stripe figure to put it on the same footing, and the two still don’t meet. The difference is not enormous (four figures, maybe five), which is the worst possible size. Too small to be alarming, too large to be rounding.
So you tell yourself it’s timing. Then you open the deck and type a number you cannot defend.
Sometimes that gap is nothing. Sometimes it is a customer paying last year’s price, and it has been happening every month since March. The two look identical in a spreadsheet. Telling them apart is the actual work.
The two systems are counting different things, and neither is wrong
A gap is not evidence of an error. Your CRM and your billing system were built to answer different questions.
HubSpot’s ARR is a deal property. Per HubSpot’s documentation, Annual recurring revenue is the total revenue earned annually for that deal, “calculated based on the term length and values of the recurring line items associated to the deal.” With no term length, HubSpot assumes twelve months. Monthly recurring revenue divides that total by the number of months in the term. Both of them, and Total contract value too, “do not take into account the value in the Amount property.”
That last sentence causes more month-end arguments than any other line in either knowledge base. The number a rep typed into the deal amount is not the number HubSpot reports as ARR; ARR comes from the line items. If your line items are stale, your ARR is too, and nothing warns you. There is more on the property mechanics in the HubSpot resource center.
Stripe’s MRR is a normalized sum, net of discounts. Stripe’s support documentation defines it as “summing the monthly-normalized amounts of all active and past-due subscriptions,” with ARR “calculated by multiplying MRR by 12.” Taxes and application fees are excluded. Trials are excluded. Permanent recurring discounts are always subtracted, and whether one-time and recurring discounts come off is a setting you choose, so two companies on identical plans can report different MRR, correctly.
Note the phrase past-due. A customer whose card failed is a past-due subscriber, and past-due subscribers sit inside Stripe’s recurring revenue. Your finance team may not feel that way.
The five reasons a real ARR and a real MRR won’t reconcile
These are structural, documented, and explain most of a persistent gap.
- Annual contracts, normalized differently. A $36K annual deal contributes $3,000 a month to Stripe’s MRR and $36K to the ARR you computed from your CRM. Annualize Stripe’s MRR back up and you get the same number, but if anyone in the chain compared a monthly figure to an annual one, the gap is arithmetic, not revenue.
- Mid-cycle changes bill prorated amounts. Stripe’s own example: a customer moving from a $10 plan to a $20 plan halfway through the period is billed “an additional 5 USD: -5 USD for unused time on the initial price, and 10 USD for the remaining time on the new price.” Positive prorations “aren’t immediately billed.” The CRM shows the new contracted value the moment the deal is won; Stripe shows a partial charge.
- Discounts and credit notes. MRR can be configured net of one-time and recurring discounts, and permanent recurring discounts always come off. A CRM deal amount is usually a list or negotiated figure someone typed. Two different quantities wearing the same label.
- Trials and past-due subscriptions. Trials are outside Stripe’s MRR; past-due subscriptions are inside it. Your CRM shows both as active accounts, so both produce a mismatch in opposite directions.
- Line-item coverage and manual properties. HubSpot’s revenue analytics calculates from the recurring revenue properties, and those “need to be updated manually in order to see any data”: the products and quotes on a deal don’t feed it. A deal amount also doesn’t refresh when line items change via import or API, and the line items card caps at 200 items.
In a lot of companies those five explain the whole difference, and the honest answer is “definitional, reconciled, here is the bridge.” If they don’t, you have a different problem, and it is worth money.
Separate the definitional gap from the dollar gap
The mistake almost everyone makes is diagnosing a per-account problem from an aggregate. Your total ARR and your total MRR will never match, and that is expected. SaaS Capital’s 2025 retention study, its fourteenth annual survey, with more than 1,000 private B2B SaaS companies responding, puts median net revenue retention at 101% and median gross revenue retention at 91%.
101% / 91%
median net and gross revenue retention across the survey’s B2B SaaS companies. A normal book of business sheds revenue it never intends to lose, which is exactly why a gap between two totals can’t tell you whether anything is broken.
SaaS Capital, 2025 B2B SaaS Retention Benchmarks
Nine points of churn and contraction live inside a perfectly normal book of business, before any error exists. So an aggregate difference is uninformative by construction: it sums your expected attrition, your definitional mismatches and your real errors into one number that separates none of them.
Stop looking at totals. Start looking at rows. Two readings, either of which is a finding:
- The gap is stable and spread thinly. Nearly every account differs by a small amount and the pattern doesn’t change month to month. That’s structural: definitions, normalization, discount treatment. Document your ARR methodology, disclose it, move on.
- The gap sits on specific accounts and persists. A handful of customers where contracted value and charged amount disagree, the same handful every cycle. That is not a definition. That is an unbilled upgrade, a cancellation that never propagated, or an invoice never raised, and it compounds monthly for as long as it goes uncaught.
The second reading is the one worth running down, and you can do it without writing to either system.
The four-line reconciliation you can run read-only
Two exports, one common key. Here is the method, including where it gets annoying.
- 1 · Pull contracted value per account from the CRM. Use the recurring revenue line items, not the Amount field, because that is what HubSpot’s own ARR reports from. Normalize to a monthly figure so it sits next to MRR without an annualization error.
- 2 · Pull the active subscription amount per account from Stripe. Take active and past-due; a failed payment is a finding, not a non-event.
- 3 · Match on a key you can trust. Company names in a CRM and customer records in billing drift apart on suffixes, rebrands, parent entities and typos. Match on a stable identifier where one exists; where it doesn’t, you are guessing.
- 4 · Compare contracted to charged, and sort by absolute difference. The top of that list is your first hour of work. Anything in both columns with the same number is fine.
What makes it painful at scale is everything from step 3 onward: multi-currency accounts, accounts renamed mid-contract, a billing subscription with no CRM record, a deal whose line items don’t add up to what the customer agreed to. This is the seam, the space between the two systems neither one is watching. It’s where the month-end reconciliation tax gets paid, and it’s the same gap as where your CRM and billing quietly disagree about money.
When the accounts are genuinely wrong, change them deliberately
The upgrade that closed in March and never reached billing
Suppose the reconciliation surfaces twelve accounts. Two are old friends: a $24K/yr customer still charged the $18K/yr price eight months after an upgrade closed, and a customer whose cancellation in Stripe never reached the CRM, so they are still counted in pipeline and forecast.
You have a decision now, not a diagnosis, and it matters, because both fixes change a record finance and sales rely on.
The principle worth holding onto: the person who owns the relationship should approve the specific change. Not a bulk import, not a script someone ran on a Friday. The exact account, the exact old value, the exact new value, a named human who said yes. Anything that touches contracted revenue without that step creates a new reconciliation problem while solving the old one.
That is also the design Junction follows: a read-only scan ranks mismatches by dollar impact, the paid plan’s revenue agents prepare the specific correction and then wait for you to approve that exact change, and afterward both systems are re-read to confirm the issue actually closed.
What to write in the deck on Friday
The reconciliation will not always be finished when the deck is due, but the question will still be asked. So write the sentence that is true:
The CRM ARR figure and the billing MRR figure are calculated from different records and are not expected to match in aggregate; the difference is definitional and consistent month to month. We reconcile account by account, and any account where contracted and charged value disagree is corrected through an approved change.
The honest line for the board deck
That is defensible: it names the gap, separates the definitional part from the dollar part, and commits to a process instead of a number.
If you would rather not build the classification by hand, start with a free read-only scan. Connect HubSpot and Stripe and Junction returns every account where the two disagree, with the dollar impact attached and ranked, usually in minutes. It changes nothing in either system, and you can see what a scan looks like before deciding what’s worth fixing. Start a free one at app.getjunction.io/signup.
Sources
- HubSpot's default deal properties (ARR, MRR, TCV definitions), HubSpot Knowledge Base, updated September 9, 2026
- Track recurring revenue in HubSpot (manual recurring revenue properties), HubSpot Knowledge Base, updated August 24, 2026
- Understanding Monthly Recurring Revenue (MRR) and Annual Recurring Revenue (ARR), Stripe Help & Support, retrieved September 21, 2026
- Analytics (Billing): MRR report and configurable MRR definitions, Stripe Documentation, retrieved September 21, 2026
- Prorations (worked mid-cycle change example), Stripe Documentation, retrieved September 21, 2026
- Supported metrics: revenue.mrr covers active and past-due subscriptions, Stripe Documentation, retrieved September 21, 2026
- 2025 B2B SaaS Retention Benchmarks, Research Brief 32 (median NRR 101%, GRR 91%), SaaS Capital, September 2025
- Use line items with deals (deal amount not updated by API imports), HubSpot Knowledge Base, updated July 24, 2026
