Top finding for the Finance Controller. SKUs whose unit margin has materially eroded in the last quarter.
At a glance
SKUs whose margin percentage has materially eroded vs the prior quarter. The Controller’s “what’s getting worse” worklist.
| What it counts | Per-SKU margin % comparison: this 90D vs prior 90D. Surfaces SKUs where the absolute margin % drop exceeds 20 percentage points (configurable). |
| Tax treatment | Net of tax. |
| Currency | Reporting currency. |
| Subsidiary scope | Respects dashboard filter. |
| Minimum revenue threshold | $5K monthly to filter noise from low-volume SKUs. |
| Time window | 90D vsP |
| Alert trigger | any SKU dropped >20% margin, sentiment margin_erosion |
| Roles | owner, finance |
Calculation
Calculated automatically from your NetSuite 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 wholesale apparel distributor on NetSuite OneWorld. Three subsidiaries: a US parent (USD), a UK distribution sub (GBP), and a Canadian sub (CAD). Annual revenue ~$80M. Comparing 14 Jan 26 to 12 Apr 26 vs 14 Oct 25 to 13 Jan 26. Reporting currency USD.| SKU | Description | Prior margin % | This margin % | Drop (pp) | Period revenue |
|---|---|---|---|---|---|
| BR-A-001 | Brand A Premium Tee Black M | 42% | 38% | -4pp | $186K |
| BR-A-014 | Brand A Premium Polo | 52% | 49% | -3pp | $124K |
| BR-B-022 | Brand B Hoodie Grey | 38% | 12% | -26pp | $410K |
| BR-C-088 | Brand C Tee | 28% | 4% | -24pp | $92K |
| BR-D-014 | Brand D Discounted Sub-style | 22% | -12% | -34pp | $58K |
- Three SKUs trip the alert (drops greater than 20pp), each tells a different story, and the diagnostic split is what makes the card actionable. A single number (“margin is down”) is a complaint; a SKU-level worklist with reason codes is an action. The three alerts here decompose to: BR-D-014 (-34pp) is a pricing decision gone wrong, BR-B-022 (-26pp) is a high-volume cost shock, BR-C-088 (-24pp) is a clearance event. Each requires a different intervention from a different team. The Controller’s job is not to fix margin everywhere, it is to make sure each erosion signal lands with the right owner inside 48 hours; this card builds that worklist automatically.
- BR-D-014 dropped 34pp into negative margin (-12%), meaning the business is paying customers to take this product. Most likely cause: discount pricing pushed below cost, with merchandising authorising a 60% off promotion without checking the landed-cost floor. Less common but real: an upstream cost spike (freight surcharge, supplier price increase) that pushed cost above the discounted price. The Controller pings merchandising the same morning. The remediation is either pull the promotion or accept the loss and write the discounted units down formally; either way the decision happens with eyes open. Annualised at the current revenue rate, BR-D-014 alone is bleeding 0K target, which adds up at the bottom line.
- **BR-B-022 (-26pp from 38% to 12%) is the most financially concerning of the three because it is a high-volume SKU at 410K is $107K of dollar margin loss in a single quarter, which is more than the other two alerts combined. Big-revenue SKU plus modest-percentage drop almost always wins on dollar impact versus small-revenue SKU plus huge-percentage drop. The card surfaces the percentage drop because it triggers anomaly detection cleanly, but the action priority is dollar impact. A Controller working the worklist should sort by
period_revenue × abs(margin_drop_pp)to prioritise dollars. On this account, BR-B-022 traces back to a freight surcharge on a hoodie line manufactured in Vietnam; the cost rose 14% in one batch and merchandising had not pushed price. - BR-C-088 (-24pp) into 4% margin is almost certainly a clearance situation but it should still be confirmed, not assumed. A SKU dropping into single-digit margin is either intentional (clearing seasonal stock at cost-plus-handling) or accidental (somebody promoted a SKU that was already on a thin margin). The card does not know which; the merchandiser does. The conversation that should happen is fast: “BR-C-088 down to 4%, was that the spring promo?” “Yes, that ends 22 Apr 26 and the SKU is being retired.” Done. Without the card, that conversation never happens until the quarter close exposes the mix shift; with the card, it happens the morning the alert fires.
- The healthy-but-eroding watchlist (BR-A-001 at -4pp, BR-A-014 at -3pp) is below the alert threshold but the trend is worth tracking, especially because the same brand (Brand A) shows two consecutive SKUs softening. Two SKUs in the same brand with margin softening at the same time is a brand-level signal: probably a supplier price tick, possibly a freight pattern, or a competitive pricing shift in the channel that forced a price reduction. The card supports a configurable “Watchlist” threshold (typically 3-5pp) that surfaces the early-warning cohort without firing the alert. The Controller scans the watchlist weekly; the alerts demand action within 24-48 hours. On this account, the Brand A erosion turned out to be a 3% supplier cost increase that had been quietly absorbed for two quarters before the merchandiser caught it; surfacing it earlier would have saved roughly $40K of cumulative margin.
Sibling cards merchants should reference together
| Card | Why pair it with Margin Erosion Alerts |
|---|---|
| Margin by SKU | Current snapshot. |
| Gross Margin % | Aggregate roll-up. |
| Landed Cost Avg | Upstream cost driver. |
| Landed Cost Variance | Variance details. |
| Top SKUs Value | Volume cross-check. |
Reconciling against the vendor’s own dashboard
Where to look in NetSuite: NetSuite does not expose this as a native report; the period-over-period margin comparison is one of the gaps that Vortex IQ fills. The closest manual approaches inside NetSuite are:
Reports → Sales → Sales by Item with Margin (run twice for the two windows, manually diff the per-SKU margins in a spreadsheet)
Saved search: Item-level aggregation of (SUM(InvoiceLine.Amount) - SUM(InvoiceLine.EstimatedCost)) / SUM(InvoiceLine.Amount) for two date ranges, with a calculated column for the delta
SuiteAnalytics workbook: a custom workbook with two pinned date filters and a calculated margin-delta column; this is the only native approach that approximates the card, and it usually takes a competent admin 2-3 hours to build
Reports → Inventory → Inventory Profitability (item-level margin trend over time, but no automatic alert on threshold breaches)
A NetSuite Admin can build the saved search in roughly 90 minutes; most do not, because the alert layer (which SKU breached the threshold this week, when did it breach, what is the dollar impact) does not exist natively. NetSuite tells you the numbers; Vortex IQ tells you which numbers moved and by how much. Most Controllers run the saved search quarterly during board prep and miss intra-quarter erosion entirely.
Common reconciliation pitfalls when building this manually:
- Cost basis drift mid-period: NetSuite’s
Item.AverageCostupdates with each receipt, so a SKU’s “this period” margin uses a different cost basis at different points within the period. The card uses period-end average cost; a manual saved search that uses transaction-line cost can produce different per-SKU margins. - Refund and Credit Memo handling: a Credit Memo against an Invoice in the prior period drags margin in the current period if it posts in the current window. The card normalises to invoice-date economics; a naive saved search filtered to current-period transactions distorts.
- Promotional discount line items: if discounts are booked as separate line items (negative-amount lines) rather than netted into the SKU price, the saved search needs to allocate the discount back to the SKU before computing margin. Most accounts get this wrong on the first attempt.
| Reason | Direction | Why |
|---|---|---|
| Threshold setting | Either | Default 20pp; some Controllers set 10pp for tighter monitoring, others 25-30pp for volatile categories. The number of SKUs surfaced is sensitive to this. |
| Minimum revenue threshold | Either | 10K for top-200 SKU focus, others $1K for a wider net. Tunable per workspace. |
| Window definition | Either | Default 90D vs prior 90D smooths promotional spikes. 30D vs prior 30D would generate roughly 4x more alerts because seasonal mix moves margin within shorter windows. 12-month rolling vs prior 12-month is the most stable view but the slowest signal. |
| Cost basis drift | Either | Card uses period-end average cost as the basis for both windows. A saved search using transaction-line cost can produce slightly different margins because cost moves within the period. Differences usually under 1.5pp per SKU. |
| Discount allocation | Either | Card allocates promotional discount lines back to the SKU before computing margin. Manual saved searches that miss this allocation can show inflated margins on promoted SKUs. |
| Inter-co eliminations | Either | Consolidated view applies eliminations; per-subsidiary cuts do not. A SKU sold inter-company at a low transfer price reads as low-margin at the originating sub but normal-margin at the consolidated level. |
| ASC 606 deferral | Card unchanged | Both periods recognise revenue under the same convention, so the ratio is unbiased. Subscription-adjacent SKUs (annual replenishment, extended warranty) read against recognised revenue only. |
| FX cadence on multi-currency SKUs | Small | Both windows translated at respective transaction-date FX. Pure FX impact on margin is usually under 1pp; large swings only matter if the SKU’s revenue and cost are in different currencies and FX moved sharply between the windows. |
| Marketplace-fee inclusion | Either | Some workspaces reclassify Amazon / eBay / Walmart marketplace fees into COGS; others leave them in OpEx. The card respects whatever the GL mapping shows. Reclassifying mid-period creates a one-time margin shift that looks like erosion but is actually accounting policy. |
| Card | Expected relationship | What the comparison reveals |
|---|---|---|
| Commerce-platform per-product margin reports | NetSuite is the source-of-truth | Most commerce platforms (Shopify, BigCommerce, Adobe Commerce) track per-variant cost as a single static field that rarely updates. They cannot generate a period-over-period margin trend because they do not capture cost history. NetSuite does. This is one of the structural reasons NetSuite is the only viable source for margin erosion analysis on a multi-channel commerce business. |
| shopify.gross_margin | Shopify margin > NetSuite margin | Shopify’s variant-level cost is rarely updated as freight surcharges hit. The Shopify number lags reality by 30-90 days; the NetSuite number is current. A SKU showing erosion on this card but stable margin on Shopify is the signal that merchandising needs to update Shopify cost fields. |
| google_ads.cost per-SKU | Indirect, but critical | An eroding-margin SKU still receiving high ad spend is the killer cross-channel finding. NetSuite says “this product is unprofitable”, Google Ads says “we are spending money to acquire customers for this product”. The intersection is “we are paying to lose money”, which the Margin Erosion with Active Ad Spend cross-channel card surfaces explicitly. |
| facebook_ads.spend per-product | Indirect, similar dynamic | Facebook / Meta ad spend on eroding-margin SKUs is the same kill-shot finding for DTC brands. |
| Landed Cost Variance | Causal | If margin is eroding because landed cost is rising, this card surfaces the SKU and Landed Cost Variance surfaces the cause. The two together are the diagnostic pair. |
| stripe.fees + paypal.fees | Indirect, hidden margin tax | Payment processing fees (2.5-3% of GMV) eat real margin even when not classified into COGS. Some Controllers reclassify into COGS for “true product margin”; if you do, expect this card to read 1.5-2.5pp lower across the board. |
| Inventory Carrying Cost | Indirect, hidden margin tax | Carrying cost on slow-moving SKUs eats margin too. A SKU showing 4% margin on this card and sitting in 91-180 aging is closer to break-even economics than the headline suggests. |
Known limitations / merchant FAQs
What is the right threshold? Default 20pp. Tighter (10-15pp) for stable industries (industrial distribution, B2B chemicals, professional services product lines) where margin should not move quarter to quarter. Looser (25-30pp) for volatile categories where seasonal swings are normal (fashion apparel, holiday-driven seasonal goods, perishables on flash promotion). The right setting is the level that produces a manageable number of true positives. If your team is getting 80 alerts a week and ignoring 70 of them, the threshold is too tight; tune up. If the alert never fires and you are still getting margin surprises at quarter close, the threshold is too loose; tune down. Why is the threshold in percentage points, not percent of original margin? Because pp differences are linear and additive. A SKU dropping from 50% to 40% is -10pp; a SKU dropping from 20% to 10% is also -10pp but represents 50% of original margin. Both are alerts. The percentage-of-original framing is misleading because it inflates the apparent severity of low-margin SKU drops; pp grounds the conversation in absolute movement, which is what actually hits the bottom line in dollars when multiplied by revenue. Why is the comparison 90D vs prior 90D? Smooths out promotional spikes and short-term cost shocks. 30D would generate too many false positives because a single big promotional week distorts the period margin even on healthy SKUs. 90D captures roughly a fiscal quarter, which aligns with the cadence of supplier price changes, freight contract renewals, and seasonal pricing shifts. Tunable to 60D or 120D per workspace; 30D is available but generates 3-4x more alerts and rarely changes the action set. Discontinued SKUs, do they appear? Excluded if zero revenue in current period (the comparison would compare to nothing). SKUs with falling-but-non-zero revenue still appear; SKUs in their first 90 days (no prior period) are flagged as “new” and routed to a separate New SKU Margin Watch view rather than the erosion alert list. Multi-currency, FX impact? Both periods translated to reporting currency at respective transaction-date FX. Pure FX shifts are usually under 5pp on margin and only matter when revenue and cost are in different currencies. A US brand selling into the UK in GBP but sourcing from Vietnam in USD has structural FX exposure on per-SKU margin; a weakening GBP shrinks GBP-translated revenue while USD cost stays flat. The card surfaces this as erosion; the action is hedging or repricing, not a SKU-level intervention. Single-subsidiary vs OneWorld behaviour? Identical formula. OneWorld scopes across subsidiaries. The most useful operational pattern on OneWorld is to view margin erosion by subsidiary, because pricing power and cost structure differ by geography. A SKU eroding in the US sub may be stable in the UK sub if pricing is set independently and cost flows differ. The consolidated view can hide single-sub erosion when other subs compensate. B2B vs DTC, do I read margin erosion alerts differently? Yes. DTC margin erosion is usually retail-pricing-driven (promotion, sale event, full-price-to-discounted shift) and the action is merchandising and pricing. B2B margin erosion is usually contract-driven (a renewed contract at worse pricing, a tier rebate kicking in, a customer-specific discount agreed in a sales conversation) and the action is sales and account management. The card does not separate them; the user should overlay the channel cut. On a hybrid business, Margin by Channel splits DTC from B2B from Marketplace, which is the right second-level view after this card identifies the SKUs. OneWorld multi-subsidiary, does inter-co transfer pricing distort the alert? Yes, potentially. A SKU sold inter-company at a transfer price (typically cost-plus a small mark-up) reads as low-margin at the originating sub. If transfer pricing changes mid-period (e.g. a tax-driven repricing at year-end), the card can fire an erosion alert that is purely an accounting policy change, not an operational issue. Confirm with the tax team before chasing it; the safer pattern is to set the alert at consolidated level and run per-sub views as a diagnostic, not as the primary alert. ASC 606 revenue recognition, does it change the per-SKU margin? For physical product businesses, no. Revenue is recognised at fulfilment under both ASC 606 and IFRS 15, which matches the cost recognition timing. For bundled product-plus-service offerings (a kit that includes installation, an annual replenishment subscription that includes coaching), ASC 606 may split the performance obligations and recognise revenue across multiple periods while cost recognises at fulfilment. The card uses recognised revenue only, so the per-SKU margin reflects only the fulfilled portion. This means a subscription-adjacent SKU shows lower headline margin than a non-subscription SKU even at the same economic profitability. Tune the alert threshold per SKU type or carve out the subscription cohort via field map. FX revaluation timing, does it move per-SKU margins? Marginally. Revenue and COGS are recognised at transaction-date FX and do not revalue. The per-SKU margin therefore stays stable across FX revaluation runs. What does move is the consolidated dollar value of the period margin (because remote-sub Income Statement balances translate at period-average); the percentage stays flat. Comparing two periods, both translated at their own period-average FX, is the cleanest read. Discount stacking and promotional pricing, how does the card handle them? The card uses the net-of-discount unit revenue. If a SKU lists at 80 after a 20% promotional discount, and the cost is 80 - 80 = 37.5%, not the list-price-margin of 50%. This means a heavily promoted SKU shows the discounted margin, which is the operationally meaningful number. Some Controllers prefer to see the list-price-margin separately to detect promotional creep; tune the field map to expose both. NetSuite vs Oracle ERP Cloud / SAP S/4HANA on this metric? NetSuite’s strength on this card is the SuiteAnalytics workbook approach, where a custom workbook with two pinned date filters approximates the period-over-period view (though it lacks the alert layer). Oracle ERP Cloud has an Item Profitability Analysis report that is closer in spirit but heavier to set up. SAP S/4HANA exposes the data through the Profitability Analysis (CO-PA) module, which is the most powerful but requires significant configuration and a controlling-module licence. For mid-market commerce (250M+ businesses with deep margin analytics already in CO-PA, Vortex IQ adds the cross-channel ad-spend join that even a fully configured CO-PA cannot deliver natively. Does this card account for marketplace fees, payment processing fees, and ad spend? Not by default. The card uses GL-classified COGS only, which excludes Amazon / eBay marketplace fees (usually OpEx), Stripe / PayPal processing fees (usually OpEx), and ad spend (always OpEx). For a “true contribution margin” view, pair with the Cross-Channel Contribution Margin card, which subtracts these per-SKU. The headline difference is significant: a SKU showing 35% gross margin on this card may be at 22% contribution margin once ad spend, marketplace fees, and processing are loaded in. The boardroom number stays as gross; the operating decision uses contribution. Magento / Adobe Commerce specifics, is per-SKU cost trustworthy? Adobe Commerce supports acost attribute but most installations do not maintain it actively, and freight or duty allocations are rarely loaded. Trust NetSuite, not Adobe, as the per-SKU cost source-of-truth. The cross-channel comparison is useful for a different reason: a stable-margin SKU on this card showing eroding margin on Adobe is the signal that merchandising needs to update Adobe cost fields to match the NetSuite ground truth.