Most feasibility studies arrive as a PDF with a spreadsheet behind it. If you are a developer, a founder or an analyst, it is worth rebuilding the core numbers yourself. It takes about forty lines of Python, and it shows quickly whether a project actually clears its cost of capital or only looks good on one headline metric.
Below is a small, dependency-free model of the four numbers that decide most investment cases: NPV, IRR, payback and break-even, plus a one-line sensitivity test. The figures are illustrative (in Saudi riyals) for a small production project. Replace them with your own.
The inputs
# Illustrative numbers only (SAR). Replace with your project's figures.
capex = 4_000_000 # land works, building, equipment, pre-operating
working_capital = 600_000 # stock + receivables - payables at steady state
rate = 0.12 # discount rate (cost of capital), annual
# Year 1..5 net operating cash flow after zakat/tax
cash_flows = [350_000, 900_000, 1_250_000, 1_400_000, 1_450_000]
salvage = 1_200_000 # residual value + working capital recovered in year 5
Two things people often forget: working capital is a real cash outflow at the start, and it usually comes back at the end. Both belong in the cash flows.
NPV, IRR and payback
def npv(rate, flows):
return sum(cf / (1 + rate) ** t for t, cf in enumerate(flows))
def irr(flows, lo=-0.99, hi=1.0, tol=1e-7):
f = lambda r: npv(r, flows)
if f(lo) * f(hi) > 0:
raise ValueError("IRR not bracketed")
for _ in range(200):
mid = (lo + hi) / 2
if f(lo) * f(mid) <= 0:
hi = mid
else:
lo = mid
if hi - lo < tol:
break
return (lo + hi) / 2
def payback(flows):
cum = 0.0
for t, cf in enumerate(flows):
prev = cum
cum += cf
if t > 0 and cum >= 0:
return t - 1 + (-prev / cf)
return None
flows = [-(capex + working_capital)] + cash_flows
flows[-1] += salvage
print(f"NPV @ {rate:.0%}: {npv(rate, flows):,.0f} SAR")
print(f"IRR: {irr(flows):.1%}")
print(f"Simple payback: {payback(flows):.1f} years")
Output:
NPV @ 12%: -286,894 SAR
IRR: 10.0%
Simple payback: 4.3 years
This is the interesting part. A payback of 4.3 years on a five-year horizon sounds acceptable, and many summaries would stop there. But the NPV is negative and the IRR (10%) is below the 12% cost of capital. On these numbers the project destroys value. Payback ignores the time value of money and everything after the payback year, so never judge a project on payback alone.
(The IRR here uses simple bisection, which is fine for conventional cash flows: one outflow followed by inflows. If your cash flows change sign more than once, there can be more than one IRR, so rely on NPV.)
Break-even
fixed_costs = 1_100_000 # annual: salaries, rent, maintenance, insurance
price = 250 # per unit, excl. VAT
variable_cost = 140 # per unit
be_units = fixed_costs / (price - variable_cost)
print(f"Break-even: {be_units:,.0f} units/year")
Break-even: 10,000 units/year
Compare that figure with the market study, not with the sales target. If the realistic addressable demand for your product in your region is 25,000 units a year, a 10,000-unit break-even means you need a 40% share just to cover fixed costs. That is a very different conversation from "we break even in year two".
Note the price is excluding VAT. In Saudi Arabia VAT is 15%, and it is collected for the government, not earned by the project. Mixing VAT-inclusive prices into revenue is a common error in early models.
Sensitivity: the test that matters most
low = [-(capex + working_capital)] + [cf * 0.8 for cf in cash_flows]
low[-1] += salvage
print(f"NPV with -20% cash flow: {npv(rate, low):,.0f} SAR; IRR {irr(low):.1%}")
NPV with -20% cash flow: -1,013,333 SAR; IRR 4.7%
A 20% shortfall in operating cash flow is not a pessimistic scenario. It is an ordinary year with slower ramp-up or weaker prices. Run the same test on price, on volume, on capex overruns and on a six-month delay before opening. The variable that moves NPV the most is where the study's research effort should go.
What the code does not do for you
The arithmetic is the easy part. The hard part is the inputs:
- Demand and price must come from a real market study (competitors, customer segments, and prices actually paid), not from a target.
- Capex should be based on quotations, not round numbers.
- The discount rate should reflect the project's risk and financing mix. In Saudi Arabia that often includes a development-fund or bank loan, with its own grace period and repayment schedule.
- Zakat or corporate income tax depends on the ownership structure. Model it according to ZATCA rules for your entity rather than as a flat guess.
If you are preparing a study for a lender or an investor, these inputs are what they will challenge. We wrote more about how we approach them at our feasibility study office in Riyadh (Arabic).
Disclosure: I work at Googan Business Services, a feasibility-study and consulting firm in Riyadh. The numbers above are an illustrative example, not a real client project, and nothing here is a financing or investment guarantee.
Top comments (0)