At a glance
Store-wide gross margin gauge: total gross profit divided by total revenue across all line items over the trailing 30 days, with prior-30 comparison. The single most important profitability signal on the BC dashboard. Where individual brand or product margins live in BC Margin by Brand, this card aggregates everything to one number and fires an alert when it slips below 35%, the floor at which most BC stores are no longer covering their fully-loaded operating costs.
| What it counts | (SUM(line_revenue_ex_tax) - SUM(line_cost)) / SUM(line_revenue_ex_tax) * 100 over the trailing 30 days, vs prior 30. Cost from cost_price field per SKU; revenue from line items (excluding shipping). |
| API endpoint | GET /v3/catalog/products for cost_price per SKU; GET /v2/orders/{id}/products for line revenue. The OpenSearch index materialises per-SKU revenue and cost per day, then aggregates store-wide. |
| VAT / tax treatment | Ex-tax revenue (VAT and sales-tax stripped before margin computation). |
| Shipping | Excluded from both revenue and cost; shipping has its own margin equation. |
| Discounts | Deducted from revenue side; cost stays the same, so heavy promo periods compress margin. |
| Refunds | Not deducted (gross margin). For net margin including refunds, configure under Settings → Refund handling. |
| Cancelled orders | Excluded. |
Incomplete orders | Excluded. |
| Currency | Multi-currency aggregated using daily FX. Cost is in primary currency by convention. |
| Channels | All channels included by default. Per-channel margin would be valuable for B2B-vs-DTC visibility; configure under Settings → Margin scope → Channel filter. |
| B2B Edition behaviour | B2B price-list orders carry lower margin (wholesale price < retail). B2B-active stores see headline margin pulled down 5-15pp from the DTC-only equivalent. Configure DTC-only view to read pure DTC margin separate from B2B. |
| Cost data quality | cost_price is merchant-maintained in BC; missing values default to zero, inflating margin to 100%. The card warns when cost-data coverage is below 90% of revenue-weighted SKUs. Run a cost-data audit before relying on the margin number. |
| Promotional cycles | Cart-level discounts pro-rate across line items, depressing margin during promo days; expect 3-7pp margin compression on heavy promo days. The card’s 30-day window smooths this; weekly views show more volatility. |
| Time window | 30D vsP (rolling 30 days vs prior 30). |
| Alert trigger | <35% (margin pressure). The 35% floor is the BC-ecosystem-wide threshold below which most stores struggle to cover fully-loaded operating costs (3PL, ad spend, payment fees, customer service). Stores with structurally lower-margin assortments (commodity goods, electronics) should configure their own floor. |
| Roles | owner |
Calculation
Calculated automatically from your BigCommerce data. See the At a glance summary above for what the metric tracks and the worked example below for a typical reading.Worked example
A US specialty foods retailer on BigCommerce Pro with own-label + reseller brands, B2B Edition active. Snapshot for 1 Apr to 30 Apr 26 vs prior 30 days.| Metric | Current 30D | Prior 30D | Delta |
|---|---|---|---|
| Revenue (ex-tax) | $354,000 | $341,000 | +3.8% |
| Cost (COGS) | $185,330 | $176,200 | +5.2% |
| Gross profit | $168,670 | $164,800 | +2.3% |
| Gross margin % | 47.7% | 48.3% | -0.6pp |
| Alert status | Healthy (above 35% floor) |
| Cohort | Revenue | Margin |
|---|---|---|
| DTC (web + Amazon + POS) | $186,000 | 54.2% |
| B2B Edition portal | $168,000 | 40.5% |
| Aggregate | $354,000 | 47.7% |
- Headline 47.7% (-0.6pp) is healthy and within normal MoM variance. The 35% alert floor isn’t close. The slight compression (-0.6pp) is within the noise band of ±1pp; not yet trend-worthy.
- DTC at 54.2% vs B2B at 40.5% = a 13.7pp gap. This is the structural wholesale discount, perfectly normal. The headline 47.7% is the volume-weighted blend of the two cohorts. For DTC-only assessment, read 54.2%; for finance and board reporting, read 47.7%; both are correct at their own scope.
- Cost grew 5.2% MoM while revenue grew 3.8%. Cost is outpacing revenue, the leading indicator of margin compression. Investigation: did a key supplier raise prices? Did shipping cost (when included in
cost_priceas landed cost) increase? Cost growth above revenue growth is the canary; track for two more months before calling it a trend. - The 35% floor is conservative for specialty foods (typical specialty-foods margin 45-60%); a more realistic alert floor for this merchant is 42% (5pp below their typical baseline of 47-50%). Configure category-aware floors under Settings → Alerts → Margin floor.
- B2B at 40.5% is healthy for B2B Edition. B2B margins of 35-45% are normal; below 30% suggests over-discounting wholesale; above 50% suggests under-using B2B’s wholesale pricing capability (you’re missing the wholesale-discount opportunity).
- Read alongside BC Margin by Brand to decompose; a 0.6pp headline drop usually traces to one or two brands.
- Audit cost-data coverage. If <90% of SKUs have populated
cost_price, the headline number is unreliable. - For 2 consecutive periods of margin compression, investigate: supplier price increases, mix shift toward lower-margin SKUs, increased promo density.
- Configure category-aware alert floor. The 35% default is a floor for general retail; specialty / premium categories should be 5-10pp higher.
- For B2B-active stores, run separate DTC-only and B2B-only margin reads to separate operational signals.
Sibling cards merchants should reference together
| Card | Why pair it with Gross Margin |
|---|---|
| BC Margin by Brand | Brand-level decomposition; identifies which brand is moving the headline. |
| Total Revenue | Revenue side of the margin equation. |
| BC Top SKUs Revenue | Hero-SKU contribution to overall margin. |
| BC Top Coupons | Promo cycles compress margin. |
| BC AOV with/without Discount | Discount-density’s margin impact. |
| BC Channel Refund Rate | High-refund + thin-margin = bleed. |
| BC Revenue by Brand | Volume context for margin contribution. |
| BC Revenue by Category | Category mix impact on overall margin. |
Reconciling against the vendor’s own dashboard
Where to look in BigCommerce Control Panel: BigCommerce does not natively surface gross margin as a single dashboard tile. Reports → Sales (Plus / Pro / Enterprise) shows revenue but cost / margin requires Custom Reports or Insights add-ons. For per-product cost: Products → individual product → Identifiers shows thecost_price field. The lack of native margin reporting is the single most-common reason BC merchants implement Vortex IQ.
Why our margin may differ from BC reports / accounting:
| Reason | Direction |
|---|---|
Cost data freshness. We use whatever cost_price is currently in BC; stale costs inflate margin. | Vortex IQ HIGHER (using stale low cost) |
| VAT / tax handling. We use ex-tax revenue; BC’s reports vary. | Vortex IQ MARGIN MATCHES if both ex-tax |
| Refund treatment. We don’t deduct refunds (gross); accounting does (net). | Vortex IQ HIGHER |
| Currency conversion. Daily FX vs accounting month-end FX. | Sub-1% gap |
| Bundle costs. Bundle parent vs component cost varies. | Either direction |
| Cancelled-order impact. We exclude cancelled; accounting may include reversal entries. | Vortex IQ HIGHER |
Landed-cost vs FOB. We use whatever’s in cost_price; if you populate FOB only and landed includes freight + duty, accounting will show lower margin. | Vortex IQ HIGHER |
| Card | Expected relationship | What causes legitimate divergence |
|---|---|---|
netsuite.netsuite_gross_margin | NetSuite GL-grounded margin should match within 1-3% | NetSuite uses costing method (FIFO, weighted avg); BC’s cost_price is point-in-time. |
quickbooks.qb_gross_margin | QuickBooks gross margin correlates strongly | QuickBooks accrues COGS at fulfilment; we attribute at order. Timing differences. |
xero.xero_gross_margin | Xero’s GP report should match within 1-2% | Xero’s COGS includes some operational costs; we measure pure product cost only. |
shipbob.sb_landed_cost | Adds 3PL fees to COGS | Configure landed-cost mode if your books include 3PL fees in COGS. |
cost_per_item) and Adobe Commerce (per cost); merchant-facing semantics are equivalent.
Known limitations / merchant FAQs
My margin reads 100%. Is the brand a gold mine? Almost certainly not. Most likely cause: missingcost_price data. BC defaults the field to zero, so revenue minus zero cost = 100% margin. Audit cost coverage in Products → Inventory by filtering for cost_price = 0. Populate cost data; the margin will normalise.
Why is the alert floor 35%?
Because most BC stores below 35% gross margin can’t cover their fully-loaded operating costs (3PL ~5-8%, ad spend ~10-15%, payment fees ~3%, customer service ~2%, platform fees ~2-3%). Total operating typically 25-30%; gross margin needs to be at least that plus net profit target. Below 35% gross is structurally hard to be profitable. Configure a higher floor for premium-category stores.
My margin reads 47% but my P&L says 38%. Why?
Most likely we measure gross margin (revenue minus product cost) while your P&L measures operating margin (gross minus operating expenses). The 9pp gap is your operating cost. Both are correct at their own scope; reconcile by adding operating costs to our gross to land on operating margin.
My B2B margin is 40% but DTC is 54%. Should I stop selling B2B?
No, don’t confuse gross margin with business value. B2B at 40% gross with 0.2M revenue. Compute net margin (gross minus B2B operating costs: sales rep, support, payment terms financing) before making cohort-shutdown decisions.
My alert fires on every promo period. Is that wrong?
Promo periods compress margin temporarily; the 30-day rolling smooths most of this but heavy promo days can drop the headline below 35% briefly. Configure promo-period silence under Settings → Alerts → Silence calendar to suppress alerts on known promo dates.
Should I include shipping in margin?
Generally no. Shipping is a separate equation (collected from customer minus paid to carrier). We exclude both shipping revenue and shipping cost. For total-margin including shipping, configure Settings → Margin scope → Include shipping; the headline will shift by 1-3pp.
Why doesn’t this card include refunds?
Default is gross margin (pre-refund). Refunds are post-fact and have their own cards. Configure net margin under Settings → Refund handling if your finance team prefers net. For most operational decisions gross is the right view; for accounting reconciliation use net.
My multi-storefront has different prices per storefront. How does this card aggregate?
Default aggregates across storefronts. Configure per-storefront filter for storefront-specific margin (UK premium pricing produces different margin than US discount pricing). Per-storefront margin is the right read for multi-brand merchants running different pricing strategies per market.
My cost data is stale; some cost_price values are 18 months old. What’s the impact?
If supplier costs increased and you didn’t update BC, your margin reads HIGHER than reality. Run a cost-data refresh quarterly. Most BC merchants have stale cost_price data; this is the single most common cause of margin overstatement.
Can I see the alert fire history?
Yes, the alert log under Settings → Alerts → History shows when this card crossed the 35% threshold over the past 12 months. Useful for “how often did margin slip into the danger zone?” pattern analysis.