{
  "slug": "promo-code-cannibalization-calculator",
  "title": "Promo Code Cannibalization Calculator",
  "heading": "Promo Code Cannibalization Calculator",
  "category": "financial",
  "url": "https://www.revenuelab.fyi/toolbox/promo-code-cannibalization-calculator",
  "summary": "Find out how much discount revenue would have happened anyway at full price.",
  "description": "A promo code that converts 5,000 orders looks like a win until you account for how many of those buyers would have paid full price without it. This calculator estimates cannibalization by comparing your promo redemption rate against a baseline full-price conversion rate for a similar audience, then splits redeemed orders into incremental (the discount caused the purchase) and cannibalized (the customer would have bought anyway, so the discount is pure margin loss). It computes the net margin impact: incremental orders contribute discounted margin, cannibalized orders lose the full discount amount versus what you'd have earned at full price. The output includes a break-even incrementality rate — the minimum share of orders that must be truly incremental for the promo to not destroy margin versus doing nothing. Retail and e-commerce promos commonly run 30-60% incremental, meaning 40-70% of redeemers were going to buy anyway; loyalty-tier or first-purchase discounts tend to skew more incremental since they target genuinely price-sensitive or new segments. Run this before renewing recurring sitewide sales, since the habit of training your best customers to wait for a code is the slow, compounding cost that a simple 'redemptions vs. revenue' report never shows.",
  "formula": "Incremental orders = redemptions × incrementality rate; Cannibalized orders = redemptions × (1 − incrementality rate); Net margin impact = incremental orders × discounted margin − cannibalized orders × discount amount.",
  "dateModified": "2026-09-30",
  "run_url": "https://www.revenuelab.fyi/api/public/calc?tool=promo-code-cannibalization-calculator",
  "inputs": [
    {
      "id": "redemptions",
      "label": "Promo code redemptions",
      "kind": "number",
      "hint": null,
      "default": 5000,
      "unit": null,
      "min": 0,
      "max": null
    },
    {
      "id": "aov",
      "label": "Average order value",
      "kind": "number",
      "hint": null,
      "default": 80,
      "unit": "$",
      "min": 0,
      "max": null
    },
    {
      "id": "discountPct",
      "label": "Discount percentage",
      "kind": "number",
      "hint": null,
      "default": 20,
      "unit": "%",
      "min": 1,
      "max": 90
    },
    {
      "id": "grossMargin",
      "label": "Gross margin at full price",
      "kind": "number",
      "hint": null,
      "default": 50,
      "unit": "%",
      "min": 1,
      "max": 95
    },
    {
      "id": "incrementalityRate",
      "label": "Estimated incrementality rate",
      "kind": "number",
      "hint": null,
      "default": 45,
      "unit": "%",
      "min": 1,
      "max": 100
    }
  ],
  "outputs": [
    {
      "id": "netMarginImpact",
      "label": "Net margin impact of promo",
      "format": "currency",
      "hint": null,
      "primary": true
    },
    {
      "id": "incrementalOrders",
      "label": "Truly incremental orders",
      "format": "number",
      "hint": null,
      "primary": false
    },
    {
      "id": "cannibalizedOrders",
      "label": "Cannibalized (would've bought anyway)",
      "format": "number",
      "hint": null,
      "primary": false
    },
    {
      "id": "breakEvenIncRatePct",
      "label": "Break-even incrementality rate needed",
      "format": "percent",
      "hint": null,
      "primary": false
    },
    {
      "id": "discountedMarginPerOrder",
      "label": "Margin per discounted order",
      "format": "currency",
      "hint": null,
      "primary": false
    }
  ],
  "worked_example": {
    "inputs": [
      "Promo code redemptions: 5000",
      "Average order value: 80 $",
      "Discount percentage: 20 %",
      "Gross margin at full price: 50 %",
      "Estimated incrementality rate: 45 %"
    ],
    "outputs": [
      "Net margin impact of promo: $10,000",
      "Truly incremental orders: 2,250",
      "Cannibalized (would've bought anyway): 2,750",
      "Break-even incrementality rate needed: 40.0%",
      "Margin per discounted order: $24.00"
    ]
  },
  "how_to": {
    "title": "How to use this",
    "steps": [
      "Enter promo code redemptions.",
      "Enter average order value ($).",
      "Enter discount percentage (%).",
      "Enter gross margin at full price (%).",
      "Enter estimated incrementality rate (%).",
      "Read your net margin impact of promo on the right — it updates as you type.",
      "Hit Share to keep the scenario or send it to someone."
    ]
  },
  "scenarios": [
    {
      "name": "Conservative",
      "description": "Lower-end numbers — what if things land soft?",
      "values": {
        "redemptions": 3000,
        "aov": 50,
        "discountPct": 12,
        "grossMargin": 30,
        "incrementalityRate": 27
      }
    },
    {
      "name": "Typical",
      "description": "Defaults — the most common real-world setup.",
      "values": {
        "redemptions": 5000,
        "aov": 80,
        "discountPct": 20,
        "grossMargin": 50,
        "incrementalityRate": 45
      }
    },
    {
      "name": "Ambitious",
      "description": "Higher-end numbers — what if things really pop?",
      "values": {
        "redemptions": 8000,
        "aov": 130,
        "discountPct": 32,
        "grossMargin": 80,
        "incrementalityRate": 72
      }
    }
  ],
  "limitations": [
    "Results are estimates before tax, fees, and inflation unless an input explicitly covers them.",
    "Rates are treated as fixed for the whole period — variable-rate products will drift from this projection.",
    "This is educational maths, not financial advice. Check anything contractual with the lender or your accountant."
  ],
  "faq": [
    {
      "q": "How do I actually measure the incrementality rate?",
      "a": "Run a holdout: withhold the code from a random matched segment and compare their organic conversion rate to the redemption rate among the group that received it. The gap approximates true incrementality. Without a holdout, you're guessing, and most marketers guess too high."
    },
    {
      "q": "Why can a promo with high redemption still lose money?",
      "a": "If most redeemers were going to buy at full price anyway, you're just handing back margin on orders you already had. High redemption counts feel like success but the net margin impact calculation often turns negative once cannibalization is above 60-70%, which is common for sitewide, non-targeted discount codes."
    },
    {
      "q": "Does this apply to first-purchase-only codes the same way?",
      "a": "First-purchase codes tend to have much higher true incrementality, often 60-80%, because a first-time visitor without brand loyalty is genuinely more price-sensitive. The same formula applies, just plug in a higher incrementality rate estimate based on your own test data."
    },
    {
      "q": "What's the break-even incrementality rate used for?",
      "a": "It tells you the minimum share of redemptions that must be truly incremental before the promo breaks even against doing nothing. If your break-even rate is 55% and your measured incrementality is only 40%, the promo is destroying margin regardless of how many people redeemed it."
    }
  ],
  "related": [
    "https://www.revenuelab.fyi/toolbox/incrementality-lift-calculator",
    "https://www.revenuelab.fyi/toolbox/new-vs-returning-revenue-mix-calculator"
  ],
  "license": "CC-BY-4.0",
  "citation": "RevenueLab — Promo Code Cannibalization Calculator (https://www.revenuelab.fyi/toolbox/promo-code-cannibalization-calculator)"
}