Skip to main content

What a quantity discount is

A quantity discount is a “first N discounted” mechanism: customers get a pool of discounted units that refreshes on a cadence, depletes against usage, and resets at each cadence boundary.
1,000 discounted API calls/month, $0.001/call
January: 3,500 calls → 1,000 discounted, 2,500 billable → $2.50
February: 800 calls  → 800 discounted, 0 billable       → $0.00 (200 unused = lost)
Unlike a percent or fixed discount, which act on the dollar amount after pricing has been calculated, a quantity discount reduces quantity before the pricing model runs. That timing matters: it can shift which bracket a customer lands in for volume or tiered pricing, sometimes in counterintuitive ways (see the bracket-shift behavior below).

Scope

DimensionCoverage
Product typesPIT (consumption-based) and POT (access-based)
Quantity strategiesOn-demand and recurring
Pricing modelsAll unit-based models (per-unit, volume, tiered, package, step)
Discount levelPer product/pricing — not cross-product or contract-level

The core mechanic

  1. Pool created — a fresh pool of discounted units is created at each cadence boundary.
  2. Deplete chronologically — periods within the cadence window consume from the pool in order.
  3. Bill the remainder — usage beyond the pool is billable.
Quarterly cadence, monthly billing, 500 discounted/quarter:
January:  Used 200 → Discounted: 200, Pool left: 300, Billable: 0
February: Used 250 → Discounted: 250, Pool left: 50,  Billable: 0
March:    Used 100 → Discounted: 50,  Pool left: 0,   Billable: 50
Q2: Pool resets to 500.
In Phase 1, unused units always expire at the cadence boundary — there’s no carryover into the next cycle.

Cadence relative to billing period

RelationshipExampleBehavior
Cadence = billing periodMonthly cadence, monthly billEach billing period gets its own pool
Cadence > billing periodQuarterly cadence, monthly billA single pool is shared across months and depletes chronologically
Cadence < billing periodDaily cadence, monthly billEach day gets its own pool; month-end is the sum of daily overages
No cadenceFunctionally the same as cadence = billing period: each billing period gets the full discount value, but proration of partial windows doesn’t apply

How it treats PIT and POT identically

The discount engine treats PIT and POT identically — it receives a quantity and subtracts discounted units from it, without knowing or caring whether that quantity came from a PIT meter or a POT allocation. For PIT, this looks like usage being offset month to month:
SMS @ $0.05, Discount: 100 discounted/month (monthly cadence)
January: 150 sent → 100 discounted, 50 billable → $2.50
February: 80 sent → 80 discounted, 0 billable   → $0.00 (20 unused = lost)
For POT, the discount reduces a stable allocation rather than a fluctuating usage count:
300 seats @ $20/seat/month, Discount: 50 discounted (monthly cadence)
Every month: 300 − 50 = 250 billable → $5,000
Upgrade to 500: 500 − 50 = 450 billable → $9,000
If the allocation is smaller than the discount itself (for example, 30 seats against a 50-unit discount), only 30 units get discounted — the remaining 20 are unused and lost, since there’s no carryover in Phase 1.

Lifetime caps track consumption, not pool size

A lifetime cap (max_lifetime) limits the total discounted units ever consumed across the contract — not the size of any single pool. Unused or wasted discounted units don’t count toward this cap; only units actually applied against usage do.
100 discounted/month, max 1,000 ever
Month 1:  500 calls. Discounted: 100. Lifetime: 100.
Month 2:  80 calls.  Discounted: 80.  Lifetime: 180. (20 unused ≠ counted)
...
Month 11: 200 calls. Discounted: 20 (only 20 left). Lifetime: 1,000.
Month 12+: All billable.
How long a lifetime cap lasts depends entirely on usage — using the full pool every period exhausts it faster than using only part of it. Cadence reset and lifetime cap are independent, orthogonal mechanisms and can be combined: cadence controls when the pool refreshes, while the lifetime cap controls how much can ever be consumed.

Proration of the pool for partial cadence windows

When a cadence window is only partially covered — for example, a contract starting mid-month — the pool itself can be reduced proportionally, controlled by the prorate_stub flag.
pool = value × (window_days / full_cadence_days)
1,000 discounted/month, contract starts Jan 15 (17 of 31 days):
Prorated pool = 1,000 × (17/31) = 548.39
By default (prorate_stub=false), the full pool applies even to a partial window. This is distinct from POT’s own proration — for POT, pricing proration adjusts the dollar amount for a partial period, while discount proration (when enabled) adjusts the quantity pool. These operate on different axes and aren’t expected to interact directly.

Bracket-shift effects on volume and tiered pricing

Because the quantity discount reduces the billable quantity before the pricing model runs, it can shift which bracket a customer lands in:
  • Volume pricing: reducing quantity can move a customer into a lower bracket, which sometimes carries a higher rate — counterintuitively, the discount can increase the invoice in that scenario.
    Brackets: [10000, 100000, inf] @ [$0.01, $0.005, $0.001]
    QD: 5,000 discounted/month, customer uses 14,000:
    Without QD: 14,000 → Bracket 2 → 14,000 × $0.005 = $70
    With QD:    9,000  → Bracket 1 → 9,000 × $0.01  = $90
    
  • Tiered pricing: reducing quantity simply means fewer tiers get filled. There’s no equivalent paradox here — the total is always less than or equal to what it would be without the discount.
ModelQuantity discount applicable?Notes
Flat feeNoFixed amount regardless of quantity
PackageYesFewer units means fewer packages
PercentNoBased on monetary input, not units
StepYesFewer units means fewer steps triggered

Stacking with other discounts

Quantity discounts reduce units first; dollar and percent discounts apply afterward to whatever amount results. Multiple quantity discounts (for example, a daily one and a monthly one) can coexist via the order field, each depleting its own pool independently.
50 discounted (order=1) + 20% off (order=2), 200 calls @ $0.01
Step 1: 200 − 50 = 150 billable units
Step 2: 150 × $0.01 = $1.50
Step 3: $1.50 × 80% = $1.20

What’s deferred to a later phase

Carryover of unused units, expiry models beyond use-it-or-lose-it, grant-timing controls (such as delaying availability after payment), per-event scope, and prepaid entitlement balance tracking are all out of scope for the current phase. The discount’s active window currently follows the line item’s own lifecycle rather than having an independent start or end date.