The CEO opened the board meeting by saying the team had closed $1.2M in Q2. Twenty minutes later the fractional CFO put up the P&L. Recognised revenue for the same quarter: $340K.
Nobody in the room was lying. The $1.2M was total contract value signed. The $340K was the portion of that value the company had actually earned by June 30th under ASC 606. The gap was three years of multi-year contracts sitting in deferred revenue, plus about $180K of implementation fees the CFO had refused to book upfront.
What made the meeting painful was not the accounting. It was that nobody could reconcile the two numbers on the spot. The CRM had one field, Deal Amount, and it held a single figure that mixed subscription, services, and a multi-year prepay discount into one lump. Getting from that lump to a revenue schedule took the CFO nine hours in a spreadsheet every month.
I have now seen this exact scene at four companies between 30 and 120 people. The root cause is never the accounting standard. It is that the CRM was built to close deals and the finance system was built to recognise revenue, and nobody designed the handoff between them.
This is a RevOps problem wearing an accounting costume. Here is how the standard actually works, where SaaS contracts break it, and what to build in HubSpot or Salesforce so your CFO stops rebuilding the revenue schedule by hand.
Revenue recognition is a data modelling problem before it is an accounting problem.
Your accountant knows the rules. What they do not have is a clean feed of what was sold, over what period, split by what type of obligation. That feed comes from your CRM, and in most companies it does not exist.
Bookings, billings, and recognised revenue are three different numbers
Before the standard, the vocabulary. These three get used interchangeably in board decks and they mean completely different things.
Bookings is the total value of contracts signed in a period. A three-year deal worth $90K signed in June is $90K of Q2 bookings.
Billings is what you invoiced. If that same customer pays annually, you billed $30K in June and will bill $30K in each of the next two Junes.
Recognised revenue is what you earned. If service starts June 1st, you earned one month, so $2,500 lands in June's P&L. The other $27,500 sits on the balance sheet as deferred revenue, which is a liability, because you owe that customer eleven more months of software.
Sales teams are compensated on bookings. Cash flow runs on billings. Investors, auditors, and your P&L run on recognised revenue. I wrote a longer breakdown of how these interact with ARR in ARR vs bookings vs revenue, and the short version is that a company can post record bookings and shrinking revenue in the same quarter without anything being wrong.
Typical ratio between reported bookings and recognised revenue in a quarter where a Series A team closes several multi-year prepaid contracts. Neither number is wrong. They answer different questions.
The five steps, translated out of accountant
ASC 606 was issued by FASB in 2014 and became effective for private companies in 2019. IFRS 15 is the equivalent standard outside the US and is close enough that most of this applies either way. Both replaced a mess of industry-specific rules with one model built on a single idea: you recognise revenue when you transfer control of the thing you promised, not when the money arrives.
The mechanics run in five steps. Here they are in terms a RevOps person can act on.
Identify the contract. There has to be an approved agreement with enforceable rights and a real expectation of getting paid. In CRM terms, this is your closed-won gate. If your reps mark deals won on a verbal yes and the countersigned order form arrives three weeks later, your revenue schedule starts in the wrong month.
Identify the performance obligations. Every distinct promise in the contract is its own obligation. A subscription is one. Onboarding might be another. A dedicated CSM might be another. This is the step where SaaS gets messy and I will come back to it.
Determine the transaction price. The total you expect to receive, adjusted for discounts, credits, refunds, and anything variable. Usage overages and performance rebates make this an estimate rather than a fact.
Allocate the price across the obligations. You split the total by standalone selling price, not by what the order form says. If you list onboarding at $10K and discount it to zero to win the deal, the accounting still allocates value to it based on what you normally charge.
Recognise revenue as each obligation is satisfied. Subscription access is satisfied over time, so it goes ratably by day or by month. A one-time deliverable is satisfied at a point in time.
Steps one, two, and four are where your CRM either helps or actively lies. Steps three and five are your CFO's job.
Where SaaS contracts break the model
If every customer signed an identical twelve-month subscription starting on the first of the month, none of this would need an article. They do not. Here are the five patterns that cause almost all the pain, in the order I see them.
Implementation and onboarding fees
The instinct is to book the $15K setup fee as revenue the day the invoice goes out. Usually you cannot.
The test is whether the setup work is distinct. If the activities only get the customer into your product and deliver no standalone value, the fee is not a separate obligation. It gets deferred and recognised over the subscription term, and in some cases over the expected customer life including renewals, which can be longer than the contract.
If the work has genuine standalone value, for example a data migration or a custom integration you would sell to a customer who was not buying the subscription, it can be a separate obligation recognised as the work is delivered.
The practical consequence for RevOps: your CRM needs to distinguish setup fees from subscription fees at the line item level, and it needs a flag for whether the setup work is distinct. Otherwise finance is opening every signed PDF to find out.
Ramp deals
A three-year contract at $2K a month in year one, $4K in year two, $6K in year three is now standard in mid-market SaaS. The customer pays a ramp. The accounting mostly does not.
If the service delivered is the same throughout, revenue is generally recognised evenly across the term rather than following the payment schedule. Total contract value of $144K over 36 months means roughly $4K a month recognised from month one, while you are only invoicing $2K. The difference sits as a contract asset, which is the mirror image of deferred revenue.
I have watched a founder discover this the week before a diligence call and have to restate four quarters. If you sell ramps, your CRM needs the ramp schedule as structured data, not as a sentence in the deal notes.
Multi-year prepay with a discount
A customer pays three years upfront for a 15% discount. Bookings look enormous. Cash looks enormous. Revenue is unchanged in shape, just spread over 36 months at the discounted rate.
The trap here is comp and forecasting rather than accounting. If your reps are paid on total contract value and your board deck reports bookings, a single big prepay makes a quarter look like a breakthrough. Two quarters later the pipeline is empty and nobody saw it coming because the recognised revenue line never moved.
Usage-based and hybrid pricing
Variable consideration is the hardest part of the standard for anyone selling on consumption. You estimate what you expect to receive, constrain the estimate so you are not booking revenue you might have to reverse, and true up as actual usage lands.
In practice, most companies under 100 people recognise usage revenue in the month it is consumed and skip the estimation entirely, which is defensible when usage is billed monthly in arrears. It stops being defensible when you sell prepaid credit pools that expire, because unused credits carry breakage assumptions. If you have moved to consumption pricing, I covered the operational side of this in the usage-based pricing guide.
Mid-term upgrades and downgrades
The customer on a $2K plan upgrades to $5K in month seven. Under the standard this is a contract modification. The remaining unrecognised balance from the original plan gets reallocated across what is left of the term along with the new services, and the monthly figure from month seven is a blend rather than a clean $5K.
This is the one that most billing tools handle badly and most spreadsheets handle wrong. If expansion is a real motion for you, and it should be, see the net revenue retention guide for how to instrument the upstream side of it.
The CRM data model that makes this work
Here is the part nobody writes about, because the people writing about ASC 606 sell accounting software rather than CRM architecture.
The single biggest cause of manual revenue schedules is that the deal record holds one amount field. One number cannot carry a subscription, a services fee, a ramp, and a term. So the CFO opens the contract PDF.
Six fields do most of the work. Put them on the line item object, not the deal.
Service start date and service end date, because close date is when you signed, not when the clock starts. These are different for almost every enterprise deal and the difference is what shifts revenue between quarters.
Obligation type, a picklist with values like subscription, one-time services, distinct services, usage. This is the field that tells finance whether a line is ratable or point in time. Get your deal desk to set it at quote time.
List price and net price as separate fields. The standard allocates on standalone selling price, so finance needs to see the discount rather than only the discounted number. Storing only net price destroys information you cannot recover later.
Billing frequency, because it drives invoicing and deferred revenue while doing nothing to the recognition schedule. Keeping it separate from the recognition fields is what stops people conflating the two.
Ramp schedule, ideally as child records with a period and an amount per period. If that is too heavy, a JSON field that your billing tool reads is better than a note.
HubSpot handles most of this with line item properties and a custom object for ramp periods. I wrote up the modelling patterns in HubSpot custom objects for RevOps. Salesforce users get CPQ or a managed billing package, which is more capable and considerably more expensive to run.
The three-system handoff
At the scale most of our clients operate, revenue data crosses three systems, and every reconciliation problem lives at one of the two joins.
The first join, CRM to billing, breaks when a rep edits a deal after it is closed won. Someone changes the amount, adds a line, or moves the close date, and the subscription in the billing tool no longer matches the contract. Lock closed-won deals down with field-level permissions and route changes through a deal desk. If you do not have one, the deal desk guide covers what a two-person version looks like.
The second join, billing to ledger, breaks when someone issues a credit note or a refund directly in the accounting system without touching the subscription. The GL and the billing tool then disagree forever and every month-end starts with a hunt.
The reconciliation that catches both takes about twenty minutes to build. Once a month, pull total recognised revenue from the billing tool and total revenue from the GL, and compare against the sum of what the CRM says should have been recognised. Three numbers, one report, run on the fifth working day. Any variance over 2% is a data problem worth chasing. We build this as an n8n job that posts the three figures into a Slack channel, which turns a monthly investigation into a monthly glance.
What to do if you are 50 people and this is all news
You do not need NetSuite. You need a sequence.
Two things about the order. The policy document is genuinely more important than the tooling, because it is what turns judgement calls into a repeatable rule that survives your bookkeeper leaving. And step two is the one everyone skips, which is why they end up buying a $30K revenue recognition platform to compensate for a CRM that cannot say when service starts.
One client, a 60-person B2B SaaS company selling into European manufacturing, was spending roughly eleven hours a month on the revenue schedule across their finance lead and an external accountant. Most of that time was reading contracts to answer questions the CRM should have answered. We added the line item fields, backfilled 140 active contracts over two weeks, and wired HubSpot into their billing tool. The month-end close went from eleven hours to about ninety minutes. Nothing about the accounting changed. The data feeding it did.
Spending your month-end reading contract PDFs?
Book a free 30-minute audit. We will look at your CRM data model and show you the three fields that are costing your finance team the most hours.
Book an audit →Frequently asked questions
Does ASC 606 apply to a private company with no investors?
Yes, if you report under US GAAP, which most US companies do the moment they have an external accountant preparing financial statements. Private companies were required to adopt it for annual periods beginning after December 15, 2018. In practice a five-person startup with a bookkeeper on cash basis will not be doing formal revenue recognition, and that is fine until the first institutional round or bank facility, at which point somebody asks for GAAP financials and the restatement is painful. Outside the US the equivalent is IFRS 15 and the mechanics are close enough that the CRM work is identical.
Can we recognise a setup fee upfront if the customer already paid it?
Payment has nothing to do with it. The question is whether the setup work is a distinct performance obligation, meaning it delivers standalone value the customer could get from another vendor or use independently. Pure onboarding that only gets the customer into your product is generally not distinct, so the fee gets deferred and recognised over the subscription term. A genuine data migration or a custom build usually is distinct and can be recognised as delivered. Your accountant makes the call, then you write it into the policy document so it is applied the same way every time.
What is the difference between deferred revenue and a contract asset?
Deferred revenue means you have been paid or invoiced more than you have earned, so you owe the customer service. It is a liability. A contract asset is the opposite: you have earned more than you have invoiced, which is what happens on ramp deals where revenue is recognised evenly while billing starts low. It is an asset. Most SaaS companies only ever see deferred revenue until they sign their first ramp deal, then a new line appears on the balance sheet and everyone spends an afternoon working out what it is.
Do we need a revenue recognition tool, or is a spreadsheet fine?
A spreadsheet is fine up to roughly 50 to 80 active contracts if they are mostly annual subscriptions with clean start dates. It stops being fine when you have ramps, mid-term upgrades, or usage in the mix, because the modification maths compounds and a single error propagates across every future period. My rule of thumb: if your finance lead spends more than four hours a month on the schedule, or if you have ever restated a period, buy the tool. Stripe Billing, Maxio, and Chargebee all handle standard SaaS patterns at reasonable cost. Fix the CRM fields first, otherwise you are paying a tool to consume bad data.
How does revenue recognition affect sales commission?
It should not, and at most companies it does not. Reps are paid on bookings or on invoiced amount, because paying on recognised revenue means paying a three-year deal out over 36 months, which no AE will accept. The related trap is ASC 340-40, which requires you to capitalise the commission cost of obtaining a contract and amortise it over the contract term or the expected customer life. So the rep gets paid in March and the expense shows up in your P&L across the next three years. This surprises founders more than any other part of the standard. If you are redesigning plans, the sales compensation plan guide covers the operational side.
The takeaway
The accounting standard is not the hard part. Your accountant has read it and can apply it. What they cannot do is invent data that your CRM never captured.
If you take one thing from this: go and look at whether your closed-won deals record a service start date separate from the close date. In most HubSpot and Salesforce instances I audit, they do not. That single missing field is why month-end takes a day instead of an hour, and it takes about fifteen minutes to add.
If you want a second pair of eyes on the CRM side of this, our CRM and RevOps work usually starts with exactly this audit, and the automation practice handles the sync and reconciliation layer. Or just get in touch and describe your month-end. We can usually tell you where the time is going in one call.