Data Analysis

OKR Sheet Linked to FCFF: A Financial Model Design (2026)

Marc SeanMay 2, 20265 min read

OKR sheet architecture: a 3-tab design

Split the workbook into three tabs.

TabRoleData flow
OKR_DataKR inputs and score calculationOutputs to Assumptions only
AssumptionsScenario switches and financial assumptions (DSO, Capex included)Outputs to P&L, BS, CF
P&L / BS / CFThree-statement modelReceives from Assumptions only

One-way flow keeps the model auditable. If the P&L references OKR_Data directly, cross-tab dependencies snowball and you can't trace where a number came from. Centralizing every financial assumption in one tab means a scenario change propagates consistently across all three statements.

Required FP&A fields per OKR row

In Measure What Matters (Portfolio/Penguin, 2018, ch. 4), John Doerr defines a Key Result as something whose attainment must be judgable independently of other KRs. Translated into spreadsheet terms, you need at least seven columns per row.

ColFieldTypeExample
AKR_IDText2026Q3-SALES-01
BObjective descriptionTextHit ARR ¥500M
CTarget valueNumber500,000
DWeight (0–1)Number0.35
ECurrent valueNumber338,000
FProgressFormula=E2/C2
GConfidence scoreNumber (manual)0.72
HLast updatedDate2026/05/01

The confidence score (column G) is not the same as progress (column F). ARR can be at 67% of target while confidence sits below 50% because pipeline quality has degraded. That subjective estimate is the input that drives the scenario switch.

The weighted-average score lives at Assumptions!B3.

// Assumptions!B3: weighted-average KR confidence
=SUMPRODUCT(OKR_Data!G2:G20, OKR_Data!D2:D20)
 / SUMPRODUCT(OKR_Data!D2:D20)

Per Google Sheets' SUMPRODUCT documentation, the function multiplies arrays element-wise and sums the result, treating blanks as zero. Even an ARRAYFORMULA over 5M rows recalculates in under 50ms.

Cascading into EBITDA

Branch scenarios off the score in Assumptions!B3.

// Assumptions!B4: scenario flag
=IF(B3>=0.75,"OnTrack",IF(B3>=0.55,"Caution","Downside"))

// Assumptions!B5: monthly revenue assumption (¥k)
=IFS(B4="OnTrack", 42000, B4="Caution", 36000, B4="Downside", 29000)

In Q2 2026, the weighted-average KR score was 75.7% — OnTrack. Going into Q3, the product roadmap KR and customer success KR slipped, and the score fell to 67.8%. The scenario auto-switches to Caution.

ScenarioMonthly revenueQuarterly EBITDA (22%)NOPAT (30% tax)
OnTrack (≥75%)¥42,000k¥27,720k¥19,404k
Caution (55–75%)¥36,000k¥23,760k¥16,632k
Downside (<55%)¥29,000k¥19,140k¥13,398k
// P&L!C5: quarterly EBITDA
='P&L'!C3 * Assumptions!$B$8   // C3 = quarterly revenue, B8 = EBITDA margin (0.22)

// P&L!C7: NOPAT
='P&L'!C5 * (1 - Assumptions!$B$9)   // B9 = effective tax rate (0.30)

From KR confidence to FCFF waterfall

This is where the model becomes investor-ready. A scenario toggle on the P&L alone doesn't finish FCFF. KR confidence shifts working capital (DSO) and Capex timing, and those flow straight into cash.

DSO assumption and balance-sheet linkage

When product KRs slip, customer acceptance drags and the collection cycle stretches. In Caution, lift average DSO from 45 days to 52.

// Assumptions!B6: DSO (days)
=IFS(B4="OnTrack", 45, B4="Caution", 52, B4="Downside", 60)

// BS!C15: AR balance
='P&L'!C3 / 90 * Assumptions!$B$6
// P&L!C3 = quarterly revenue (Caution: ¥108,000k)
// → AR balance: ¥108,000 / 90 × 52 = ¥62,400k

// BS!C16: ΔAR (vs prior period)
=C15 - B15
// B15 = end-of-Q2 AR (OnTrack: ¥126,000/90×45 = ¥63,000k)
// → ΔAR = ¥62,400 - ¥63,000 = -¥600k (small AR release = small WC improvement)

Capex timing linkage

It's irrational to keep deploying full growth Capex while a product roadmap KR is slipping. In Caution, defer 50% of growth Capex on engineering equipment. In Downside, freeze it entirely.

// Assumptions!B7: quarterly Capex (¥k)
=IFS(B4="OnTrack", 45000, B4="Caution", 22500, B4="Downside", 0)

FCFF waterfall (CF tab)

// CF!C3: NOPAT (from P&L)
='P&L'!C7

// CF!C5: D&A (fixed, ¥9,000k/Q)
=Assumptions!$B$10

// CF!C7: ΔWC (sign-flipped ΔAR)
=-'BS'!C16

// CF!C9: Capex
=-Assumptions!$B$7

// CF!C11: FCFF
=C3 + C5 + C7 + C9

Lay the three scenarios side by side and a structural pattern jumps out.

FCFF waterfall (Q3 2026, ¥k)OnTrackCautionDownside
NOPAT¥19,404¥16,632¥13,398
D&A¥9,000¥9,000¥9,000
ΔWC (sign-flipped ΔAR)¥0+¥600+¥4,400
Capex-¥45,000-¥22,500¥0
FCFF-¥16,596+¥3,732+¥26,798

The Downside FCFF is higher than OnTrack — because Capex went to zero. When you walk an investor through this paradox in a QBR, "we're cash-rich even in Downside" doesn't fly. What does work: "this is the result of halting growth investment, and we're trading future runway to get there." That framing is the value of binding the OKR sheet to FCFF.

The OnTrack-to-Caution shift produces a +¥20,328k FCFF delta. Here's the bridge.

FCFF bridge (OnTrack → Caution, ¥k)Amount
① NOPAT contraction (revenue -¥18,000k × 22% × 70%)-¥2,772
② ΔWC improvement (AR -¥600k, WC release)+¥600
③ Capex deferral (¥45,000 → ¥22,500)+¥22,500
FCFF delta+¥20,328

Drop this bridge into the monthly board deck as a single page and the explanation lands on its own: "OKRs are tracking behind, so we deferred Capex; the FCFF impact was +¥20,328k." You start the conversation on KR attainment and end up with numbers that reconcile to the balance sheet and cash flow. That's the point of the design.

Staleness alerts to keep inputs fresh

If a KR confidence score hasn't been touched in 14 days, the Assumptions tab is running on a dead input. As of May 2026, plenty of teams ship quarterly forecasts without realizing the underlying scores haven't moved.

// Assumptions!D3: days since last update
=TODAY() - MAX(OKR_Data!H2:H20)   // column H = each KR's last-updated date

// Assumptions!E3: alert message
=IF(D3>14,
   "⚠ KR scores " & D3 & " days stale — model needs review",
   "✓ Fresh")

Park that cell at the top of the Assumptions tab, paint it red with conditional formatting, and it's the first thing you see when the model opens. SUMPRODUCT can extend it to per-owner alerts.

// Per-owner staleness check
=SUMPRODUCT((TODAY()-OKR_Data!H2:H20>14)*(OKR_Data!I2:I20="Tanaka"))
// Column I = owner name; any value ≥1 means follow-up needed

Closing the update loop with ModelMonkey

The sheet design itself is complete with the SUMPRODUCT and 3-tab structure above, but the operational cost of updating eight or more KRs every week isn't trivial. Connect ModelMonkey to Google Sheets and confidence-score inputs from Slack or Google Forms write straight into the OKR_Data tab — every entry triggers a recompute through Assumptions, P&L, BS, and CF. The 14-day alert fires less often, and the "are these numbers right?" check before QBR shrinks.

Try ModelMonkey free for 14 days — works in both Google Sheets and Excel.


Frequently Asked Questions