Analytics Catalog/Workday/Payroll/Payroll Cost Trend & Variance
Explore the catalogModulesPayrollGL ReconciliationPayroll ResultHeadcount
Workday · Payroll · Report

Payroll Cost Trend & Variance

Why payroll moved. The month-over-month answer decomposes into people and rates, once the one-time noise is pulled out and named, and it must sum back to the delta exactly or it explains nothing.

RuleTrend fully loaded cost on the earned-for view, with retro, off-cycle, and overtime shown as their own lines before the decomposition.Neverpublish a variance bridge that does not sum to the delta. An almost-explained variance is an unexplained variance.
Getting the trend honest first— the view, the one-time lines, and the FTE denominator.
DecisionWhy it matters
Earned-for viewLabor cost belongs to the period the work happened. This view restates prior months when retro pay lands; that is a feature, and the report shows the restatement rather than hiding it. The paid-in view answers cash questions and gets its own column, never a blend.
One-time lines outRetro catch-ups, off-cycle payments, and severance distort a trend read. They stay in total cost, shown as named lines above the run-rate, so the decomposition works on the recurring base.
Overtime separatedAn overtime spike is an operations story, not a compensation story. Its own line, read next to the Overtime report.
FTE, not headsThe people factor uses full-time equivalents from the snapshot. Two part-time hires are one FTE of cost pressure, and a heads-based bridge misstates it.
The decomposition, and the SQL— two factors, exact by construction, on the payroll fact and the snapshot.

Cost is FTE times cost per FTE, so the month-over-month change splits into a people effect priced at last month's rate and a rate effect on this month's people. Priced that way, the two terms sum to the delta exactly:

-- month-over-month bridge: recurring fully loaded cost, decomposed
WITH m AS (
  SELECT f.earned_for_period_key AS period,
         SUM(f.amount)           AS cost,
         MAX(s.fte)              AS fte
  FROM fct_payroll_result f
  JOIN dim_pay_component pc ON f.pay_component_key = pc.pay_component_key
  JOIN (SELECT date_key, SUM(fte) AS fte FROM fct_worker_snapshot GROUP BY 1) s
       ON s.date_key = f.earned_for_period_key
  WHERE pc.in_fully_loaded
    AND NOT pc.is_one_time AND NOT pc.is_overtime
    AND f.earned_for_period_key IN (202604, 202605)
  GROUP BY 1
)
SELECT curr.cost - prev.cost                              AS delta,
       (curr.fte - prev.fte) * (prev.cost / prev.fte)     AS fte_effect,
       (curr.cost / curr.fte - prev.cost / prev.fte) * curr.fte AS rate_effect
FROM m curr JOIN m prev ON prev.period = 202604 AND curr.period = 202605

Sample output, April to May, the months the rest of the catalog uses:

AprilMaybridge
Recurring cost2,044,8002,086,340+41,540
FTE144.0146.0FTE effect +28,400
Cost per FTE14,20014,290Rate effect +13,140

28,400 plus 13,140 is 41,540: the bridge closes. The people effect is the two May hires the Movement report nets out; the rate effect is the merit cycle landing in run-rate. A variance the bridge cannot place goes back to the one-time lines or to the reconciliation, in that order. Sample values are illustrative, never client data.

Want a payroll bridge that closes every month?
The earned-for trend, the named one-time lines, and the exact decomposition, reconciled against Workday, and you own every line.
Talk to us
Terms on this page
run-rate
Recurring fully loaded cost, one-time lines removed. The trend that means something.
variance bridge
The delta split into named effects that sum back exactly.
FTE effect
The change in people, priced at last month's cost per FTE.
rate effect
The change in cost per FTE, on this month's people.
restatement
Prior months moving when retro pay lands on the earned-for view. Shown, not hidden.
one-time lines
Retro, off-cycle, severance. In total cost, out of run-rate.