Personnel cost is usually 50-70% of operating expense in a services or software business, and it is almost always the worst-modeled part of the plan. Finance holds a headcount spreadsheet, HR holds a requisition tracker, and the FP&A model carries a single "salaries" line that nobody can decompose. When the CFO asks what happens to next year's EBITDA if 40 open roles slip by one quarter, the answer takes three days.
Workforce planning is one of the best first or second Anaplan use cases precisely because it is driver-based, cross-functional, and painful to do anywhere else. This tutorial is a build guide: the list architecture decision that determines whether the model scales, the module stack, the formulas that matter, and the reconciliation that makes Finance trust the output.
Assume a company of roughly 2,500 employees, 300 cost centers, monthly time, a two-year horizon, and managers who will do their own hiring plans.
Step 1: Decide what a row is
Everything downstream depends on this. There are three common granularities, and picking the wrong one is the single most expensive mistake in a workforce model.
| Grain | List size | Good for | Watch out for |
|---|---|---|---|
| Employee-level | One item per current employee plus planned hires | Precise loaded cost, compensation review, manager-by-manager plans | List churn every payroll cycle; sparsity across cost centers |
| Position-level | One item per filled or open position (requisition) | Recruiting alignment, backfill tracking, org design | Requires discipline in the HR system to keep position IDs stable |
| Role/grade-level | One item per job family x grade x location | Long-range and top-down capacity planning | Cannot answer "which person" questions; averages hide outliers |
The pattern that works for most implementations is position-level for the operating plan, role-level for the long-range plan, with employee attributes carried as properties of the position rather than as a separate dimension. A position exists whether or not somebody sits in it, which is exactly what a plan needs. Filled positions carry an employee ID property; open positions carry a start-date assumption.
Critically, model the position list as a flat list with a SYS mapping module, not as a composite hierarchy under cost center. Positions move between cost centers during reorganizations, and a flat list plus a mapping line item survives that. It is also the only version that plays nicely with Application Lifecycle Management, because the position list is a production list your target model owns.
Step 2: The module stack
Follow DISCO — Data, Inputs, System, Calculations, Outputs — so the model stays legible and fast. A workable stack:
System modules (SYS)
SYS01 Time Settings by Month— line items:Month Index,Is Current Month?,Is Future Month?,FY,Quarter,Days in Month.SYS02 Position Details(dimension: Position) —Employee ID,Cost Center,Job Family,Grade,Location,Status(Filled / Open / Approved-not-open),Manager,Is Filled?.SYS03 Cost Center Mapping—Function,Region,P&L Owner.
Data modules (DAT)
DAT01 Employee Actuals by Month— imported payroll actuals by position and month: base pay, bonus paid, employer taxes, benefits.DAT02 Comp Benchmarks by Grade and Location— midpoint salary, benefit load %, employer tax rate %.
Input modules (INP)
INP01 Position Plan(Position x no time) —Planned Start Month,Planned End Month,Planned FTE,Planned Base Salary,Bonus Target %,Recruiting Cost.INP02 Assumptions by Cost Center and Month—Merit Increase %,Attrition Rate % (annualized),Backfill Rate %,Contractor Rate.INP03 Top-Down Headcount Target(Cost Center x Quarter) — for the reconciliation described later.
Calculation modules (CAL)
CAL01 FTE Phasing by Position and MonthCAL02 Personnel Cost by Position and MonthCAL03 Attrition and Backfill by Cost Center and MonthCAL04 Cost Center Rollup by Month
Output modules (REP)
REP01 Headcount and Cost by Cost Center,REP02 Bridge vs Prior Plan,REP03 Recruiting Pipeline View.
Only CAL01 and CAL02 are dimensioned by Position x Month. Everything else aggregates. That single restraint is usually the difference between a model that recalculates in two seconds and one that takes forty.
Step 3: FTE phasing
A position should contribute cost only in the months it exists, and a mid-month start should not cost a full month. In CAL01 FTE Phasing, dimensioned by Position and Month:
// Boolean: is this position active in the month?
Is Active? =
SYS01.Month Index >= INP01.Planned Start Month Index
AND (INP01.Planned End Month Index = 0
OR SYS01.Month Index <= INP01.Planned End Month Index)
// Fraction of the month worked (handles mid-month starts)
Month Fraction =
IF NOT Is Active? THEN 0
ELSE IF SYS01.Month Index <> INP01.Planned Start Month Index THEN 1
ELSE (SYS01.Days in Month - DAY(INP01.Planned Start Date) + 1)
/ SYS01.Days in Month
// Cost-weighted FTE, and a clean point-in-time headcount
Cost FTE = INP01.Planned FTE * Month Fraction
Closing FTE = IF Is Active? THEN INP01.Planned FTE ELSE 0
Keep Cost FTE and Closing FTE separate and label them clearly. Half the disputes in workforce reviews come from Finance quoting average FTE while HR quotes closing headcount for the same month. Publish both, name them unambiguously, and put the definition in the page description.
If you want a productivity ramp for new hires — common in sales capacity planning — add Productive FTE = Cost FTE * Ramp % where Ramp % comes from a small SYS04 Ramp Curve by Months Since Start module. Look it up by months-since-start rather than writing nested IFs; a lookup against a tiny module is faster and editable by the business.
Step 4: Fully loaded cost
In CAL02 Personnel Cost by Position and Month, layer the components rather than computing one blended number. Every component becomes an auditable line on the P&L bridge.
Base Salary =
IF SYS01.Is Future Month? THEN
(INP01.Planned Base Salary / 12) * Merit Factor * CAL01.Cost FTE
ELSE DAT01.Base Pay Actual
// Merit applied from the review month forward, compounding by year
Merit Factor = CUMULATE(1 + INP02.Merit Increase % , SYS01.Is Merit Month?, TRUE)
Bonus = Base Salary * INP01.Bonus Target % * INP02.Bonus Payout Factor %
Employer Tax = (Base Salary + Bonus) * DAT02.Employer Tax Rate %
Benefits = DAT02.Benefit Cost per FTE per Month * CAL01.Cost FTE
Recruiting = IF SYS01.Month Index = INP01.Planned Start Month Index - 1
THEN INP01.Recruiting Cost ELSE 0
Total Loaded Cost = Base Salary + Bonus + Employer Tax + Benefits + Recruiting
Three build notes that save rework:
- Actual-versus-forecast switchover belongs in one place. Drive it off
SYS01.Is Future Month?and nothing else, so that closing a month is a single calendar update rather than a formula edit. If you run versions, pair this with the switchover setting described in our tutorial on versions, scenarios, and time ranges. - Never put text formulas in a Position x Month module. Names, titles, and status labels live in
SYS02with no time dimension. Text line items across 2,500 positions x 24 months are pure waste — see formula performance tuning for the measurement approach. - Benefits per FTE, not per position. A part-time position should carry a part-time benefit load, and driving off
Cost FTEgets that free.
Step 5: Attrition and backfill
Naming individual leavers in a plan is both wrong and awkward. Model attrition statistically at the cost-center level and let it offset the position-level build-up.
// CAL03, dimensioned Cost Center x Month
Opening FTE = PREVIOUS(Closing FTE)
Gross Attrition = -Opening FTE * (1 - (1 - INP02.Attrition Rate %) ^ (1/12))
Backfill Hires = -Gross Attrition * INP02.Backfill Rate %
-> lagged by Time Ranges via OFFSET(..., -INP02.Time to Fill Months, 0)
Net Attrition = Gross Attrition + Backfill Hires
Closing FTE = Opening FTE + CAL01 Planned Hires + Net Attrition
Use the monthly-equivalent conversion rather than dividing the annual rate by 12; over a two-year horizon the difference is material and CFOs notice. Expose Time to Fill Months as an input by job family — it is the assumption that moves the plan most, and it is the one recruiting can actually defend.
Step 6: Reconcile top-down to bottom-up
The model earns trust the moment it can explain the gap between the CFO's headcount envelope and what managers have actually planned. Build REP02 as a variance module dimensioned by Cost Center and Quarter:
Top-Down Target FTE = INP03.Top-Down Headcount Target
Bottom-Up Planned FTE = CAL04.Closing FTE
Gap FTE = Bottom-Up Planned FTE - Top-Down Target FTE
Gap Cost = Gap FTE * CAL04.Average Loaded Cost per FTE
Status = IF Gap FTE > 0 THEN "Over envelope"
ELSE IF Gap FTE < 0 THEN "Headroom" ELSE "On plan"
Then add a decision bridge from prior plan to current plan with fixed drivers: merit, promotions, timing shifts, new roles, attrition, backfill, contractor conversion, FX. A bridge with named drivers ends arguments; a single variance number starts them.
Step 7: The manager experience
Managers abandon workforce models that ask too much. Ship three UX pages, not thirty.
- My Team (worksheet) — a filtered grid of the manager's positions with
Planned Start Month,Planned FTE,Planned Base Salary, andStatus. Add row for a new requisition, nothing else editable. - My Cost Summary (board) — loaded cost by month, headcount by quarter, gap to envelope, one chart, one KPI card.
- Submit (board) — a validation panel that blocks submission on missing start dates or salaries outside the grade band, wired to Anaplan Workflow.
Lock everything else with Dynamic Cell Access rather than roles: closed months read-only, salary fields visible only to HR-cleared roles, requisition fields editable only while the cycle is open. The pattern is in our Dynamic Cell Access tutorial, and the approval routing in building approval chains with Anaplan Workflow.
Salary confidentiality is the reason most workforce models get paused. Decide on day one whether managers see individual salaries or only cost-center aggregates, and enforce it with selective access plus DCA — not by hiding a line item on a page.
Step 8: Integration and cadence
- Inbound weekly: the HR system (Workday, SuccessFactors, BambooHR) feeds the position list, employee attributes, and status. Import into the flat position list with a code-based action, and never let the model create positions that HR does not know about.
- Inbound monthly: payroll actuals by position and cost element, plus the GL for reconciliation.
- Outbound monthly: loaded cost by cost center and account into the P&L model or the data warehouse.
Schedule these through Data Orchestrator or CloudWorks rather than manual imports — the trade-offs are covered in our integration tooling comparison. Reconcile personnel cost to the GL every month within a defined tolerance and publish the variance. A workforce model that is never tied back to actuals quietly becomes fiction inside two quarters.
Common failure modes
- Employee list as a composite child of cost center. The first reorganization breaks the model. Use a flat list plus mapping.
- One blended cost-per-head. Fast to build, impossible to defend, and useless for scenario work on grade or location mix.
- No open-position concept. If only filled positions exist, the model cannot answer the hiring-delay question — the most common question asked of it.
- Position x Month x Cost Element x Scenario. Four dimensions on a detail module explodes cell count. Keep cost elements as line items, and hold scenarios at the cost-center summary level.
- Modeling termination dates for named individuals. Legally sensitive and analytically unnecessary. Attrition is a rate.
A realistic delivery timeline
| Week | Work |
|---|---|
| 1 | Grain decision, list architecture, HR extract specification |
| 2-3 | SYS and DAT modules, position list import, payroll actuals load |
| 4-5 | CAL01 and CAL02, loaded cost validated against one month of payroll |
| 6 | Attrition, backfill, top-down reconciliation |
| 7 | UX pages, DCA, Workflow |
| 8 | UAT with three pilot cost centers, GL reconciliation, ALM release to production |
Eight weeks is achievable when the HR extract is available in week one. It is not achievable when the position list has to be reconstructed from spreadsheets, which is the usual delay — start that conversation before the kickoff.
QuanticPlanning builds workforce and personnel-cost models on Anaplan for Finance and HR teams, including grain and list architecture decisions, HR and payroll integration, and manager rollout. If you are scoping a workforce planning build, or you have one that cannot reconcile to the GL, get in touch.