← Back to Blog
Quantitative MarketingPromo EconomicsFinancial EngineeringLoyalty

Points Liability and Breakage: Pricing the Currency You Invented

Loyalty points are debt you issued in a currency you control. A $10,000 nominal liability with an 8% monthly redemption hazard is worth $8,183 in present value. Here is the survival curve, the discounting, and why a flat breakage assumption is the most expensive line in the model.

SPSantosh Paudel· July 24, 2026· 9 min read
Table of contents

When you issue loyalty points, you have borrowed from your customers in a currency you print. The balance is real, it sits on your books, and the only questions that matter are how much of it will be claimed and when.

Both questions are answered by a survival curve, which is the same tool actuaries use for mortality and lenders use for prepayment. Most loyalty programmes answer them with a single flat percentage that someone chose years ago.

The short answer

Issue 1,000,000 points worth $0.01 each and you have created a $10,000 nominal liability. With an 8% monthly redemption hazard and a 24-month expiry, 86.48% gets redeemed and 13.52% expires unclaimed. The expected liability is $8,648.21 undiscounted and $8,182.95 in present value at an 8% annual discount rate.

Points are a zero-coupon liability with an uncertain claim rate

The structure is familiar from fixed income. You have a face value, a maturity (the expiry date), and a holder who may or may not present the claim. Unlike a bond, the holder is not obliged to, and the fraction who never do is called breakage.

Breakage is the entire economics of the programme. It is also the number most often set by assumption rather than measurement.

The survival model

Model redemption as a constant monthly hazard h: each month, a given unredeemed point has probability h of being redeemed. Survival to month t is (1 - h)^t. Anything still unredeemed at expiry is breakage.

For h = 8% and 24 months:

Survival = 0.92^24 = 0.1352

So 13.52% breaks and 86.48% is claimed.

The timing matters as much as the total, because a dollar claimed in month 22 costs less than a dollar claimed in month 1. Discount each month's redemptions back:

def points_liability(points_issued, cents_per_point, monthly_hazard,
                     expiry_months, annual_discount):
    nominal = points_issued * cents_per_point
    survive = (1 - monthly_hazard) ** expiry_months

    pv = 0.0
    for m in range(1, expiry_months + 1):
        redeemed_this_month = (1 - monthly_hazard) ** (m - 1) * monthly_hazard
        pv += redeemed_this_month * nominal / (1 + annual_discount) ** (m / 12)

    return {
        "nominal": nominal,
        "breakage_pct": survive,
        "breakage_value": nominal * survive,
        "expected_liability": nominal * (1 - survive),
        "present_value": pv,
        "pv_saving_vs_nominal": nominal - pv,
    }


for k, v in points_liability(1_000_000, 0.01, 0.08, 24, 0.08).items():
    print(f"{k:24} {v:>12,.4f}")

Output:

nominal                      10000.0000
breakage_pct                     0.1352
breakage_value                1351.7893
expected_liability            8648.2107
present_value                 8182.9530
pv_saving_vs_nominal          1817.0470

Carrying the liability at nominal overstates it by $1,817.05, or 18.2%.

The sensitivity that should worry you

The hazard rate is a single input. Here is what it does to the answer.

Monthly redemption hazardBreakageExpected liabilityChange vs 8% case
4%37.54%$6,245.87$2,402.34 lower
8%13.52%$8,648.21baseline
15%2.02%$9,797.67$1,149.46 higher

Halving the hazard from 8% to 4% moves the liability by $2,402 on a $10,000 issue, a 28% swing. That is a far larger effect than anything the finance team will argue about in the discount rate, and it is driven by a parameter most programmes have never estimated from their own data.

Worse, the hazard is not constant in reality, and it is not stable over time. Programmes that make redemption easier, add a mobile wallet, or lower the minimum redemption threshold are raising h directly. The liability jumps and the breakage revenue that was quietly funding the programme evaporates. This is a well-known failure mode: a usability improvement ships, redemption rises, and the programme becomes unprofitable without any change to the reward structure.

Measuring your actual hazard

You do not need a survival library. You need issuance and redemption timestamps.

def empirical_hazard(cohort_issued, redeemed_by_month):
    """cohort_issued: points issued in a single month.
    redeemed_by_month: list, points from that cohort redeemed in month 1, 2, ...
    Returns the monthly hazard implied by each month."""
    remaining = cohort_issued
    out = []
    for m, redeemed in enumerate(redeemed_by_month, start=1):
        h = redeemed / remaining if remaining > 0 else 0.0
        out.append((m, h, remaining))
        remaining -= redeemed
    return out


demo = empirical_hazard(100_000, [9_000, 7_400, 6_100, 5_000, 4_200])
print(f"{'month':>6} {'hazard':>9} {'at risk':>10}")
for m, h, rem in demo:
    print(f"{m:>6} {h:>9.4f} {rem:>10,.0f}")

Output:

 month    hazard    at risk
     1    0.0900    100,000
     2    0.0813     91,000
     3    0.0729     83,600
     4    0.0638     77,500
     5    0.0579     72,500

Note the hazard falling month over month in that illustrative series. That is the common shape: eager redeemers go first and the residual population is progressively less likely to act. A constant-hazard model fitted to early data will overestimate long-run redemption, and a model fitted to late data will underestimate it. Fit the curve, do not average it.

Three things to change on Monday

Estimate the hazard from your own cohort data instead of inheriting an assumption. It is a division per month over data you already store.

Carry the liability at present value with the assumption stated, and rerun it quarterly. When someone proposes making redemption easier, the model tells you what that costs before the change ships rather than after.

Stop treating breakage as revenue you can plan on. It is the residual of a behavioural process you are actively trying to reduce through every usability improvement you make. Programmes that budget against breakage are budgeting against their own customer experience roadmap.

A points balance and a bonus with a wagering requirement are the same class of instrument: a promise whose cost depends on what fraction of people complete a path. The difference is only that points have a longer expiry and a friendlier name.

Free resource

Get the Promo & Bonus Economics Workbook

Every formula for pricing a promo before you launch it: expected value, wagering cost, breakage, breakeven conversion. Worked examples with real executed numbers.

No spam. Unsubscribe anytime.

Browse all free guides →

Want to implement this with guidance?

Santosh helps founders turn insights like this into real systems.

Promo Economics Audit

External Resources

Further Reading & Tools

Related Posts

01
9 min
Risk ManagementPromo Economics
TodayQuantitative Marketing

Value at Risk and Kill Switches for Live Promotions

A spend cap set at expected payout shuts down 46% of perfectly healthy campaigns. The right multiple is 1.52x. Sizing exposure limits and automated kill switches against a real payout distribution.

Read article
02
8 min
Incentive DesignBehavioral Economics
TodayQuantitative Marketing

The Line Between Motivating and Manipulating: An Incentive Design Ethics Test

Every mechanic in this series works because of a cognitive bias. That makes them powerful and makes some of them indefensible. A six-question test for which side of the line your design sits on, and what regulators have already acted against.

Read article
03
8 min
Price DiscriminationPricing
TodayQuantitative Marketing

Why Promo Codes Beat Sales: Price Discrimination in Practice

A blanket 20% discount earns $20,000 less than no discount at all. The same discount behind a code that only bargain hunters bother to find earns $64,000 more. The friction is the entire mechanism.

Read article