
SaaS revenue recognition is straightforward until you read an actual contract.
The textbook case is clean. 12 months, fixed fee, billed annually in advance, recognised evenly. Any system handles it, and the deferral schedule writes itself.
Then a real contract arrives. 14 months, because the customer wanted the renewal date to line up with their fiscal year. A usage component above a committed floor. An upgrade in month 5 that changes the rate for the remaining term. A discount applied to year 1 only. No list price anywhere in the business, because pricing is negotiated every time.
Software and IT services make up close to 60% of Light's prospect base, and this is what their contracts look like.
of Light's identified prospects are software and IT services companies
to process revenue at Famly, per Rasmus Vogt, the company's VP Finance
revenue in the books at Tillo, across 750 to 900 invoices a month
Where standard tooling gives up
Not on the accounting. On the contract shapes.
Most revenue tools assume a term measured in whole years, a price that exists on a rate card, and a billing rhythm that does not change mid-contract. Every one of those assumptions is routinely false at a growing SaaS company, and the failure mode is always the same: the contract that does not fit gets handled manually, and manual handling migrates to a spreadsheet.
Dreamdata is a precise example. It invoices from Light and does not yet run the contracts module, because its terms need 13 and 14 month recurrences and it has no list prices anywhere in the business. That is work in flight, being built with them. It is also exactly the class of requirement that most vendors quietly leave in the too-hard column, which is how a finance team ends up with a revenue engine and a spreadsheet.
All Gravy hit the same wall from the invoicing side. Its contract terms were too bespoke for standard tools to generate correctly, so invoicing stayed manual for years. The team's answer was to build its own CPQ tool and connect it directly to the ledger.
The spreadsheet is a second ledger
Whatever holds the terms the general ledger does not have is a second ledger, whether or not anybody calls it one.
It has 1 row per contract, columns per month, a formula spreading the amount, and a journal posted monthly from the total. It is maintained by hand and it drifts. A contract amended in March gets updated in the CRM, invoiced correctly, and forgotten in the deferral model until somebody notices in Q4 that the release schedule no longer matches the invoices.
Every SaaS finance team running this has a story about the reconciliation that took a week, usually discovered during an audit.
Famly cut revenue processing from 20 hours to 15 minutes. Tillo has revenue in the books on T+1, across 750 to 900 invoices a month.
The textbook case
12 months, fixed, even
Handled by anything. Also a minority of the contracts a growing SaaS company signs.
The real case
13 months, usage, mid-term upgrade
Falls outside the tool, gets handled by hand, and the handling moves into a spreadsheet that drifts from the contract.
What fixes it
Recognition from the contract
Release templates unwind the deferral month by month from the contract itself, so an amendment propagates rather than needing a second update.
The ARR question
The other thing SaaS finance carries is 2 revenue numbers.
There is ARR, built in a warehouse from CRM and product data, which the board manages against. And there is recognised revenue, built in the ledger from invoices and deferrals, which the auditor sees. They come from different sources on different cadences and diverge by a few percent, which is fine until somebody has to bridge them.
Dreamdata's Peter Egehoved calls this two world syndrome, and names the moment it hurts: every time an auditor shows up and asks him to walk through that ARR number. The walk is a reconstruction rather than a trace, because the 2 numbers were derived independently.
When contracts, invoices, payments and recognition sit in the same ledger the walk becomes a lookup. An ARR figure resolves to the contracts behind it, each contract to its invoices, each invoice to the payment that settled it, and each period's recognition to the schedule the contract generated. The auditor pulls 100% of the journal population through the API and tests the calculation rather than rebuilding the inputs.
What still needs a person
Plenty, and this is the part worth protecting.
Whether a multi-element arrangement has distinct performance obligations. How to allocate consideration across them when there is no standalone selling price, which is the normal situation when nothing has a list price. Whether a usage tier represents variable consideration that should be estimated or a separate obligation. Whether a mid-term upgrade is a modification or a new contract.
Those are judgment calls and they should stay judgment calls. The reason to automate the mechanical part is that a team spending its month maintaining schedules has no attention left for the contracts that genuinely need thinking about, and those are the ones that end up restated.
The test
Take the 5 least standard contracts signed last year. For each, ask where the recognition schedule lives and what happens when it gets amended.
If the answer involves a spreadsheet, or updating 2 systems, the revenue number is only as reliable as somebody remembering to do both. That is a fine arrangement at 20 contracts and an audit finding at 300.
See how contracts, billing and revenue connect, read about deferred revenue that unwinds itself, or book a demo.