Present Value of CPI-Linked Variable Lease Payments at Commencement

Include index or CPI-linked variable lease payments in the opening present value at the commencement-date index level — not a CPI forecast — and remeasure at the original rate when the index resets.

Problem Statement Link to this section

Index-linked rent is where a naive present-value engine either overreaches or under-includes. A lease whose payments escalate with the Consumer Price Index (CPI) is genuinely variable — the future cash flows are not known at commencement — yet both standards require those payments to enter the opening lease liability anyway, measured at the index level as it stands on the commencement date. The trap on one side is forecasting future CPI into the payment vector and discounting a projection the standards forbid; the trap on the other is treating the payment as fully variable and excluding it, which understates the liability. This page answers a single question: how do index or CPI-linked variable payments enter the opening present value, and what happens to the schedule when the index later resets? The answer is: freeze the index at its commencement value, discount the resulting fixed-in-substance vector, and only revisit the liability through remeasurement — at the original locked rate — when the index actually changes. It is a specific case of the broader present value calculation logic that seeds every lease liability.

Standard Anchor Link to this section

Both frameworks admit index-linked variable payments into the initial liability, but only at the commencement-date index level. ASC 842-20-30-5(b) includes variable lease payments that depend on an index or a rate in the lease payments, initially measured using the index or rate at the commencement date. IFRS 16.27(b) is the mirror provision: variable lease payments that depend on an index or a rate are included in the initial measurement using the index or rate as at the commencement date. Neither standard permits building an expectation of future index movements into the opening vector — the commencement-date level is measured as though it will persist unchanged, producing a fixed-in-substance stream for discounting.

Subsequent index changes are handled by remeasurement, not re-forecasting. IFRS 16.42–43 require the lessee to remeasure the lease liability when future lease payments change as a result of a change in an index or rate — but only when the cash flows actually change, for example when a contractual CPI reset takes effect. Critically, IFRS 16.43 specifies that this remeasurement uses an unchanged discount rate: the liability is recomputed as the present value of the revised payments at the original rate, and the adjustment is taken against the right-of-use asset. ASC 842 reaches the same result — an index reset that changes the payments remeasures the liability at the discount rate unchanged unless another remeasurement trigger requires a fresh rate. The discount rate that governs this whole exercise is selected under mapping discount rates to variable lease payments.

Usage- or performance-based variable payments — a percentage of retail sales, a per-mile charge — are a different animal entirely. They are excluded from the liability and expensed as incurred; their disclosure is handled separately under disclosing variable lease costs under ASC 842.

Formula / Algorithm Specification Link to this section

Let be the index level (the CPI value) observed on the commencement date and let be the contractual base payment for period before indexation. At commencement every indexed payment is measured at the commencement index, so the ratio and the payment vector is simply the base payments held flat:

The opening liability discounts this fixed-in-substance vector at the locked periodic rate :

where is the opening lease liability, is the commencement-level indexed payment, is the locked periodic rate, and is the number of periods. When the index resets at period to a new level , the remaining payments are re-struck at the new ratio and the liability is remeasured at the unchanged rate :

The difference (the pre-reset carrying amount) adjusts the right-of-use asset. The rate never re-strikes for an index change alone — that is the invariant the code below enforces.

Index-linked payments in the liability versus usage-based payments expensed A contractual variable payment is tested by type. An index or CPI-linked payment is measured at the commencement-date index level, held flat as a fixed-in-substance stream, and discounted into the opening lease liability; a later index reset remeasures the remaining payments at the original unchanged rate. A usage-based or performance variable payment is diverted out of the liability and expensed as incurred, entering the variable-cost disclosure instead. Variable lease payment Index / rate linked? Into the opening liability measured at commencement index I₀ held flat · discounted at locked rate index reset → remeasure remaining payments at the ORIGINAL rate Excluded — expensed as incurred usage-based (% of sales, per mile) never enters the liability → variable-cost disclosure Yes No
Only index- or rate-linked variable payments enter the opening liability, and only at the commencement-date index level; a later reset remeasures the remaining payments at the original locked rate. Usage-based variable payments are diverted out of the liability and expensed as incurred, feeding the variable-cost disclosure instead.

Annotated Python Snippet Link to this section

The function builds the commencement payment vector at the commencement index level — never a forecast — discounts it with decimal.Decimal, and exposes a remeasurement helper that re-strikes the remaining payments at the same rate when the index resets. The terminal assertion proves the initial liability uses the commencement index and that remeasurement leaves the rate untouched.

from decimal import Decimal, ROUND_HALF_UP, getcontext

getcontext().prec = 28                                    # audit-grade precision

def cpi_linked_opening_liability(
    base_payments: list[Decimal],
    commencement_index: Decimal,
    periodic_rate: Decimal,
) -> Decimal:
    """Opening PV of index-linked payments at the commencement index.

    ASC 842-20-30-5(b) / IFRS 16.27(b): measure indexed payments using the
    index at commencement — NOT a CPI forecast. Ratio I0/I0 = 1, so the
    base payments are held flat and discounted as a fixed-in-substance stream.
    """
    ratio = commencement_index / commencement_index       # == 1 at commencement
    pv = Decimal("0")
    for t, base in enumerate(base_payments, start=1):
        payment = base * ratio                            # frozen at I0 level
        pv += payment / (Decimal(1) + periodic_rate) ** t
    return pv.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)

def remeasure_on_index_reset(
    remaining_base: list[Decimal],
    commencement_index: Decimal,
    reset_index: Decimal,
    periodic_rate: Decimal,                               # UNCHANGED (IFRS 16.43)
) -> Decimal:
    """Remeasure remaining payments at the new index, ORIGINAL rate."""
    ratio = reset_index / commencement_index
    pv = Decimal("0")
    for t, base in enumerate(remaining_base, start=1):
        pv += (base * ratio) / (Decimal(1) + periodic_rate) ** t
    return pv.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)

rate = Decimal("0.005")                                   # locked periodic rate
opening = cpi_linked_opening_liability(
    [Decimal("10000.00")] * 24, Decimal("312.5"), rate)
restruck = remeasure_on_index_reset(
    [Decimal("10000.00")] * 12, Decimal("312.5"), Decimal("321.9"), rate)

# Initial liability uses I0 only (no forecast); reset raises the liability,
# and the discount rate is byte-for-byte the same object on both sides.
assert opening == cpi_linked_opening_liability(
    [Decimal("10000.00")] * 24, Decimal("312.5"), rate)
assert restruck > cpi_linked_opening_liability(
    [Decimal("10000.00")] * 12, Decimal("312.5"), rate)
print(f"Opening at I0: ${opening}  remeasured after reset: ${restruck}")

The assertions encode the two invariants: the opening liability is a deterministic function of the commencement index alone (re-running it yields the identical figure, proving no forecast crept in), and the post-reset liability rises while the periodic rate passed to both functions is the same value — never re-struck for an index change.

Index-Linked vs. Usage-Based Variable Payments Link to this section

The single most consequential classification on this page is index-linked versus usage-based. They share the word "variable" and nothing else about their accounting treatment.

Aspect Index / rate-linked (CPI) Usage-based (% of sales, per unit)
In the opening liability? Yes — at commencement index level No — excluded entirely
Measured using The index/rate as at commencement Not measured at commencement
Future changes Remeasure liability at the original rate Expensed as incurred each period
Standard ASC 842-20-30-5(b) / IFRS 16.27(b) Expensed; disclosed as variable cost
Where it surfaces Amortization schedule Variable lease cost disclosure

Misfiling a CPI escalation as usage-based understates the liability from day one; misfiling a sales-based rent as index-linked capitalizes a payment the standards require to be expensed. The test is whether the payment varies with an external index or rate (in the liability) or with the lessee's own use or performance (expensed).

Gotcha / Failure Mode: Forecasting CPI Into the Opening Vector Link to this section

The tempting error is to build a "best estimate" of future CPI into the opening payment vector — escalating each year's rent by an assumed 3% inflation — and discount that projection. Both standards forbid it: the opening measurement uses the commencement index level held flat, and forward movements are captured only when they actually occur.

Before (WRONG — projects assumed inflation into the initial vector):

# Escalates each period by a forecast CPI — NOT permitted at commencement
payments = [base * (Decimal("1.03") ** (yr)) for yr in range(n_years)]
opening = sum(p / (Decimal(1) + r) ** t for t, p in enumerate(payments, 1))

After (correct — commencement index only; movements via remeasurement):

# Held flat at the commencement index; reset handled later, at the original rate
payments = [base for _ in range(n_periods)]              # I0 / I0 == 1
opening = cpi_linked_opening_liability(payments, i0, r)  # ASC 842-20-30-5(b)

Debug checklist when an indexed liability looks too high or reconciles poorly:

  1. No forward index in the vector. Confirm every indexed payment equals its base times the commencement ratio, not an escalated projection.
  2. Reset uses the original rate. A remeasurement for an index change must reuse the locked rate; re-striking the rate is a separate trigger, not an index reset.
  3. Usage-based filtered upstream. Sales- or usage-based rent must be removed before discounting, not blended into the indexed stream.
  4. Adjustment routed to the ROU asset. The remeasurement difference adjusts the right-of-use asset, not period expense, unless the asset is written down to zero.

Frequently Asked Questions Link to this section

Do I forecast future CPI when computing the opening lease liability?

No. ASC 842-20-30-5(b) and IFRS 16.27(b) require index-linked payments to be measured using the index or rate as at the commencement date, held flat. You do not project inflation or future index levels into the opening vector. The commencement index level is applied to every future indexed payment as though it will persist, producing a fixed-in-substance stream to discount. Actual index movements are captured later through remeasurement, not baked into the initial measurement.

What discount rate applies when a CPI index resets?

The original rate, unchanged. IFRS 16.43 requires remeasurement for an index or rate change to use an unchanged discount rate, and ASC 842 reaches the same result: you recompute the liability as the present value of the revised payments at the rate locked at commencement, and the difference adjusts the right-of-use asset. The discount rate only re-strikes for a different kind of trigger, such as a change in the lease term or a modification, not for an index reset alone.

Are usage-based variable payments included in the lease liability?

No. Payments that vary with the lessee's use or performance — a percentage of retail sales, a per-mile or per-unit charge — are excluded from the liability entirely and expensed as incurred. Only payments that depend on an external index or rate enter the liability, and only at the commencement level. Usage-based amounts surface in the variable lease cost disclosure rather than the amortization schedule, so they must be filtered out of the payment vector before discounting.