What it is
Budget variance is the metric every FP&A team builds against each month: actual revenue versus budget, actual costs versus budget, with the gap (variance dollars and variance percent) highlighted line by line. It is the basis for the monthly board commentary, the trigger for re-forecasting, and the input to compensation and bonus calculations in many firms.
In Xero, the source data sits in two places: the approved Budget (entered through Xero's Budget Manager) and the actuals (posted transactions surfaced via the P&L). The Xero API exposes Budget Summary as a standalone report, but the variance computation — actual minus budget — is left to whoever is reading the data. Most finance teams build the variance pack in Excel.
Why analysts want it in Excel
Excel is where the variance pack actually lives. The standard layout puts budget in one column, actual in the next, variance dollars and variance percent in two more, with commentary cells underneath and conditional formatting flagging material variances. Most FP&A teams already have a variance template they reuse every month — only the underlying numbers change.
Live data in Excel turns this from a monthly rebuild into a live-refreshed workbook. The variance template gets built once, the budget and actual cells reference XO functions, and every Refresh re-pulls the latest figures. Late journals and budget-revision adjustments propagate automatically. Re-forecasts become a matter of changing the budget name in a parameter cell rather than re-keying the whole pack.
Why the manual method breaks
- Export the Budget Summary from Xero, export the P&L from Xero, paste both into the variance workbook, line up account codes, type the variance formulas — repeat every month, every entity, every re-forecast cycle.
- Late journals posted after the P&L export silently break the variance calculation; the workbook says one thing, the live ledger says another.
- Budget revisions force a re-export and re-paste of the budget column; if you forget which budget version you exported, the variance pack becomes unreliable.
- Tracking-category variance (budget vs actual by region or department) multiplies the export work — one export per category combination per period.
- Re-forecasting mid-quarter requires re-running the entire export cycle; the workbook lags the ledger by the time between export and meeting.
The live add-in method
Honest positioning: there is no single Budget Variance report in XO Report. The closest task pane report is Budget Summary, which surfaces the budget figures only — it does not include actuals or compute the variance. There is no XO function called XO.VARIANCE.
The pattern. XO Report exposes the budget via XO.BUDGET and the actual via XO.BALANCE (or by referencing the inserted P&L report). Variance is a standard Excel formula you compose: actual - budget for variance dollars and (actual - budget) / budget (or actual / budget - 1) for variance percent.
Two workflow choices. (1) Cell-level formulas: pull XO.BUDGET (budget) and XO.BALANCE (actual) for the SAME account into adjacent columns and compute variance with Excel arithmetic. (2) Two task pane reports + Excel:insert Budget Summary on one sheet and P&L on another, then build a Variance sheet that references both. Pick the surface that matches your template.
# Setup block (column J — far right, visually separate from the
# variance table; XO functions need cell references for dates per
# FUNCTIONS.md, not text strings).
# $J$1 = Org ID returned by =XO.ORG()
# $J$2 = budget name (must match a budget configured in Xero,
# e.g. "Overall Budget")
# $J$3 = account code (e.g. "4000" for Sales)
#
# Variance table starts row 5. Columns:
# A = Period (Excel DATE value, formatted "MMM YYYY")
# B = From date (=EOMONTH(A6,-1)+1 — first of period month)
# C = To date (=EOMONTH(A6,0) — last of period month)
# D = Budget (=XO.BUDGET(...) using B6/C6 date cells)
# E = Actual (=XO.BALANCE(...) using B6/C6 date cells)
# F = Variance $ (=E6-D6 → Actual minus Budget)
# G = Variance % (=IF(D6=0,"-", E6/D6-1))
#
| Period | From | To | Budget | Actual | Variance ($) | Variance (%) | ← row 5 header
| Jan 2026 | =EOMONTH(A6,-1)+1| =EOMONTH(A6,0) | =XO.BUDGET($J$1,$J$2,$J$3,B6,C6) | =XO.BALANCE($J$1,$J$3,B6,C6) | =E6-D6 | =IF(D6=0,"-",E6/D6-1) | ← row 6
| Feb 2026 | =EOMONTH(A7,-1)+1| =EOMONTH(A7,0) | =XO.BUDGET($J$1,$J$2,$J$3,B7,C7) | =XO.BALANCE($J$1,$J$3,B7,C7) | =E7-D7 | =IF(D7=0,"-",E7/D7-1) | ← row 7
| Mar 2026 | =EOMONTH(A8,-1)+1| =EOMONTH(A8,0) | =XO.BUDGET($J$1,$J$2,$J$3,B8,C8) | =XO.BALANCE($J$1,$J$3,B8,C8) | =E8-D8 | =IF(D8=0,"-",E8/D8-1) | ← row 8
# Pattern: XO.BUDGET and XO.BALANCE both take an account code as a
# parameter — comparing them on the SAME account and SAME date range
# gives an apples-to-apples variance. The From/To date cells (B/C)
# derive from the Period date in column A via EOMONTH, so editing
# the Period label updates the whole row in one shot.
#
# Note: XO.BUDGET only supports P&L accounts (Revenue + Expense)
# per FUNCTIONS.md — Balance Sheet accounts do not have budgets.XO.BUDGET has 5 required arguments: org_id (lock with absolute references like $J$1 in the example above), budget_name(a string matching a budget you have configured in Xero's Budget Manager — use the wizard's budget picker to discover available names; the function returns an error listing options if the name is wrong), account code as a string, plus a date range.
XO.BALANCEon a P&L account (Revenue or Expense class) returns the activity over the same date range. Subtract budget from actual for variance dollars (=E-D in the layout above); divide for variance percent (=IF(D=0, "-", E/D-1)) to guard against zero-budget rows. Note FUNCTIONS.md is explicit that the date arguments take cell references, not text strings — the EOMONTH-derived From/To cells in columns B/C handle this so dragging the row down updates dates automatically.
For Net-Income-level variance (whole P&L bottom line), the cell-level pattern breaks down because XO.PROFIT returns total Net Income while XO.BUDGETonly returns a single account's budget. For a Net-Income variance you have two options: (a) aggregate XO.BUDGETacross every P&L account (revenue lines minus expense lines) in a hidden working area, or (b) reference the Total Revenue and Total Expense lines from an inserted P&L report and compute Net Income variance against the aggregated budget total.
Departmental or tracking-category variance is supported by XO.BUDGETvia separate per-category budgets (TRACKING budgets in Xero, e.g., "FY2026 North Region") and by XO.BALANCE via its tracking-category arguments. The actual-side filter and the budget-name filter stay in sync as long as the naming convention is consistent.
Related docs
Frequently asked questions
- Why is there no one-click Budget Variance report in Xero or XO Report?
- Xero’s API exposes Budget Summary as a standalone report (budget figures only) and the P&L as another standalone report (actual figures only). Variance computation — actual minus budget, with percentages and commentary — is left to the consumer because every firm’s variance template is slightly different (column order, conditional formatting, materiality thresholds). XO Report provides the budget and actual data layers; the variance lives in Excel.
- Which Xero plan supports budgets accessible via XO.BUDGET?
- Budgets are available on Xero’s Standard and Premium plans (not on Starter or the accountant-only Ledger/Cashbook plans). If XO.BUDGET returns an empty result on a Standard-or-above plan, the most common cause is the budget not being approved in Xero — only approved budgets are visible to the API and the formula builder’s budget picker.
- Can I compare the current budget against a prior forecast in the same workbook?
- Yes — XO.BUDGET takes the budget name as a parameter, so call it twice with different budget_name strings in adjacent columns. Standard pattern: Column C = current budget ("FY2026 Budget"), Column D = prior forecast ("FY2026 Q1 Forecast"), Column E = actual via XO.BALANCE, Column F = budget-vs-actual variance, Column G = forecast-vs-actual variance. All columns refresh together on workbook recalculation.
- How do I build departmental or tracking-category budget variance?
- XO.BUDGET supports per-tracking-category budgets via the budget_name parameter — set up a TRACKING budget in Xero (e.g., "FY2026 North Region") and call =XO.BUDGET($A$2, "FY2026 North Region", "4000", from, to). On the actual side, XO.BALANCE accepts tracking-category arguments directly: =XO.BALANCE($A$2, "4000", from, to, "Region", "North"). Combine these into a per-region variance grid in Excel.
- How do rolling forecasts work with this pattern?
- Change the Period values in column A (Excel DATE values formatted "MMM YYYY") and the From/To date cells in columns B/C auto-recompute via EOMONTH, which cascades through XO.BUDGET and XO.BALANCE on workbook recalculation — the entire variance grid refreshes from one edit. For a rolling 12-month forecast, set A6 to =EOMONTH(TODAY(),-12) and fill A7…A17 with =EOMONTH(A6,1), =EOMONTH(A7,1), … so the window auto-rolls with the system date. Re-forecasting mid-quarter is a single cell change, not a re-export.