# Actual costs and the run-rate

> What the business really spent per month and category, and the monthly run-rate a plan starts from (ADR 80, workflow). Calculated by the engine (calc/actual_costs.py, model actual-costs-1.0.0).

What the business really spent per month and category, and the monthly run-rate a plan starts from
([ADR 80](../adr/0080-bills-and-actual-costs.md), [workflow](../workflows/actual-costs.md)). Calculated by the engine
(`calc/actual_costs.py`, model `actual-costs-1.0.0`).

## The example

Three months, July to September 2026, in euros:

| Expense | Category | Paid (gross) | Net | Service period |
| --- | --- | --- | --- | --- |
| Hosting, 3 Jul, 3 Aug, 3 Sep | cloud hosting (cost of sales) | 119.00, 119.00, 142.80 | 100.00, 100.00, 120.00 | the month |
| Annual software licence, 1 Jul | software | 1,428.00 at 19 % VAT | not stated | Jul 2026 to Jun 2027 |
| Tax adviser, 20 Aug, marked one-off | professional services | 595.00 | 500.00 | the month |

## 1. Amount on the chosen basis

$$a_r = \begin{cases} \text{net}_r & \text{basis net, net known} \\ \dfrac{\text{gross}_r}{1 + v_r} & \text{basis net, net unknown, rate known (estimated)} \\ \text{gross}_r & \text{otherwise} \end{cases}$$

| Symbol | Meaning | Unit |
| --- | --- | --- |
| $a_r$ | Amount of expense $r$ used in the table | base currency |
| $\text{net}_r, \text{gross}_r$ | Net and gross amount, converted with the expense's FX rate | base currency |
| $v_r$ | VAT rate | fraction |

**In plain words.** On a net basis the amount without VAT is used; when only the gross amount and the rate are known
it is estimated and the warning `net_estimated` is shown. **Example.** The licence: $1428 / 1.19 = 1200$.

## 2. Spreading over the service period

$$C_{k,m} = \sum_{r \in k} \frac{a_r}{|S_r|}\,[m \in S_r]$$

| Symbol | Meaning | Unit |
| --- | --- | --- |
| $C_{k,m}$ | Cost of category $k$ in month $m$ | base currency |
| $S_r$ | The months of the expense's service period; without one, the month of its date | months |

**In plain words.** An expense for several months is shared evenly over them; an expense for one month counts in
that month. **Example.** The licence adds $1200 / 12 = 100$ to software in every month from July to June.

## 3. Run-rate per category and in total

$$\bar C_k = \frac{1}{n}\sum_{m=1}^{n}\left(C_{k,m} - O_{k,m}\right) \quad\text{(average)},\qquad \bar C_k = C_{k,n} - O_{k,n} \quad\text{(last month)},\qquad \bar C = \sum_k \bar C_k$$

| Symbol | Meaning | Unit |
| --- | --- | --- |
| $n$ | Months in the window (at most 36) | months |
| $O_{k,m}$ | Part of $C_{k,m}$ from expenses marked one-off | base currency |
| $\bar C_k$, $\bar C$ | Monthly run-rate of category $k$, and of all categories | base currency per month |

**In plain words.** The run-rate is what a normal month costs: the average of the window (a month with no costs
counts as zero and is flagged `no_costs_in_<month>`) or the last month, without one-off expenses. Categories whose
line is `cogs.*` add up to the cost-of-sales run-rate, the rest to operating costs.

**Example.** Hosting $\frac{100 + 100 + 120}{3} = 106.67$; software $100$; the tax adviser is one-off, so $0$.
Total $\bar C = 106.67 + 0 + 100 = 206.67$ a month, of which $106.67$ is cost of sales. The window's total
including the one-off is $1120.00$.

*For developers:* `actual_costs`, `ActualCostsRequest`, `ActualCostsResult`; test `test_actual_costs.py`.
