
Gross margin is the share of revenue you keep after the cost of the goods you sold, and for a Shopify store it is the first real signal of whether the business works. Here is the formula: gross margin % = (net sales minus COGS) / net sales x 100. Simple enough. The catch is that the gross margin sitting in your accounting software is almost never the margin you actually keep. Discounts, returns, refunds, and free-shipping subsidies quietly chip it down, and most stores never see the gap. By the end of this page you will have the formula, a working calculator, real 2026 DTC benchmarks by category, and the one COGS adjustment most Shopify stores get wrong.
Use the calculator below to get your gross margin in seconds. Enter gross sales and COGS for the period. Add shipping cost and transaction fees if you want a sharper number, since both belong in a real ecommerce cost base. Then flip on the returns-adjusted toggle to see the margin you actually keep after discounts, refunds, shipping, and fees. Most stores stop at the first number. Scroll past the tool for the one you can actually bank.
Gross margin is the percentage of revenue left after you subtract the cost of goods sold. If a store does $100,000 in net sales and the products cost $38,000, gross profit is $62,000 and gross margin is 62%. The dollar figure ($62,000) is your gross profit. The percentage (62%) is your gross margin. People use the terms interchangeably, but they are not the same.
Is gross margin the same as gross profit? No. Gross profit is a dollar amount. Gross margin is that same amount expressed as a percentage of net sales. Gross profit tells you how much you made. Gross margin tells you how efficiently you made it, which is why it travels better across months and across SKUs of different sizes.
Two inputs drive the number. Net sales is revenue after discounts and refunds, not gross sales at full price. COGS is the cost of the goods that left the door. Get either one wrong and the margin is fiction. For a deeper look at where this metric sits among the others, see our ecommerce profit metrics guide.
The gross margin formula is short:
Gross margin % = (net sales minus COGS) / net sales x 100
Gross profit = net sales minus COGS
Gross margin ratio = (net sales minus COGS) / net sales, expressed as a decimal
The ratio is just the percentage before you multiply by 100. A 62% gross margin is a 0.62 gross margin ratio. Same number, different dress.
Here is a worked ecommerce example with realistic Shopify numbers. A skincare brand runs a month like this:
True COGS = $34,000 + $4,000 + $3,500 + $2,500 = $44,000.
Gross profit = $120,000 minus $44,000 = $76,000.
Gross margin = $76,000 / $120,000 x 100 = 63.3%.
If that same brand had counted only the $34,000 product cost, it would have reported a 71.7% gross margin. That eight-point gap is not rounding. It is the freight and fees that a generic formula skips and a Shopify P&L cannot afford to.
With Polar: Closing that eight-point gap by hand means rebuilding a spreadsheet every month. In the Synthesizer semantic layer you connect your COGS, inbound freight, and transaction fees once as Custom Metrics, and CM1 (gross margin after those costs) recalculates automatically as new orders land. The freight and fee lines stop falling out of the math, so the 63.3% number is the one your team reads, not the inflated 71.7%.
Gross margin takes four steps once your cost inputs are clean.
Most stores understate COGS by leaving out freight and fees, which inflates margin and hides which SKUs actually pay rent. The fix is to define COGS once and reuse it everywhere. In Polar, that is what Custom Metrics and Custom Dimensions are for: you model your COGS definition a single time, including freight and fees, and every report inherits it. A KPI is a definition, not a number, and the definition has to live in one place or it drifts.
One honesty note. Polar reads what your store and your cost inputs report. If your COGS feed is missing freight, or your unit costs are stale, the margin will be confidently wrong. Garbage COGS in, garbage margin out. Clean the inputs first, then trust the metric.
These four get mixed up constantly. Here is the difference in one table.
Think of it as a stack. Revenue flows in at the top. Take out COGS and you reach gross margin. Take out the rest of your variable costs, including shipping and ad spend, and you reach contribution margin. Take out fixed costs and overhead and you land on net margin. This is the gross-to-contribution-to-net stack, and it is the connection most explainers never draw.
The practical lesson: gross margin can look healthy while contribution margin bleeds, because ad spend and shipping live below the gross line. A 65% gross margin brand spending half its revenue on paid acquisition is not a 65% business. For the next layer down, read our contribution margin explainer.
Your dashboard says 65% gross margin. After returns and free shipping you keep closer to 52%. That gap is the true-margin trap, and it catches stores that read the headline number and stop.
Four things erode the accounting gross margin. Discounts shrink net sales below list price. Returns and refunds reverse revenue while you keep the reverse-logistics cost. Shipping subsidies on free-shipping orders come straight out of your pocket. None of these show up if you compute margin off gross sales and product cost alone.
Here is the operator pattern we see repeatedly across DTC brands, fully anonymized. A store reports 65% gross margin in its books. Layer in an 8% return rate, a 6% average discount, and free shipping on most orders, and the margin it actually banks lands around 52%. Thirteen points vanish between the report and the bank account. That is not an accounting error. It is the difference between accounting gross margin and the operator's true margin.
With Polar: When the books say 65% and the bank says 52%, the question is which number is governed. The Synthesizer holds a single definition per metric, so a returns-and-discount-adjusted gross margin built as a Custom Metric becomes the one figure everyone references, not two numbers that disagree across reports. No reconciling two spreadsheets before a meeting: the true margin is the default view.
This compounds with the omnichannel-CAC trap, where blended acquisition cost over-credits paid channels and makes thin-margin orders look fine. Read margin and CAC off the wrong base together and you scale the orders that lose money. By 2028 the dashboard is a debug tool, not a product, which means the value is in catching this gap, not in displaying the pretty number.
The Polar solve: build a returns-and-discount-adjusted gross margin as a Custom Metric, so the true number is the one your team sees by default. Then skip the wait entirely with Ask Polar or the Polar MCP and ask, in plain language, "what's my true gross margin by SKU this month." You get a cited answer against your governed semantic layer instead of queuing a request with an analyst. That is the Question Latency Tax, the cost of every decision that waits days for a number, and it is what conversational analytics removes.
Honesty note again: returns-adjusted margin is only as good as your refund data. If returns are logged off-platform or in a 3PL system, reconcile them into your store data first, or the adjustment will undercount.
A good gross margin for ecommerce typically lands between 50% and 70%, but the honest answer depends on your category and your business model. Below are 2026 DTC ranges drawn from aggregated, anonymized operator patterns. Treat them as orientation, not gospel.
Business model shifts the bar. A manufacturer who owns production usually carries the highest gross margin and the lowest flexibility. A reseller who buys wholesale runs thinner because someone already took a cut. A marketplace seller often runs thinnest after platform fees. The rule of thumb for a healthy DTC brand: aim for a gross margin high enough that contribution margin survives your real ad spend and shipping. If gross margin is 40% and you spend 30% of revenue acquiring customers, the math does not close.
These are headline ranges. The number that matters is yours, computed off true COGS, and tracked over time.
Gross margin compresses from both ends: COGS creeps up and net sales leak away. Pull these levers.
The thread running through all of it is measurement at the right grain: per-SKU and per-channel gross margin, not a store-wide average that hides the products dragging you down. In Polar, Custom Metrics and Custom Dimensions let you slice gross margin by SKU and by channel, the Synthesizer semantic layer blends your cost data with Shopify revenue across 400-plus pre-built ecommerce metrics, and for stores running heavy SKU-level analysis at scale, a dedicated Snowflake instance gives you the horsepower to model automated P&Ls down to the SKU. One operator put it plainly: a month-end P&L can show you an X% company gross margin, but only SKU-level margin reveals which products sit well above that average and which ones quietly drag it down.
A note on the data stack: generic tools like dbt, Cube, or AtScale can model margin if you have an engineering team to wire them up. The point of an ecommerce-native layer is that the COGS, returns, and channel logic is already built for Shopify, so you skip the rebuild.
With Polar: The wiring is the cost with dbt or Cube: weeks of engineering before you see a single margin number. With the native Shopify connector the Synthesizer is live in 24 hours and refreshes every 15 minutes, with COGS, returns, and per-channel logic already modeled. Your data lands in a dedicated Snowflake instance you can query, export, or replicate, so the SKU-level P&L is yours to build on rather than a black box you rent.
Book a 20-minute Polar walkthrough and we will build your returns-adjusted gross margin metric live, by SKU and by channel, before the call ends. You bring your Shopify store and your COGS inputs. We will show you the number you actually keep, not the one your dashboard flatters you with. Twenty minutes, your data, your real margin.
