+1 (726) 224-7339

Building a SaaS ARR and Revenue Model in Anaplan: Bookings-to-ARR Bridge, Cohort Retention, and Deferred Revenue

Every SaaS finance team eventually hits the same wall. The CRM knows about bookings. The billing system knows about invoices. The GL knows about recognised revenue. Nobody owns the number in the middle — ARR — and so the board deck, the revenue forecast, and the deferred revenue schedule are built in three different spreadsheets that reconcile only by coincidence.

Anaplan is a natural home for this because the bridge between those numbers is exactly a planning problem: a contract-level dataset, a customer hierarchy, and a set of rules about timing. This tutorial builds a SaaS revenue and ARR planning model end to end — the bookings-to-ARR bridge, the movement waterfall (new, expansion, contraction, churn), cohort retention and NRR, subscription revenue recognition under ASC 606 / IFRS 15, deferred revenue and billings, and the forecast layer that projects all of it forward.

It assumes you are comfortable with lists, SUM/LOOKUP, time ranges, and a layered model structure. If your model does not yet have a clear System layer, read the DISCO blueprint first.

Agree the definitions before you build

More SaaS models fail on definitions than on formulas. Get these written down and signed off by the CFO before any list is created, because every one of them changes the arithmetic.

  • ARR basis. Annualised value of committed recurring subscriptions, as at a point in time. Decide explicitly whether it includes usage-based revenue (most companies exclude it, or include only a committed floor), professional services (almost always excluded), and contracts in a notice period (usually included until the termination date).
  • ARR effective date. Does a contract count as ARR from its signature date or its service start date? Service start is the more defensible answer and the one that makes ARR reconcile to revenue.
  • Expansion vs. new. An upsell to an existing customer is expansion. A new logo in the same parent group is a judgement call — decide once, at parent or at billing-entity level, and apply it consistently.
  • Churn timing. Recognise churn at the end of the paid term, not at the date notice is received. Otherwise the current period gets punished for cancellations that are still generating revenue.
  • Currency. ARR is a point-in-time metric, so it is normally reported at a frozen plan rate rather than a moving spot rate, precisely so that movement analysis shows customer behaviour, not FX. If your group reports in several currencies, this is worth reading alongside multi-currency FX translation.

Write each definition into the line item description in Anaplan as you build. That is the cheapest documentation you will ever produce, and it survives staff turnover.

Step 1 — The dimensional skeleton

Keep contract data in a data hub and calculate in a spoke model. Contract volume grows every quarter and you do not want it competing with the planning estate.

ListTypeNotes
Contract LinesNumbered, productionThe grain of truth: one row per subscription line, per term.
CustomersFlat, productionInclude churned customers; history must not disappear.
Customer HierarchyCompositeCustomer → Segment → Region.
CohortsFlatOne member per month of first ARR, e.g. 2024-03.
ProductsFlatWith a Revenue Type property: Subscription / Usage / Services.
Movement TypesFlatNew, Expansion, Contraction, Churn, Renewal, Price Uplift, FX.
TimeNativeMonthly, with a separate longer time range for contracts that run beyond the plan horizon.

The Movement Types list is the design decision that pays for itself. Once movement is a dimension rather than a set of line items, the waterfall, the NRR calculation, the board chart, and the forecast all read from one module instead of four parallel ones.

Step 2 — Contract staging and validation

In the hub, build SYS01 Contract Staging dimensioned by Contract Lines, holding the raw attributes: customer ID, product, contract start, contract end, term months, billing frequency, total contract value, annual value, currency, and a source system key.

Then validate rather than trust:

Valid Customer?   = ISNOTBLANK(Customer Mapped)
Valid Dates?      = Contract End > Contract Start
Valid Term?       = Term Months > 0
Sane ACV?         = ABS(Annual Value - (TCV / Term Months * 12)) < 1
Load Error        = IF NOT Valid Customer? THEN "Unmapped customer: " & Customer Raw
                    ELSE IF NOT Valid Dates? THEN "End date before start"
                    ELSE IF NOT Valid Term? THEN "Zero or negative term"
                    ELSE IF NOT Sane ACV? THEN "TCV and ACV disagree" ELSE ""
Include?          = Load Error = ""

Publish the rejects on a UX page filtered to Load Error <> "". A SaaS model that silently drops three contracts a month will be quietly abandoned within two quarters, because the ARR will never match what the CRO believes.

Step 3 — Spread contracts into a point-in-time ARR position

This is the core calculation, and the part most teams get structurally wrong by trying to do everything at contract-line grain.

Build CAL10 Contract ARR dimensioned Contract Lines × Time, with exactly one meaningful line item:

Active?     = Contract Start <= END(Period) AND Contract End >= START(Period)
ARR         = IF Active? AND Revenue Type = Subscription THEN Annual Value ELSE 0

Then collapse to the reporting grain immediately, in CAL11 Customer ARR, dimensioned Customers × Time × Products:

ARR Closing = SUM of CAL10.ARR mapped by Customer and Product
ARR Opening = PREVIOUS(ARR Closing)
ARR Delta   = ARR Closing - ARR Opening

After this module the contract list never appears in downstream logic again. That single rule is what keeps the model fast as contract volume grows into the hundreds of thousands, and it is the same discipline described in formula performance tuning.

Step 4 — Classify the movement

Now turn ARR Delta into the waterfall. Build CAL12 ARR Movement dimensioned Customers × Time × Movement Types, and classify with a small set of mutually exclusive rules:

Is New?          = ARR Opening = 0 AND ARR Closing > 0 AND First ARR Month = CURRENTPERIODSTART()
Is Reactivation? = ARR Opening = 0 AND ARR Closing > 0 AND First ARR Month < CURRENTPERIODSTART()
Is Churn?        = ARR Opening > 0 AND ARR Closing = 0
Is Expansion?    = ARR Closing > ARR Opening AND ARR Opening > 0
Is Contraction?  = ARR Closing < ARR Opening AND ARR Closing > 0

Movement Amount  = IF Movement Type = New          AND Is New?          THEN ARR Delta
                   ELSE IF Movement Type = Churn   AND Is Churn?        THEN ARR Delta
                   ELSE IF Movement Type = Expansion AND Is Expansion?  THEN ARR Delta
                   ELSE IF Movement Type = Contraction AND Is Contraction? THEN ARR Delta
                   ELSE IF Movement Type = Reactivation AND Is Reactivation? THEN ARR Delta
                   ELSE 0

Then the control that makes the whole thing trustworthy:

Waterfall Check = ARR Opening + SUM(Movement Amount over Movement Types) - ARR Closing

Waterfall Check must be zero for every customer and every period. Put it on an admin page with conditional formatting. If it is not zero, your classification rules overlap or leave a gap, and you will find out now rather than in a board meeting.

Two refinements worth adding in a second release:

  • Split expansion into seats and price. If the contract data carries quantity and unit price, Volume Expansion = Δqty × prior price and Price Expansion = Δprice × current qty turns a single number into an actionable one. Pricing teams will use it immediately.
  • Separate renewal from expansion. A flat renewal is not growth, but it is the single most important leading indicator of retention risk. Track renewal ARR up for renewal and renewed ARR as their own line items in the same module.

Step 5 — Cohorts, NRR, and GRR

Cohort retention is where ARR data becomes a story about the business rather than a number.

Stamp each customer with a cohort once, in a System module — First ARR Month, derived from the earliest period where ARR Closing > 0, held as a list-formatted Cohorts line item. Stamp it, do not recalculate it live; a customer's cohort must never move.

Then CAL20 Cohort Retention, dimensioned Cohorts × Time:

Cohort Starting ARR    = SUM of ARR Closing at cohort month for customers in cohort
Cohort Current ARR     = SUM of ARR Closing in current period for customers in cohort
Net Revenue Retention  = IF Cohort Starting ARR = 0 THEN 0
                         ELSE Cohort Current ARR / Cohort Starting ARR
Gross Revenue Retention= (Cohort Starting ARR - Churn - Contraction) / Cohort Starting ARR
Logo Retention         = Customers Active Now / Customers in Cohort

Three things to get right:

  1. GRR is capped at 100% by construction. It excludes expansion. If your GRR exceeds 100%, you have let expansion leak into the numerator.
  2. Report trailing-twelve-month NRR alongside cohort NRR. They answer different questions — TTM NRR is what investors ask for; cohort NRR is what tells you whether last year's customers were better than the year before's.
  3. Exclude the partial first month. A cohort's starting ARR should be measured at the end of its first full month, or new customers who signed on the 28th will distort the curve.

The classic triangle chart — cohorts down, months since start across — is a straightforward UX grid off this module, and it is usually the first thing an investor asks to see.

Step 6 — Revenue recognition and deferred revenue

ARR is a management metric. Revenue is an accounting one. The model earns its keep by producing both from the same contract data, which is what makes them reconcile.

For a standard ratable SaaS subscription, CAL30 Revenue Recognition, dimensioned Contract Lines × Time:

Months in Term       = term length from staging
Monthly Revenue      = IF Active? THEN TCV Allocated / Months in Term ELSE 0
Days in Period Adj   = for part months, Active Days in Period / Days in Period
Recognised Revenue   = Monthly Revenue * Days in Period Adj

TCV Allocated is not simply TCV. Under ASC 606 the transaction price is allocated across performance obligations by standalone selling price, which matters the moment a contract bundles a subscription with implementation services or a discounted first year. Hold the allocation percentages in a rate table owned by revenue accounting, not in a formula:

Allocated Amount = Contract TCV * SSP Allocation % [by Product, by Contract]

Then billings and deferred revenue:

Billed Amount     = from the billing schedule: invoice dates and amounts
Deferred Opening  = PREVIOUS(Deferred Closing)
Deferred Closing  = Deferred Opening + Billed Amount - Recognised Revenue
Unbilled / Accrued= MAX(0, Recognised Revenue Cumulative - Billed Cumulative)

And the control every auditor will look for:

Deferred Rollforward Check = Deferred Opening + Billed - Recognised - Deferred Closing

Zero, every entity, every period. Same discipline as the balance sheet check in an integrated three-statement model — and if you have built that model, deferred revenue and unbilled AR should feed it directly rather than being re-derived.

Step 7 — The forecast layer

Everything so far is history. The forecast is a separate module that must never write into the actuals modules.

Build FOR10 ARR Forecast, dimensioned Customers (or Segment, for a driver-based approach) × Time × Movement Types, and forecast each movement type with a method suited to it:

MovementForecast driver
New ARRPipeline × win rate × average deal size, or a rep-capacity model from your territory and quota model
Expansion% of opening ARR, by segment, from historical rates
Contraction% of ARR up for renewal, by segment
ChurnRenewal-cohort based: ARR up for renewal × (1 − renewal rate)
Price upliftContractual uplift % applied at the anniversary date

The renewal-based churn method is the important one. Forecasting churn as a flat percentage of total ARR each month is the single most common error in SaaS models, and it is wrong because churn can only occur when a contract reaches its renewal date. Build a Renewal Schedule module from contract end dates, forecast a renewal rate against it, and churn becomes both more accurate and defensible in a board meeting.

Then close the loop: forecast ARR spreads into forecast revenue using the same recognition logic, so the P&L forecast and the ARR forecast can never diverge. That is the whole reason to build this in Anaplan rather than in three spreadsheets.

Step 8 — Scenarios and the reporting layer

Keep the scenario dimension small and on the forecast modules only — Budget, Current Forecast, Upside, Downside. Do not dimension the contract-grain actuals modules by scenario; it multiplies the largest modules in the model for no benefit. The same time-range and versions discipline applies here as in building a rolling forecast that doesn't bloat.

The reporting pages that get used, in order of value:

  • ARR waterfall — opening, new, expansion, contraction, churn, closing, as a bridge chart, sliceable by segment and region.
  • NRR / GRR trend — TTM, twelve rolling periods, with segment breakdown.
  • Cohort triangle — retention by cohort by month since start.
  • Revenue vs. ARR reconciliation — the bridge from closing ARR to recognised revenue for the period, showing timing, services, and usage as reconciling items. Finance will ask for this on day one.
  • Deferred revenue rollforward — opening, billed, recognised, closing, with the check line item visible.

Performance notes specific to SaaS models

  • Calculate at Contract Lines grain exactly twice — once to determine active ARR, once for revenue recognition — and aggregate immediately after each.
  • Use a longer time range for contract-grain modules (contracts run past the plan horizon) and the standard model calendar everywhere else. Do not extend the whole model calendar to cover a five-year contract.
  • Turn summaries off on ratio line items: NRR, GRR, retention rates, win rates. A summed retention percentage is meaningless and expensive.
  • Archive closed contract years into a separate model annually, as with any transaction-grain estate.
  • If your customer count is very large and very sparse across products — hundreds of thousands of customers on a handful of SKUs — this is a workload worth benchmarking before you commit; see Hyperblock or Polaris.

Common design mistakes

Treating ARR as a sum of bookings. Bookings are a flow over a period; ARR is a stock at a point in time. Deriving one from the other by addition works until the first mid-term upsell and then never again. Always calculate ARR as a point-in-time position from active contracts.

Letting movement classification overlap. Without the Waterfall Check control, a customer who churns one product while expanding another will be double-counted, and nobody will notice for months.

Recalculating cohorts live. A customer's cohort is stamped once. If it recalculates, historical retention curves change every month and the chart loses all credibility.

Forecasting churn as a flat rate on total ARR. Churn happens at renewal. Model the renewal schedule.

Building ARR and revenue in separate models. They must come from the same contract data, or reconciling them becomes a monthly manual exercise — which is exactly the work you were trying to eliminate.

The short version

One contract dataset, validated on load. Point-in-time ARR calculated at contract grain and aggregated immediately. Movement as a dimension, with a waterfall check that must be zero. Cohorts stamped once. Revenue recognition and deferred revenue derived from the same contracts, with a rollforward control. A forecast layer that is structurally separate and models churn at renewal. Get those six right and the board pack, the revenue forecast, and the audit file all agree — which, for most SaaS finance teams, is a first.

Where we help

We build SaaS revenue, ARR, and deferred revenue models in Anaplan for subscription businesses from Series B through public company reporting — including the bookings-to-ARR bridge, cohort retention, ASC 606 allocation logic, and the controls that let finance sign off on it. It sits at the centre of our Anaplan for the Office of the CFO and Anaplan Model Designing and Building work. If your ARR number currently comes from a spreadsheet that only one person understands, get in touch.