Contribution Margin Formula for Ecommerce: How to Calculate It (with SKU, CAC & CM2/CM3 Variants)

If you only track gross margin, you're flying blind on profitability.

Gross margin tells you that your unit costs less than you sold it for. It doesn't tell you whether the order paid for itself once you factored in the ad spend, the 3PL pick-and-pack, the payment processing fee, the return that came back three weeks later, or the discount code your influencer leaked on Reddit.

Contribution margin does.

This guide covers the contribution margin formula every DTC operator should have memorized, the way it actually breaks down in an ecommerce P&L (CM1, CM2, CM3, CM4), and how to track it per SKU and per channel without spending three days a month rebuilding spreadsheets.

Polar Analytics ships CM1, CM2, CM3, and CM4 as built-in metrics on a governed semantic layer (Synthesizer), so contribution margin is defined once and reused across every SKU, channel, and cohort report. More on how that works below; first, the formula itself.

What is the contribution margin?

Contribution margin is the dollars (or percentage) left after you subtract variable costs from revenue. It's the cash that "contributes" to covering your fixed costs (rent, salaries, software) and to actual profit.

The basic formula is simple:

Contribution Margin = Revenue − Variable Costs

What makes contribution margin powerful in ecommerce is what counts as "variable." Done right, it answers the only question that matters at the unit level: does this order, this SKU, this channel actually make us money?

The contribution margin formula

Per unit Contribution Margin per Unit = Selling Price − Variable Cost per Unit

Total Contribution Margin = Revenue − Total Variable Costs

Contribution margin ratio (percentage) CM% = Contribution Margin ÷ Revenue

The ratio is what you compare across SKUs, channels, and campaigns. A unit that delivers $40 CM at a 60% ratio is in a fundamentally different business than a unit at $40 CM and an 18% ratio.

The first compounds. The second drowns the moment shipping costs tick up or returns spike.

Which costs are actually variable in ecommerce?

This is where most spreadsheets quietly mislead you. A cost is variable if it scales with order volume. Treating fixed costs as variable (or vice versa) is the most common reason two teams in the same company report different CM numbers.

Here's the working list for a typical DTC brand:

Cost line Variable? Notes
COGS (landed product cost) Yes Includes freight-in, duties, supplier-level packaging
Outbound shipping Yes Net of any shipping revenue collected at checkout
Payment processing Yes Usually ~2.9% + a flat fee per transaction
Pick & pack (3PL) Yes Per-order portion of your fulfillment bill
Return processing Yes Net of resale value; includes reverse logistics
Marketplace fees Yes Amazon, TikTok Shop, Walmart referral fees
Influencer affiliate commission Yes If paid per sale
Ad spend Variable, treated separately See CM2 below
Free gift / sample inserts Yes Per-order COGS line
3PL storage / monthly minimums Fixed Fixed
Software (Shopify, Klaviyo, BI tools) Fixed Fixed
Salaries & influencer retainers Fixed Fixed
Studio / content production Fixed Fixed

The line that sparks the most debate is shipping revenue. If you collect shipping at checkout, treat it as part of revenue, and treat your actual carrier cost as a variable cost. Netting them inside one line erases the margin signal at the SKU level.

The second debate is marketplace fees vs. ad spend. Amazon referral fees are a structural variable cost. You can't sell on Amazon without paying them. Meta and Google ad spend is variable but discretionary, which is why most operators carve it into its own layer of the CM stack rather than rolling it into CM1.

CM1, CM2, CM3, CM4: the ecommerce contribution margin stack

A single contribution margin number hides too much. Ecommerce teams work with a stack. Each layer strips away another category of cost so you can see exactly where profit erodes.

The Contribution Margin Stack
From $86 of revenue to $14.70 of CM3 — per unit
Each layer strips away another category of variable cost. Same order, three honest stories.
Revenue
$86 100%
− COGS $22  ·  − Outbound shipping $8
CM1
$56 65%
− Payment $2.80  ·  − Pick & pack $4  ·  − Returns $3  ·  − Marketing $28
CM2
$18.20 21%
− Customer service $1.50  ·  − Affiliate $2
CM3
$14.70 17%
Which cost sits in which layer is your call — define it once in Synthesizer, reuse it across every SKU, channel and cohort.

CM1, order-level economics

CM1 = Net Sales + Shipping Revenue − COGS − Shipping Costs

This is the unit you'd buy. It tells you whether the product itself is profitable before any go-to-market cost.

Why include shipping revenue. Many brands recover part of their shipping cost from the customer. Excluding the inbound shipping revenue while including the outbound cost makes every order look worse than it is. Include both, or exclude both.

What CM1 doesn't include. Payment processing, marketplace fees, 3PL pick & pack, returns. Different teams put these in CM1, CM2, or break them into a separate layer. The right answer is whichever convention your team applies consistently across every report.

In Polar, CM1 is one of four contribution-margin metrics provided out of the box, with the formula editable in Synthesizer so your shipping-revenue and COGS conventions match how your finance team defines them.

CM2, post-marketing economics

CM2 = CM1 − Variable Operational Costs − Marketing Spend

Variable operational costs here mean payment processing, pick & pack, return handling. Marketing spend is your performance ad spend across Meta, Google, TikTok, and any other paid channel.

CM2 is the metric most DTC teams operate on weekly. It answers: after we paid to acquire the customer and fulfill the order, did we keep anything?

This is also where contribution margin starts to interact with your CAC and MER. If CM1 is healthy but CM2 is negative, the problem isn't the product. It's the acquisition cost.

In Polar, CM2 slices by channel and by SKU off the same definition, so the weekly "what kept margin and what didn't" review doesn't require a rebuild.

CM3, fully loaded variable economics

CM3 = CM2 − All Other Variable Operating Costs

CM3 typically includes things like customer service cost per ticket, fraud / chargeback losses, affiliate payouts, and any other variable expense tied to keeping the order alive end-to-end.

CM4, the full view

CM4 (some teams call it "full" or "true" contribution margin) nets out every variable cost the team can identify. That includes imported expenses from finance: currency conversion losses, FX hedging costs, packaging supplies, anything that scales loosely with volume. It's the number a CFO wants to see in a board deck.

It's also the number that benefits most from a clean data foundation. See the SKU-level section below.

A real example, anonymized. A subscription consumer goods brand we worked with had a healthy CM1 around 60% but a CM2 that swung between +8% and −4% by week. The biggest driver wasn't ad efficiency.

It was a flat-fee 3PL pick rate that was variable on a per-unit basis, not per-order, and bundle SKUs hid the cost inside an aggregated line. When the team split CM2 by SKU, two bundles surfaced that were dragging the entire portfolio down.

CM2 by SKU
The portfolio average hid two losers.
Blended CM2 looked fine. Split by SKU, two bundles were dragging everything down.
Core Refill
+28%
Starter Kit
+22%
Travel Size
+19%
Subscription Box
+15%
Trial Duo (bundle)
−4%
Mega Bundle (bundle)
−9%
Same definition, sliced by SKU. The unit that ships isn't always the unit you sold.

A worked example

Take a hypothetical apparel brand. One SKU, single market, single channel, last 30 days:

Line Per unit Notes
Selling price $80
Shipping revenue (collected) $6
Revenue $86
COGS (landed) −$22 Includes freight-in
Outbound shipping −$8
CM1 $56 (65%)
Payment processing −$2.80 2.9% + $0.30
Pick & pack −$4
Returns reserve −$3 Modeled at 8% return rate × cost of reprocessing
Marketing spend (allocated) −$28 Blended CAC across paid + email
CM2 $18.20 (21%)
Variable CS allocation −$1.50 Tickets per order × fully-loaded agent minute
Affiliate commission (avg) −$2.00 Weighted average across attribution mix
CM3 $14.70 (17%)

That brand could legitimately tell three different stories depending on which CM layer they quote. A retailer pitch deck will lead with CM1 (the product is solid). The board deck leads with CM3 (the business is solid). The weekly performance review leads with CM2 (paid is buying us real margin, not just revenue).

All three are true. None of them is the "right" one in isolation.

Contribution margin vs. gross margin: which to track?

Gross margin = Revenue − COGS. That's it.

Contribution margin includes the rest of the variable cost stack: shipping, fulfillment, payment fees, and (in the CM2/CM3 layers) the cost of getting the customer through the door.

Gross margin is a product question. Contribution margin is a business question. A SKU with 70% gross margin can ship at a negative CM2 once you fold in $35 CAC and $8 fulfillment. A SKU with 40% gross margin can be your most profitable line if it ships cheap and customers come back twice a quarter.

For the weekly operator review, contribution margin (specifically CM2) is the more honest number.

What's a good contribution margin for ecommerce?

There is no universal benchmark, but there are useful ranges by category.

Apparel and accessories tend to land with CM1 in the 55 to 70% range and CM2 in the 15 to 25% range.

Beauty and personal care often run higher on CM1 (60 to 75%) and similar on CM2.

Food and beverage compresses across the stack: CM1 in the 35 to 50% range and CM2 frequently in single digits, with the model defended by repeat purchase.

Consumer electronics is the inverse, thin CM1 (20 to 35%), defended by attach-rate accessories.

The most useful benchmark isn't external. It's your own CM2 trend over the last six months. A brand whose CM2 is flat or improving while revenue grows is a healthy business. A brand whose revenue grows while CM2 erodes is paying to print orders.

How to calculate contribution margin per SKU at scale

This is the part where most operators hit a wall. CM is straightforward in a spreadsheet for a single SKU. It gets hard fast across:

  • Multiple sales channels (Shopify + Amazon + TikTok Shop + Walmart, each with different fee structures)
  • Multiple markets (different shipping costs, different currencies, different return rates)
  • Multiple cost types (COGS in your ERP, ad spend in five platforms, fulfillment in a 3PL portal, returns in Loop or Shopify)
  • Bundle SKUs (the unit that ships isn't the unit you sold)
  • Cohort time lags (the customer acquired today returns the product in 21 days, paid for the return in 28, refunded in 34)

The pattern that actually works: calculate contribution margin in a layer that sits between your raw data sources and your reports, so the formula is defined once and reused everywhere.

That's the principle behind a semantic layer. You connect your sources (ecommerce platform, ad platforms, 3PL, finance) once. You define each layer of the contribution margin stack (CM1, CM2, CM3, CM4) once, with the cost lines and joins specific to your business. From then on, every dashboard, every per-SKU breakdown, every AI query reads from the same definition.

Define Once, Reuse Everywhere
One CM definition, every report.
Raw sources
Shopify · Amazon · TikTok Shop
Meta · Google · TikTok Ads
3PL costs · Finance · ERP
45+ one-click connectors
Synthesizer · Semantic layer
CM1 · CM2 · CM3 · CM4 defined once
Country-specific shipping, marketplace fees, return rates — governed, finance-approved.
Reused across
CM by SKU
CM by channel & region
CM by cohort
Ask Polar · MCP · Claude
Spreadsheets break at 50 SKUs because every analysis duplicates the formula. One definition, zero drift.

This is the use case Polar Analytics was built for.

Brands connect 45+ one-click data sources, model contribution margin once in the semantic layer (with country-specific shipping logic and marketplace-specific fees, plus 3PL cost data via Google Sheets or a direct connector), and then slice CM by SKU, by channel, by region, or by cohort without rebuilding the formula each time.

When the team asks "what was CM2 by SKU last week?" in Ask Polar (or through Claude or another AI surface via Polar's MCP), the answer reads from the same definition the finance team signed off on.

The point isn't the tool. The point is the architecture: define once, reuse everywhere. Spreadsheets break at 50 SKUs because every new analysis duplicates the formula, and every duplicate is one more place a number can drift.

Common mistakes ecommerce operators make with contribution margin

  1. Mixing fixed and variable costs. The 3PL's flat monthly storage minimum is fixed. The per-order pick fee is variable. Lumping them together makes CM2 look better in quiet months and worse in peak. Neither is real.

  1. Excluding return processing. A 12% return rate at $4 of reverse logistics per return is roughly $0.50 off your CM per gross order. At scale, that's the difference between a profitable channel and a money-losing one.

  1. Using blended CAC for channel-level CM. If you allocate the same CAC to every order regardless of channel, your "by-channel CM2" report is meaningless. Use channel-specific (or campaign-specific) ad cost when you slice CM by channel.

  1. Ignoring trends. A single CM2 number is a snapshot. The shape of CM2 over time tells you whether your business is compounding or eroding. Track it weekly. Compare cohorts.

  1. Treating shipping revenue inconsistently. If you net shipping revenue into one product and not another, your SKU-level CM comparison is broken before the analysis starts.

  1. Forgetting attribution lag. An order placed today, with ad spend attributed today, with a refund in 21 days, is three different rows in three different systems. The cleanest CM reports reconcile those rows by order, not by date alone. Polar's Lifetime ID reconstructs the full customer journey across device, session, and channel, and each order carries its order number through the stack, so a return three weeks later still ties back to the original order's date and acquisition campaign.

Lifetime ID
One order. Three systems. 34 days.
A refund three weeks later still ties back to the order's original date and acquisition campaign.
DAY 0
Order placed
Ad spend attributed today, in your ads platform.
Meta / Google Ads
DAY 21
Return initiated
Reverse logistics logged in a different tool.
Loop / Shopify
DAY 34
Refund settled
Finance row, third system, third date.
Finance / ERP
Lifetime ID Order #1234 carries through every system → the refund reconciles to Day 0's acquisition campaign.
The cleanest CM reports reconcile by order, not by date alone.

A note on what contribution margin can't tell you

This is the section most guides skip.

Contribution margin is a backward-looking number. It tells you what already happened. It does not tell you whether the next dollar of ad spend will be profitable.

That's an incrementality question, and the answer is Causal Lift (Polar's GeoLift-based incrementality testing). Causal Lift tells you whether the next increment of ad spend drives true incremental revenue, or just shifts spend you'd have captured anyway, so you can scale, cut, or maintain with confidence. Contribution margin also doesn't tell you which customers will come back. That's a cohort retention question.

And it can hide structural problems: a brand can show healthy CM2 by leaning on a small group of repeat buyers while new-customer CM2 is deeply negative.

Pair contribution margin with new-customer CAC, repeat purchase rate, and channel-level incrementality testing. CM tells you what the business made. The other three tell you whether tomorrow's CM will be better or worse.

Frequently asked questions

The contribution margin formula is Revenue minus Variable Costs. For ecommerce, the most useful working version is CM1 = Net Sales + Shipping Revenue − COGS − Shipping Costs.
Include ad spend in contribution margin at the CM2 layer, not at CM1. CM1 measures order-level product economics. CM2 measures post-marketing economics, which is the number most operators use for weekly decisions.
Yes. Outbound shipping cost is a variable cost and belongs in the contribution margin calculation. If you also collect shipping revenue at checkout, include that on the revenue side so the comparison stays apples-to-apples.
Gross margin only subtracts COGS from revenue. Contribution margin subtracts COGS and the rest of the variable cost stack: shipping, fulfillment, payment fees, and at the CM2 layer, marketing spend. Gross margin tells you about the product. Contribution margin tells you about the business.
You need each SKU's revenue, COGS, and an allocation of variable costs that scale with that SKU's unit volume. The allocation is the hard part: pick & pack rates, return rates, and (for channel-level analysis) channel-specific ad cost all need to be allocated per SKU rather than averaged across the catalog.
Contribution margin after marketing is the layer of the CM stack that subtracts paid marketing spend from CM1 (and usually variable ops like payment processing and fulfillment). Different teams call it CMAM, CM2, or post-marketing CM. Same idea.
It depends on the category. Apparel and beauty often run CM1 in the 55 to 75% range and CM2 in the 15 to 25% range. Food and beverage is tighter. The most useful benchmark is your own CM2 trend over the last six months, not the industry average.
Yes. Polar ships with CM1, CM2, CM3, and CM4 as built-in metrics. You connect your data sources (45+ one-click integrations, plus 3PL cost uploads via Google Sheets or a direct connector), customize the formula to match your business in Synthesizer, and slice by SKU, channel, region, or cohort. Polar populates analytics within 24 to 48 hours of connecting your sources; full guided onboarding typically runs about 30 days.

Contribution margin is the metric that decides whether you have a business or a revenue line.

Track CM2 weekly. The brands that survive a CPM spike are the ones who already knew which orders were paying for themselves and which were quietly bleeding.

Want to see CM1, CM2, and CM3 on your own Shopify data? Book a 20-minute Polar walkthrough.

Join 4,000+ leading Shopify brands around the world using Polar Analytics to stop manually compiling their data

Schedule a demo
Quad lock
Aimn'
Lifetime brands
Marcella New York
The Frankie Shop
Tiege Hanley
Polene
Seavees
Ripndip
Albion Fit
Kiss USA
Konges slojd
Lemaire
nohow
Maniere de Voir
Volcom
Coes
Razor Group
Oneskin
State & Liberty
Warren James
Dyper
Bonsoirs
From Future
RSVP
Merci handy
Soi Paris
Yellowpop
Olipop
Soko Glam
Fanjoy
Hero
Almond Cow
Polène