Companion to: fuel-impact-2026-06-11.html
Generated: 2026-06-11 by build_report.py (fuel-impact-report skill, MC-3483)
Purpose: step-by-step record of every input value used — verify the math from this doc alone.
| # | Source | File | Last read |
|---|---|---|---|
| 1 | IATA Jet Fuel Price Monitor | ~/Dropbox/Safair/Reporting Data/Data Fuel.xlsx |
2026-06-11 |
| 2 | B4i Fuel Feedback (Bernd Feucht) | ~/PKA/SecondBrain/wiki/concepts/Fuel-Prices-B4i.md |
embedded as base64 in HTML |
| 3 | Radixx route surcharge | ~/PKA/SecondBrain/wiki/concepts/fuel-surcharge-data/surcharge_history.json |
embedded as pivot JSON in HTML |
| 4 | FinDash kpi_data | ~/PKA/Projects/findash/data/kpi_data.json |
2026-06-11 |
| 5 | May MTD dashboard | ~/Dropbox/Safair/Reporting Data/dashboard/dashboard_data.json |
2026-06-11 |
| Parameter | Value | Basis | As-of |
|---|---|---|---|
| MAY_FLIGHTS | 4,929 flights | May 2026 ACTUAL flown | 2026-06-11 |
| MAY_SEATS | 931,362 seats | May 2026 ACTUAL capacity | 2026-06-11 |
| JUNE_FLIGHTS | 4,703 flights | kpi_data.json 2026 months[5] | 2026-06-11 |
| JUNE_SEATS | 888,867 seats | kpi_data.json 2026 months[5] | 2026-06-11 |
2026-06-01 note: MAY_FLIGHTS/MAY_SEATS updated to ACTUAL (commercial/Radixx). JUNE_FLIGHTS/JUNE_SEATS added from kpi_data.json schedule.
MC-3517 note: March + April estimate constants removed. All cost fields now read
directly from kpi_data.json actuals (fuel_r, fuel_uplift,
avg_fuel_per_liter_uplifted, total_costs, pbt_r).
NON_FUEL_PER_FLIGHT derived at runtime from April actuals: (total_costs − fuel_r) / flights.
| Metric | Value | kpi_data key |
|---|---|---|
| Flights | 5,640 | flights |
| Pax | 953,355 | pax |
| Seats | 1,062,072 | seats |
| Load Factor | 89.8% | load_factor |
| Yield | R1,329 | yield |
| Revenue | R1,233.5M | revenue_r |
| Fuel uplift | 57.226M L | fuel_uplift — ACTUAL |
| Fuel R/L delivered | R7.31 | avg_fuel_per_liter_uplifted — ACTUAL |
| Fuel cost | R418.4M | fuel_r — ACTUAL |
| Non-fuel cost | R717.8M = total_costs − fuel_r | derived |
| — Direct (ex-fuel) | R388.1M = total_direct_costs − fuel_r | kpi_data |
| — Overheads | R329.7M = total_overheads | kpi_data |
| Total costs | R1,136.3M | total_costs — ACTUAL |
| PBT | R127.4M | pbt_r — ACTUAL |
| Reconciliation check | revenue − fuel − non_fuel = R97.2M vs pbt_r R127.4M | gap R30.22M |
| Metric | Value | kpi_data key |
|---|---|---|
| Flights | 5,307 | flights |
| Pax | 864,006 | pax |
| Seats | 999,135 | seats |
| Load Factor | 86.5% | load_factor |
| Yield | R1,628 | yield |
| Revenue | R1,427.2M | revenue_r — ACTUAL |
| Fuel uplift | 53.274M L | fuel_uplift — ACTUAL |
| Fuel R/L delivered | R13.26 | avg_fuel_per_liter_uplifted — ACTUAL |
| Fuel cost | R706.5M | fuel_r — ACTUAL |
| Non-fuel cost | R683.5M = total_costs − fuel_r | derived |
| — Direct (ex-fuel) | R360.2M = total_direct_costs − fuel_r | kpi_data |
| — Overheads | R323.3M = total_overheads | kpi_data |
| Total costs | R1,390.1M | total_costs — ACTUAL |
| PBT | R43.7M | pbt_r — ACTUAL |
| Reconciliation check | revenue − fuel − non_fuel = R37.2M vs pbt_r R43.7M | gap R6.54M |
| Non-fuel/flight | R127,276 | April reference; May uses direct per-flight + overheads flat (Mar–Apr avg) |
| L/flight | 10,038 | apr fuel_uplift / apr flights — used for May |
| Lens | Result |
|---|---|
| Per-pax yield recovery | R299 ÷ R379 = 79% |
| Per-flight rev recovery | R50K ÷ R59K = 85% |
| Network revenue ÷ fuel hike | R194M ÷ R288M = 67% |
| Total absorption (rev + nonfuel saving) ÷ fuel hike | R228M ÷ R288M = 79% |
May (projection) column. The Recovery + comparison tables in the HTML report carry a third May (proj) column = the headline Base-case projection (rev R1,159.5M · fuel R601.9M @ R14.67/L · PBT −R122.0M). It is a projection, not a closed month, and is excluded from the recovery ratios above: those measure absorption of the March→April fuel hike, whereas April→May fuel falls (smaller, lower-volume month + B4i easing) — there is no hike to absorb into May.
Step 1 — April actual delivered R/L anchor:
Apr fuel_r = R706.54M (kpi_data fuel_r)
Apr fuel_uplift = 53.274M L (kpi_data fuel_uplift)
Apr actual R/L = 706.54M ÷ 53.274M = R13.2600/L
Step 2 — May fuel R/L derivation (M2 priority chain):
Priority 1 (preferred): May MTD actual avg_fuel_per_liter_uplifted from kpi_data.json
→ Used when present: NOT AVAILABLE — fell through to IATA estimate
Priority 2: Apr actual R/L × (IATA×FX latest) / (IATA×FX Apr)
Priority 3: Apr actual R/L × IATA ratio only (FX unavailable)
Priority 4: Apr actual × 0.97 (IATA unavailable; B4i-corroborated 3% ease)
Actual source used: Apr actual R13.26 × IATA ratio (146.25/167.96=0.8707). USD/ZAR not available — excluded from scaling. CAVEAT: monthly contracts lag IATA weekly spot.
April IATA $/bbl reference = 167.96
Latest IATA $/bbl = $146.25 (Jun 05, Data Fuel.xlsx)
May base R/L result = R14.2000
CAVEAT (M2): IATA-scaled estimates assume supplier contracts track IATA weekly spot. Monthly contracts lag IATA weekly; delivered R/L can diverge from spot (May actual R14.67 rose despite B4i showing decreases).A Rand move can flip the sign of the implied R/L change. This estimate is directional. Superseded by May MTD actual delivered R/L (priority 1) when kpi_data.json is updated.
Step 3 — B4i corroboration (direction check): May B4i tariff data shows broad decreases: Astron −332cpl, Shell −215cpl, PetroSA −171cpl, Engen −222cpl. This corroborates the downward IATA direction. Base R/L of R14.20 is anchored to actual April R13.26 minus documented easing.
Step 4 — Scenario band: Opt = base − R1.50 = R13.50 Base = R14.20 Pess = base + R2.00 = R15.20
| Metric | Value | Source |
|---|---|---|
| Period | June 2026 MTD (8 days, through 8 Jun) | dashboard_data.json |
| Flights | 1224 | dashboard_data.json |
| Pax | 180376 | dashboard_data.json |
| Revenue | R250.3M | dashboard_data.json |
| Yield | R1,388 | dashboard_data.json |
| LF | 78.0% | dashboard_data.json |
May MTD LF is a partial-month observation (~14 days). Bookings continue to mature. The full-month projection uses April actual full-month LF as the maturity proxy.
May MTD LF = 78.0% (from dashboard_data.json kpis_mtd — partial, ~14 days)
April actual LF = 86.5% (from kpi_data.json months[3] load_factor — ACTUAL full month close)
Projection method = MTD 80.2% @14d → full-month 86.5% using April actual full-month close
as maturity proxy; assumes April-like booking maturation
Flag = if May booking pace differs materially from April, this proxy
will over- or under-state full-month LF
Base — MTD actual vs full-month projected:
| Variant | LF | Revenue | Fuel | Non-fuel | PBT | Margin |
|---|---|---|---|---|---|---|
| [live MTD] | 82.1% | R1,160M | R583M | R627M | −R50M | -4.3% |
| Parameter | Value | Basis |
|---|---|---|
| Flights | 4,929 | May schedule |
| Seats | 931,362 | May schedule |
| L/flight | 8,324 | Apr actual fuel_uplift ÷ Apr flights |
| Non-fuel/flight | R127,276 | Apr actual (total_costs−fuel_r)÷flights |
| Non-fuel total | R627M | direct (ex-fuel) per-flight + overheads flat (Mar–Apr avg) |
| Scenario | Fuel R/L | Yield | LF | Revenue | Fuel | Non-fuel | PBT | Margin |
|---|---|---|---|---|---|---|---|---|
| Optimistic | R13.50 | R1,517 | 82.1% | R1,160M | R554M | R627M | −R21M | -1.8% |
| Base case [live MTD] | R14.20 | R1,517 | 82.1% | R1,160M | R583M | R627M | −R50M | -4.3% |
| Pessimistic | R15.20 | R1,517 | 82.1% | R1,160M | R624M | R627M | −R91M | -7.8% |
Revenue is ACTUAL from commercial/Radixx + X3 GL close (2026-06-11). Label: 'ACTUAL — X3 GL closed'. All inputs (revenue, flights, pax, LF, yield, fuel R/L, non-fuel) are factual. Scenarios vary the operating-PBT presentation only.
| Input | Value | Source |
|---|---|---|
| Revenue | R1,159.5M | ACTUAL — commercial/Radixx |
| Flights | 4,929 | ACTUAL flown |
| Capacity | 931,362 seats | ACTUAL |
| Pax | 764,240 | ACTUAL |
| LF | 82.1% | ACTUAL (764,240 / 931,362) |
| Yield | R1,517.20 | ACTUAL |
| Fuel volume | 41.03M L | 4,929 flights × 8,324 L/flight (April basis) |
| Non-fuel | R679.7M | kpi_data May total_costs R1,281.7M − fuel_r R602.0M (closed) |
May PBT oracle (spec ±R0.5M):
| Scenario | Fuel R/L | Fuel | PBT | Margin |
|---|---|---|---|---|
| May Optimistic (actual rev) | R14.17 | R581.4M | −R101.5M | -8.8% |
| May Base — central (actual rev) | R14.67 | R601.9M | −R122.0M | -10.5% |
| May Pessimistic (actual rev) | R15.17 | R622.4M | −R142.6M | -12.3% |
| Stress test — fuel held flat (<10% tail) | R16.00 | R656.4M | −R176.6M | -15.2% |
Schedule from kpi_data.json 2026 months[5]: flights=4,703, seats=888,867. Forward MTD: 1,227 flights flown (days 1-10), 177,110 pax, LF 76.4%, R245.7M revenue, R1,388/pax yield, R200k/flight. Remainder: 3,476 scheduled flights (days 11-30) projected at MTD rate (R200k/flight, 144 pax/flight). Base case full month: 4,703 flights, ~679k pax, R942M revenue, 76.4% LF. Opt = R993M, pess = R793M. Costs: April basis (R67,872.42/flight direct ex-fuel + R323,331,269.87 flat overheads). Fuel: April L/flight 8,324 × 4,703 flights = 39.15M L. Fuel R/L: B4i 8 Jun shows increases (Shell JHB +R1.00/L); June central ≈ R15.00: opt 14.50 / base 15.00 / pess 15.50 / floor May flat.
| Input | Value | Source |
|---|---|---|
| Flights | 4,703 | kpi_data.json 2026 months[5] |
| Seats | 888,867 | kpi_data.json 2026 months[5] |
| Fuel volume | 39.15M L | 8,324 L/flight × 4,703 flights |
| Non-fuel | R598.6M | R67,872.42/flight × 4,703 + R323,331,269.87 overheads (April basis) |
June PBT oracle (spec ±R0.5M):
| Scenario | LF | Yield | Fuel R/L | Revenue | Fuel | Non-fuel | PBT | Margin |
|---|---|---|---|---|---|---|---|---|
| June Optimistic (forecast) | 80.5% | R1,388 | R14.50 | R993.0M | R567.6M | R598.6M | −R173.2M | -17.4% |
| June Base case — MTD rate holds (forecast) | 76.4% | R1,388 | R15.00 | R942.0M | R587.2M | R598.6M | −R243.8M | -25.9% |
| June Pessimistic (forecast) | 64.3% | R1,388 | R15.50 | R793.0M | R606.8M | R598.6M | −R412.3M | -52.0% |
| Stress test — May fuel held flat (<10% tail) (floor) | 76.4% | R1,388 | R13.26 | R942.0M | R519.1M | R598.6M | −R175.7M | -18.6% |
Assertion: (revenue − total_costs) ≈ pbt_r.
Gap = non-operating IS items (finance costs, tax, other income) not captured in total_costs.
Warn gate: max(R15M, 1% revenue) — amber NOTE in report.
Fail gate: R50M — red WARNING block in report.
| Month | rev − costs | pbt_r | Gap | other_is | Warn gate | Status |
|---|---|---|---|---|---|---|
| Mar | R97.2M | R127.4M | R30.2M | R30.2M | R15.0M | WARN |
| Apr | R37.2M | R43.7M | R6.5M | R6.5M | R15.0M | PASS |
| May (proj) | −R122.0M | −R122.0M | — | — | — | proj — operating only (rev−costs≡PBT; no non-op IS projected) |
Identity: revenue_Δ − fuel_hike + nonfuel_saving + other_IS_movement = −pbt_drop
Revenue increase: +R193.7M
Fuel hike: −R288.1M
Non-fuel saving: +R34.3M
Other IS movement: −R23.7M (apr_other_is=R6.5M, mar_other_is=R30.2M)
PBT drop: −R83.7M
Bridge check: R288.1M ≈ R288.1M
All figures are closed-month ACTUALS from kpi_data.json (fuel_r, fuel_uplift,
pbt_r, revenue_r, pax, flights, avg_fuel_per_liter_uplifted). No estimates,
no MTD month. CY (2026) and LY (2025) summed over the SAME closed months for a
like-for-like view.
YTD window: Jan–Apr (Jan, Feb, Mar, Apr) — no months excluded
Headline impact (the two side-by-side numbers):
YTD extra fuel spend vs 2025 = Σ fuel_r 2026 − Σ fuel_r 2025
= R1,726.5M − R1,339.8M = +R386.7M
YTD PBT delta vs 2025 = Σ pbt_r 2026 − Σ pbt_r 2025
= R256.1M − R532.6M = −R276.5M
Fuel hike absorbed (not in PBT) = extra fuel + pbt delta = R110.2M
YTD table (Jan–Apr):
| Metric | 2026 | 2025 | Δ |
|---|---|---|---|
| Fuel cost | R1,726.5M | R1,339.8M | +28.9% |
| Fuel volume | 214.7M L | 101.8M L | +110.9% |
| Blended R/L | R8.04 | R13.16 | −38.9% |
| Revenue | R4,633.4M | R4,394.9M | +5.4% |
| PBT | R256.1M | R532.6M | −51.9% |
Apr 2026 vs Apr 2025 (actuals month YoY):
| Metric | Apr 2026 | Apr 2025 | Δ |
|---|---|---|---|
| Fuel cost | R706.5M | R347.3M | +103.4% |
| Fuel R/L | R13.26 | R12.66 | +4.7% |
| Revenue | R1,427.2M | R1,275.2M | +11.9% |
| PBT | R43.7M | R255.0M | −82.9% |
fuel_r, fuel_uplift, total_costs, pbt_r). No estimates used. May X3 GL closed 2026-06-11.CONSTANTS dict in build_report.py.Generated 2026-06-11 · build_report.py · MC-3483/MC-3517/fuel-impact-jun2026