The reason returns and discounts erode margin so reliably is that they're structural, not episodic. Most operating dashboards present them as point-in-time numbers — "returns were 7.4% in March" — when the right lens is rate-of-change against a cohort. Both numbers tend to drift up over time as the brand scales (more channels, more promo dependence, more first-time buyers) and the drift is invisible at the monthly level because each individual month is within tolerance of the prior one.
The cumulative result is what gets caught at year-end: gross margin compressed by 200–400bps, contribution margin compressed by 400–800bps, and a CFO asking the marketing team why ROAS looks fine but cash is tight. The honest answer is that gross revenue grew as planned and the gross-to-net path got steeper without anyone owning it.
Two leaks that always travel together
Returns and discounts are usually owned by different teams — returns by ops or merchandising, discounts by marketing — and reported in different reviews. That separation is part of why the compression goes undetected. The two are linked:
- Heavy promo cadence drives lower-intent buyers who return at higher rates than full-price buyers. A site-wide 20%-off promo in apparel often produces a return rate 30–60% higher than the same SKUs sold at full price.
- Stacked promo events compound discount take. A welcome code (15%) plus a category sale (20%) plus a free-shipping threshold subsidy (~5% effective) is not a 40% discount; it's closer to 36% gross-to-net erosion when stacked on the same order — and it's even worse when those orders are also the orders most likely to come back.
- Returns themselves cost more than the lost revenue. Most operators model returns as "we lose the revenue." The full cost is the revenue, plus reverse logistics, plus restocking labor, plus pricing concessions on returned goods that get resold at outlet, plus the COGS on items that can't be resold at all. The fully-loaded return cost on apparel is usually 2.5–4x the headline return rate.
The gross-to-net waterfall every operator should print
The single most useful artifact for catching this leak is a monthly gross-to-net waterfall. Every brand should be running it. Few do. The structure:
| Line | % of gross | Notes |
|---|---|---|
| Gross revenue (orders × list AOV) | 100% | before any reductions |
| − Code/cart-level discounts | −x.x% | by code, by stacking pattern |
| − Automatic promotions / sale pricing | −x.x% | storefront markdowns |
| − Free-shipping subsidy | −x.x% | shipping cost not collected |
| − Returns (revenue refunded) | −x.x% | by SKU, by customer cohort |
| = Net revenue | ~85–92% | this is what hits your P&L top line |
| − COGS | −x.x% | |
| − Variable fulfillment + payment | −x.x% | |
| = Contribution margin | 15–35% typical | the operating reality |
The discipline here is to refresh this waterfall monthly with year-over-year comparisons on every line. Drift on any individual line of 50–100bps in a month is normal. Drift of 50–100bps year over year, sustained for 3+ months, is a structural change that's costing you real money. That's the signal you act on.
Discount stacking: the hidden compounding
Most operators report discount rate as a single number — "we ran 8% discount take last month." The actual structure is far more interesting and almost always more painful. The orders that take a discount aren't a uniform group:
- Welcome-code only: typical effective discount 10–15%, used by ~40% of new customers. The volume is large but the per-order erosion is contained.
- Storefront sale only: 15–30% off, depending on the campaign. Operators usually count this correctly.
- Stacked (welcome + storefront): often 30–45% effective. This is the bucket that's miscounted. Welcome codes may compute on already-marked-down prices; on top of that, customers who use the welcome code disproportionately also use the next code they receive.
- Loyalty / referral / win-back: usually 5–15%, but tends to land on customers who would have bought anyway.
The action item is to break discount take into these buckets and look at the stacking rate. Most brands we audit find that 8–15% of orders involve stacked discounts, and those orders take 2–3x the average discount per order. If you cap stacking on the high-value codes (or simply enforce one-code-per-cart on certain categories), you can recover 50–150bps of discount take without touching customer-facing communication.
The return-rate cohort view
Headline return rate is usually computed as returns this month ÷ orders this month. That's wrong twice. Returns lag orders, and the order base mix changes month to month. The honest view:
- Returns by order cohort. Group orders by the month they were placed. For each cohort, track the cumulative return rate at 30 / 60 / 90 days post-order. Apparel typically peaks at 60–75 days; CPG and consumables much earlier.
- Returns by acquisition source. Cohort the first-order returns by channel (email, paid social, paid search, organic, retail). Promo-heavy paid social cohorts often return at 1.5x the rate of organic.
- Returns by promo level. Inside each cohort, segment by what discount the order took. Heavily-discounted orders tend to return more. The premium for selling at full price isn't just margin — it's a lower fully-loaded return cost.
- Returns by SKU. Always look at the top 20 SKUs by return rate, not just the top 20 by volume. Products with structural sizing or quality issues often hide inside a brand-level "7% return rate" that looks fine.
Run the cohort view monthly. The first time you do it you'll usually find a SKU or a campaign type with materially worse economics than the average. Fixing one or two of those (improved sizing guidance, removed from promo eligibility, repriced) is often worth more than a quarter of CRO testing.
Worked example: 4 points of CM hidden in plain sight
A real shape we've seen multiple times. A brand reports last year's return rate as 7.2% and discount take as 8.5%. This year, return rate is 7.9% and discount take is 9.6%. Each individual change is "within normal." The combined effect:
| Line | Last year | This year | Δ |
|---|---|---|---|
| Discount take % of gross | 8.5% | 9.6% | +1.1pt |
| Return rate % of gross | 7.2% | 7.9% | +0.7pt |
| Net revenue % of gross | 84.3% | 82.5% | −1.8pt |
| Gross margin on net | 62% | 61% | −1.0pt |
| Reverse logistics cost (net) | 1.2% | 1.4% | −0.2pt |
| Combined CM erosion | ~3.0–4.0pt |
On a $20M brand running 22% contribution margin, that's $600K–$800K of contribution that disappeared without any single line item flagging it. It shows up at year-end when the EBITDA forecast misses by a number that "doesn't make sense given revenue performance." It always makes sense. It's just buried.
The diagnostic test we run on every audit: pull the gross-to-net waterfall for the same fiscal month, current year vs. prior. If the net-revenue-as-%-of-gross line has dropped 100bps or more, you have a margin compression story regardless of what your headline P&L says. Most teams have never run this comparison.
A playbook to claw it back
Three layers, in order of speed:
Layer 1: Immediate (this quarter)
- Cap stacking on the top 3 promo codes. One-code-per-cart on at least the welcome flow.
- Audit auto-applied discounts and storefront sales. Most brands carry 1–2 evergreen markdowns that no one remembers turning on.
- Pull the SKU-level return-rate report. The top 20 by return rate get flagged for either repricing, promo exclusion, or a sizing/PDP fix.
- Build the gross-to-net waterfall and put it on the monthly review agenda.
Layer 2: Process (next two quarters)
- Move from "discount take" as a single KPI to a stacking-aware breakdown (welcome only, storefront only, stacked, loyalty). Set distinct caps.
- Cohort-track returns by acquisition source. Bake source-specific return assumptions into your CAC payback model.
- Tighten free-shipping thresholds where AOV permits — often the lowest-effort, highest-yield discount-line lever.
Layer 3: Structural (this year)
- Reposition welcome codes from blanket discounts to threshold incentives or product samples — both convert similarly with much less margin erosion.
- Build sizing/fit guidance into the PDP for the highest-return-rate SKUs.
- Move loyalty incentives from discount to reward currency that's redeemable at the customer's discretion. Reduces stacking and increases redemption discipline.
Watch-outs
Don't yank discounts overnight. Most brands have priced their unit economics around a discount-baked top line. Removing a welcome code in one shot will usually drop new-customer conversion 15–30% — and the contribution recovered won't offset the volume lost. Move in 100bps increments and watch the volume-to-margin trade.
Don't let returns become a customer-experience cost-cut. Increasing return friction (longer windows, restocking fees, smaller print) is a fast way to reduce headline return rate and a faster way to crater repeat rate. The right fix is reducing returns at the cause (sizing, expectations, quality), not punishing customers for them.
Don't trust the average. A 7% return rate hides 30%+ rates on a few SKUs. A 9% discount take hides 40% effective stacking on a small but valuable bucket. Always look at the distribution, not just the mean.
Returns and discounts are the slowest-moving and most under-reported lines on most ecommerce P&Ls. They're also the places where one analyst with a cohort spreadsheet and a willing CFO can recover 200–400bps of contribution margin in a year — and where the brands that compound margin separate themselves from the brands that compound revenue. The gross-to-net waterfall is the artifact that makes it visible. Print it monthly.