Territory and quota planning tells a sales organization who owns what and what they are expected to deliver. Incentive compensation is the other half of the same conversation: what each of those people actually gets paid when the numbers land. It is also, in most companies, the single most spreadsheet-bound process left in the revenue function — a monthly cycle of exports, VLOOKUPs, a shared folder of statement PDFs, and a queue of angry emails from reps who think they were shorted.
Anaplan handles incentive compensation well because commissions are, structurally, exactly what Hyperblock is good at: a large sparse transaction set, mapped onto a people hierarchy, run through rules that change by plan and by period. This tutorial walks the build end to end. It assumes you are comfortable with lists, line item subsets, and SUM/LOOKUP, and that a territory and quota model already exists upstream (if not, build that first — comp without quota is guesswork).
What the model has to do
Before any dimension is created, write down the five jobs of an incentive compensation model. Every design decision below traces back to one of them.
- Credit — turn raw closed-won transactions into credited amounts against named payees.
- Measure — roll credit up into period attainment against quota.
- Calculate — apply the plan's rate rules to attainment or credit to produce earnings.
- Adjust — apply draws, caps, clawbacks, holdbacks, disputes, and manual adjustments.
- Explain — produce a statement a rep can read and a control a finance team can audit.
Most failed comp models do the first three and treat the last two as an afterthought. The adjustment and explanation layers are where the operational pain actually lives.
Step 1: The dimensional skeleton
Use a data hub for the transaction feed and a separate spoke model for calculation. Comp transaction volume grows monotonically and you do not want it competing with the rest of your planning estate for workspace.
Core lists in the spoke model:
| List | Type | Notes |
|---|---|---|
Payees | Flat, production list | Every person or entity eligible to be paid. Include terminated payees for the periods they were active. |
Payee Hierarchy | Ragged / composite | Rep → Manager → Director → VP. Drives rollup credit for overlay and management plans. |
Comp Plans | Flat | One member per plan document, e.g. AE Enterprise FY26, SDR FY26, CSM Renewal FY26. |
Plan Components | Flat | The measures inside a plan: New ACV, Renewal ACV, Services Margin, MBO. |
Rate Tiers | Numbered list, T1–T8 | Tier slots, not tier values. Values are data. |
Transactions | Numbered list, production | The credited transaction grain. |
Time | Native | Monthly, with quarterly and annual rollups enabled. |
Two rules that save you a rebuild later:
- Tiers are a numbered list of slots, never hard-coded line items.
T1–T8withThreshold %,Rate %, andIs Activeas data lets comp ops change a plan without a model builder. Line items namedTier 1 Rate,Tier 2 Rateguarantee a change request every plan year. - Plan assignment is time-phased. A payee's plan is a monthly-dimensioned line item formatted as
Comp Plans, not a static property. Mid-year promotions, plan changes, and leaves of absence are normal, and a static assignment silently restates history.
Step 2: Load and stage transactions
The transaction feed from CRM or the billing system lands in the data hub as a flat file: transaction ID, close date, booking amount, currency, product, account, and owning rep ID.
In the hub, build TXN01 Transaction Staging dimensioned by Transactions with line items for each raw attribute. Then add validation line items rather than trusting the source:
Valid Payee? = ISNOTBLANK(Payee Mapped)
Valid Period? = Close Date >= Plan Year Start AND Close Date <= Plan Year End
Valid Amount? = Amount <> 0
Load Error = IF NOT Valid Payee? THEN "Unmapped rep: " & Rep ID Raw
ELSE IF NOT Valid Period? THEN "Out of period"
ELSE IF NOT Valid Amount? THEN "Zero amount" ELSE ""
Include? = Load Error = ""
Publish an exceptions page in the UX filtered to Load Error <> "". Comp ops needs to see and clear rejects before the cycle runs; discovering an unmapped rep after statements have gone out is how trust in the system dies in month two.
Sync only Include? transactions to the calculation model.
Step 3: The crediting engine
Crediting is where the real business logic hides. A single transaction can pay more than one person, and it can pay them different amounts.
Model credit as its own module, CR01 Transaction Credit, dimensioned by Transactions × Credit Roles, where Credit Roles is a small flat list: Direct, Overlay Specialist, SDR Source, Channel Manager, Manager Rollup.
Credit Payee = LOOKUP over the role assignment table by transaction attributes
Credit Rate % = Role default, overridable per transaction by comp ops
Credit Amount = Transaction Amount * Credit Rate %
Credit Period = Booking Date or Invoice Date, per plan's crediting basis
Three decisions to nail down in writing with sales ops before you build:
- Crediting basis. Booked, invoiced, or collected? This decides which date drives
Credit Period, and it is a finance policy, not a modeling preference. - Split policy. Do splits have to total 100%, or can overlays receive incremental credit above 100%? Both are legitimate; build a control total either way so the sum of credit by transaction is visible.
- Manager rollup. Managers usually earn on the rolled-up credit of their team, not on separate transaction credit. Handle this in the attainment layer via the hierarchy rather than duplicating transaction rows.
Then collapse the transaction grain up to the payment grain with a single aggregation module, CR02 Credit by Payee Period, dimensioned Payees × Time × Plan Components:
Credited Amount = SUM over CR01 mapped by Credit Payee, Credit Period, Component
Everything downstream reads this module. The transaction list never appears in the calculation logic again — which is what keeps the calculation layer fast even as transaction volume grows into the millions.
Step 4: Attainment
AT01 Attainment is dimensioned Payees × Time × Plan Components.
Quota (Period) = from the territory and quota model, time-phased
Quota (YTD) = CUMULATE(Quota (Period), Plan Year)
Credit (YTD) = CUMULATE(Credited Amount, Plan Year)
Attainment % = IF Quota (YTD) = 0 THEN 0 ELSE Credit (YTD) / Quota (YTD)
Proration Factor = Active Days in Period / Days in Period
Proration deserves attention. A rep who starts on the 20th of a month, goes on leave, or changes plans mid-quarter should not be measured against a full-period quota. Build Active Days from hire, termination, and leave dates on the payee module and apply the factor to quota, not to credit. Prorating credit makes reps feel robbed of deals they actually closed; prorating quota is the same arithmetic and is universally understood.
Almost every plan pays on year-to-date attainment with a period-to-date true-up rather than on isolated monthly performance. Build it that way from the start:
Earnings (YTD) = calculated by the rate engine below
Earnings (Prior YTD) = PREVIOUS(Earnings (YTD))
Earnings (This Period) = Earnings (YTD) - Earnings (Prior YTD)
This one pattern eliminates the majority of retroactive commission corrections. Late credit, amended deals, and quota restatements all self-correct in the current period rather than requiring someone to reopen a closed month.
Step 5: The tiered rate engine
This is the piece people most often build badly, usually with nested IF statements that break the first time a plan gains a tier.
Create RT01 Plan Rate Table, dimensioned Comp Plans × Plan Components × Rate Tiers, owned by comp ops:
| Line item | Format | Meaning |
|---|---|---|
Tier Active? | Boolean | Is this slot used by the plan |
From Attainment % | Number | Lower bound of the band |
To Attainment % | Number | Upper bound; 999 for the top tier |
Rate % | Number | Commission rate applied within the band |
Type | List: Cliff / Marginal | Whether the rate applies to all credit or only credit in the band |
Then calculate marginal earnings tier by tier in RT02 Tiered Earnings, dimensioned Payees × Time × Plan Components × Rate Tiers:
Plan = payee's plan for the period
Tier From $ = From Attainment % * Quota (YTD)
Tier To $ = To Attainment % * Quota (YTD)
Credit In Tier = MAX(0, MIN(Credit (YTD), Tier To $) - Tier From $)
Earnings In Tier = Credit In Tier * Rate %
And sum the Rate Tiers dimension away:
Earnings (YTD) = SUM of Earnings In Tier over Rate Tiers
The MAX(0, MIN(...)) band-clipping idiom is the whole engine. It handles any number of tiers, any accelerator shape, and a payee at 340% attainment, without a single conditional branch. For cliff-style plans where the top rate applies retroactively to all credit, add a parallel Cliff Earnings line item and select between them with the plan's Type.
Keep the four-dimensional RT02 module lean — five or six line items, no text, no formats you do not need. It is the largest module in the model and the one that will show up in your model size report.
Step 6: Draws, caps, clawbacks, and adjustments
AD01 Payment Adjustments, dimensioned Payees × Time:
Gross Earnings = SUM of Earnings (This Period) over Plan Components
Recoverable Draw = guaranteed minimum for the period
Draw Applied = MAX(0, Recoverable Draw - Gross Earnings)
Draw Recovery = MIN(Draw Balance (Prior), MAX(0, Gross Earnings - Recoverable Draw))
Draw Balance = Draw Balance (Prior) + Draw Applied - Draw Recovery
Clawback = negative credit from churned or cancelled deals, at the original rate
Holdback = % withheld pending collection, released on a lag
Manual Adjustment = comp ops entry, requires Reason Code and Approver
Net Payable = Gross Earnings + Draw Applied - Draw Recovery - Clawback - Holdback + Holdback Release + Manual Adjustment
Cap Applied = MAX(0, Net Payable - Annual Cap Remaining)
Final Payable = Net Payable - Cap Applied
Make Manual Adjustment impossible to use anonymously. A blank Reason Code or Approver should flag the row on an exceptions page and block the cycle from closing. Manual adjustments are legitimate and inevitable; untraceable ones are an audit finding.
Apply Dynamic Cell Access so a payee's own line items are read-only to them, editable to comp ops until the period is locked, and read-only to everyone once Period Status = Paid.
Step 7: Period locking and the cycle
Create a Period Control module dimensioned by Time with a Status line item on a list: Open, In Review, Approved, Paid. Drive DCA everywhere from it.
A workable monthly cycle:
- Day 1–2: transactions load, exceptions cleared, credit rules run.
- Day 3: comp ops reviews attainment and adjustment exceptions; status moves to
In Review. - Day 4–5: managers approve their teams through Anaplan Workflow; disputes are raised in-model against a specific transaction and payee, not by email.
- Day 6: finance approves; status moves to
Approved; the accrual export posts to the GL. - Day 7: payroll file exports; status moves to
Paidand the period locks.
The in-model dispute list is worth building even in a first release. A Disputes numbered list with payee, period, transaction, description, status, and resolution turns the most contentious part of the process into a queue with a cycle time you can measure.
Step 8: Accrual, not just payment
Finance needs an expected commission expense before anyone is paid, and it is rarely equal to the payable amount. Add AC01 Commission Accrual:
Modeled Attainment % = forecast credit / quota, from the sales forecast model
Expected Rate % = blended rate at modeled attainment
Accrual (Period) = Forecast Credit * Expected Rate % * Probability Factor
Accrual True-Up = Actual Earnings (YTD) - Accrual Posted (Prior YTD)
Because accelerators mean a rep at 130% attainment costs disproportionately more than one at 95%, a straight-line accrual at target rate understates expense in a strong year and overstates it in a weak one. Running the accrual through the same tier engine at forecast attainment is a small amount of extra work and one of the clearest pieces of value the model delivers to the CFO's office.
Step 9: The statement page
A rep should be able to answer three questions without contacting anyone: what am I getting paid, why is it that number, and which deals are in it.
Build one UX page, My Commission Statement, with selective access so each payee sees only their own rows:
- Header: period, plan name, quota, credit, attainment %, final payable, draw balance.
- Waterfall chart: gross earnings → draw → clawback → holdback → adjustments → final payable.
- Tier breakdown grid: each active tier with credit in tier, rate, and earnings in tier. This is the single highest-value element on the page — it answers "why that number" mechanically.
- Transaction detail grid: every credited transaction with account, amount, credit rate, credit amount, and credit date, filtered to the payee and period.
- Dispute button: an action that writes a row to the
Disputeslist with the selected transaction pre-filled.
Statement transparency is a performance feature as much as an operational one. Reps who can see their tier position mid-quarter sell differently than reps who find out in arrears.
Performance notes specific to comp models
- Never calculate on the
Transactionslist beyond crediting. Aggregate toPayees×Timeonce, in one module, and reference that everywhere else. - Archive closed plan years into a separate model annually. Comp transaction volume is the fastest-growing data in most Anaplan estates.
- Use line item subsets rather than duplicating plan-component logic per plan.
- Watch the size of the four-dimensional tier module. If
Payees×Time×Components×Tiersgets uncomfortable, reduceRate Tiersto the maximum number any live plan actually uses rather than a generous eight. - If your payee population is large and sparse across plans — tens of thousands of payees on a handful of components — this is one of the workloads where Polaris is worth evaluating against Hyperblock before you commit.
Common design mistakes
Hard-coding plan rules in formulas. Plans change every year and mid-year. Anything a comp ops analyst might need to change should be a data entry in a rate or rule table, not a formula. If a plan-year rollover requires a model builder, the design has failed.
One plan per payee, forever. Time-phase the assignment. Promotions and plan changes are routine and a static assignment quietly restates prior periods.
Paying on period attainment instead of YTD with true-up. Guarantees a permanent backlog of retroactive corrections.
No dispute trail. If disputes live in email, you cannot measure or reduce them, and you cannot answer an auditor asking why a payment changed.
Ignoring terminated payees. They still need statements, final payments, draw recovery, and clawback exposure for periods they were active. Keep them in the list with a status, do not delete them.
Where to start
Build one plan end to end — usually the standard AE plan, since it covers the largest population — and run it in parallel with the existing spreadsheet for two full cycles before cutting over. Reconcile to the cent and investigate every variance; roughly half of them will turn out to be errors in the spreadsheet, which is both reassuring and a useful thing to be able to show the sponsor. Then add plan types one at a time.
If you are scoping an incentive compensation build, migrating off a legacy SPM tool, or trying to rescue a comp model that has become a maintenance burden, get in touch — our Anaplan consultants have built and stabilized comp engines across sales, channel, and services organizations.