Skip to main content
Card class: HeroCategory: Ecommerce Platform
Revenue minus COGS over revenue. The single best margin-health number for the executive view.

At a glance

Revenue minus COGS over revenue, computed from Sage Intacct’s General Ledger across the period. The single best margin-health number for the executive view, sliceable by every Intacct dimension (Department, Location, Project, Item, Class, Customer, Vendor) so the same percentage can be cut by team, business unit, or project without re-querying. The boardroom number; the operating decision lives in dimensional drill-downs.
What it counts(SUM(GLDETAIL.AMOUNT for revenue accounts) - SUM(GLDETAIL.AMOUNT for COGS accounts)) / SUM(GLDETAIL.AMOUNT for revenue accounts), both sides posted (STATE = 'Posted'), filtered to the configured period, expressed as a percentage. Sage Intacct’s standard Chart of Accounts uses 4000-4999 for revenue and 5000-5999 for COGS; the field map respects whatever ranges the merchant’s Implementation Partner configured.
Tax treatmentNet of tax on both sides. Sage Intacct books tax to a separate liability account (typically 2200 Sales Tax Payable or country-specific equivalents), so revenue and COGS on this card are exclusive of US sales tax, VAT, GST, and any non-recoverable consumption tax.
ShippingIncluded on both sides if the Chart maps shipping income to a revenue account (typically 4900 Shipping Revenue) and freight-out costs to a COGS account. If shipping is offset to OpEx accounts, neither side counts.
DiscountsAlready deducted at line level. Intacct’s Order Entry applies trade and term discounts before the revenue line posts; the card uses post-discount revenue.
Refunds and Credit MemosDeducted on the revenue side (Credit Memos post a debit against revenue). COGS adjusts via the Inventory Adjustment that accompanies the return, so the percentage stays comparable.
Cancelled / voided ordersExcluded by definition. Voided Invoices reverse their journal lines; the GL net is zero.
CurrencyMulti-Entity Console: each entity’s revenue and COGS in base currency, summed at reporting FX per the Currency Configuration. The percentage is dimensionally consistent so FX moves the dollar value but rarely the ratio (unless revenue and COGS are in different currencies on the same SKU).
Entity scopeCard respects the dashboard entity filter. Default rolls across every entity the API user can see.
Dimensional cutHeadline percentage; click any chip to cut: Department margin, Location margin, Project margin, Class margin (brand or business unit), Customer margin (per-account profitability), Vendor margin (per-supplier sourcing efficiency). The Project dimension is uniquely powerful for services-heavy and project-based commerce.
Revenue recognition (ASC 606)If the account uses Intacct Contracts and Revenue Management, deferred revenue is excluded from this number; only recognised revenue counts. Without Contracts, revenue is booked at invoice posting.
Time window30D vsP (default 30D vs prior 30D)
Alert triggerdrop >2pp vsP, sentiment margin. Tunable per workspace.
Rolesowner, finance

Calculation

Calculated automatically from your Sage 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 digital agency on Sage Intacct (single entity, USD), running a project-based services business with annual revenue ~$24M. Period is 30D ending 12 Apr 26 vs the prior 30D ending 13 Mar 26. The Project dimension is populated on every revenue and COGS line; Department splits Strategy / Creative / Engineering / Media practices.
PeriodRevenue (USD)COGS (USD)Gross Margin %
Prior 30D (14 Feb 26 to 13 Mar 26)$1,940,000$1,028,20047.0%
This 30D (14 Mar 26 to 12 Apr 26)$2,180,000$1,283,82041.1%
Delta+$240K+$255K-5.9pp
Gross margin compressed 5.9 percentage points period over period, well above the 2pp alert threshold. The Nerve Centre fires sentiment margin and the Controller drills the dimensional cut. Five things to notice:
  1. The Project dimension cut surfaces the cause in one click. Pivot the same percentage by Project: 41.1% consolidated decomposes into the Project-level margins. Three projects took the full hit: PRJ-VEGA-2026 (a fixed-fee implementation with 38% margin this period vs 52% last period), PRJ-LUNA-2026 (35% vs 49%), and PRJ-NOVA-2026 (29% vs 44%). The other 47 active projects held margin within 1pp of last period. Three projects are dragging the consolidated margin by 5.9pp on their own. This is exactly the conversation Sage Intacct’s dimensional model is designed to support; on NetSuite the same drill is possible via Class plus saved searches but takes 2 to 3x longer to surface. The Implementation Partner’s monthly board pack typically includes the Project margin column, so this card mirrors the conversation the merchant already has.
  2. Drill into PRJ-VEGA-2026 (the worst Project) and the cause is a labour overrun. The Project’s COGS line shows 190KofservicestimebilledagainsttheProjectthisperiodvs190K of services-time billed against the Project this period vs 112K plan; the engineers logged 720 hours against a 480-hour scope. Pair this with Margin by SKU cut by Item dimension (Service items have margins too) and the picture sharpens further: senior-engineer time billed at 300/hragainstafixedfeethatassumedmidlevel300/hr against a fixed-fee that assumed mid-level 180/hr is the proximate cause. The remediation is a Change Order to the Customer for scope expansion, or an internal write-down on the Project. The card fires the alert; the Project margin pivot tells the Account Director where to look; the conversation with the Customer happens within 24 hours.
  3. The consolidated 41.1% number on its own is misleading because the median-Project margin is still 49%. Three problem Projects are bleeding $200K+ of dollar margin in a 30-day window; the 47 healthy Projects are operating at plan. Without the dimensional cut, the executive read is “margin compressed across the agency”, which would lead to a wrong intervention (cost cutting across all teams, hiring freezes, scope refusal). With the dimensional cut, the read is “three Projects need urgent attention; the other 47 are fine”. The intervention is targeted, not blanket. This is why the Project dimension on Intacct is uniquely valuable for services-heavy commerce; NetSuite’s Class dimension is conceptually similar but Intacct’s Project is purpose-built for project-based businesses with native time-tracking and Project-level P&L roll-up.
  4. The Department dimension cut tells a complementary story. Pivot 41.1% by Department: Strategy 52%, Creative 48%, Engineering 38%, Media 55%. Engineering is dragging because the three problem Projects all sit there. The Engineering Practice Lead now owns the conversation with three Account Directors. The card has surfaced the issue, the Project pivot has surfaced the cause, the Department pivot has surfaced the owner. Three clicks to the action; on a system without Intacct’s dimensional model, this is a 3-hour spreadsheet pull.
  5. The Class dimension carries the secondary signal: client tier. Pivot 41.1% by Class (which the Implementation Partner mapped to Strategic / Growth / SMB tiers): Strategic clients 35% margin (down from 51%), Growth 44% (down from 47%), SMB 50% (flat). The Strategic-tier compression is structural and worse than the consolidated number suggests, because Strategic accounts represent 60% of revenue. The 16pp drop on Strategic clients is the real boardroom conversation. If the Account Directors keep accepting scope expansions on Strategic accounts without Change Orders to protect margin, the agency will exit the year at sub-40% gross margin on its biggest revenue cohort. The card fires the alert; the dimensional cuts make the cause unambiguous.

Sibling cards merchants should reference together

CardWhy pair it with Gross Margin Percentage
Margin Erosion AlertsThe SKU-level worklist when this card moves. Surfaces which SKUs (or Projects) caused the compression.
Margin by SKUPer-SKU snapshot, ranked. The cohort underneath the headline.
Total COGSThe denominator’s denominator. Why is COGS rising.
Revenue Booked into GLThe revenue side of the ratio.
Average Landed Cost per UnitUpstream cost driver. Rising landed cost means falling margin.
Landed Cost Variance vs StandardCost-variance details against Standard cost.
Top SKUs by Inventory ValueVolume cross-check; concentration of where margin is being earned.
Dead Stock with Active Ad SpendCross-channel kill-shot: ad spend on margin-eroded SKUs is doubly wasteful.

Reconciling against the vendor’s own dashboard

Where to look in Sage Intacct: The native Sage Intacct views to run side by side with this card:
Reports → Financial → Income Statement (period view, dimensional). The Gross Profit subtotal divided by Total Revenue is this card. Reports → Financial → Income Statement Comparative (period vs prior period; the comparison this card automates) Interactive Custom Report (ICR) built on the General Ledger source filtered to revenue accounts (4000-4999) and COGS accounts (5000-5999), with calculated columns for the ratio, pivoted by Department / Project / Class Reports → Order Entry → Sales by Item with Margin (item-level margin, the underlying drill) Standard Dashboard “Gross Margin Trend” widget (typically configured by the Implementation Partner)
The Income Statement summary line “Gross Profit %” should match this card to within rounding when the same period and entity scope are selected. For an audit-grade match, run a Comparative Income Statement at intacct.com filtered to the two windows; the Gross Profit row’s percentage column is the headline. Most Implementation Partners build a saved ICR called something like “Gross Margin by Project, Comparative” that mirrors this card’s logic; once built, it is the monthly close report. Common reconciliation pitfalls when comparing against Intacct’s own reports:
  • Sales by Item with Margin sums Order-line margin, not GL-booked margin. The two views differ when COGS is recognised on a different schedule from revenue (any business with deferred recognition, lot-allocated costs, or period-end COGS adjustments).
  • Trial Balance with Dimensions is account-level and includes non-revenue / non-COGS accounts if the filter is not tight; this card is revenue-account-and-COGS-account only.
  • AR Aging is AR-based, not P&L. Ignore for this comparison.
Why our number may legitimately differ from a Sage Intacct Income Statement:
ReasonDirectionWhy
Account range mappingEitherIf the Chart maps revenue or COGS to non-standard accounts (e.g. shipping booked to Other Income rather than Shipping Revenue), the field map must capture them.
Marketplace and processing feesEitherSome workspaces reclassify Amazon / eBay marketplace fees and Stripe / PayPal processing 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.
Inter-co eliminationsEitherMulti-Entity Console: consolidated view applies eliminations on inter-co revenue and inter-co cost. Per-entity views do not eliminate. A SKU sold inter-co at a low transfer price reads as low-margin at the originating entity but normal-margin at the consolidated level.
Revenue recognition (Contracts module)Card lowerDeferred revenue is excluded from this card. Pre-Contracts accounts: full invoice posts to revenue at billing, no deferral. SaaS accounts using Intacct Contracts will see the percentage track recognised revenue, not booked.
FX cadence per entitySmallMulti-Entity Console: each entity translates at its configured cadence (transaction-date, period-end, period-average). A one-off ICR run at a different cadence will not match.
Period boundarySmallCard uses transaction posting date; some Income Statement views use accounting period close. Differences usually under 1% unless the close is mid-period.
ASC 606 split performance obligationsEitherBundled product-plus-service offerings split revenue across periods while cost recognises at fulfilment. Card uses recognised revenue only; per-SKU margin reflects only the fulfilled portion.
Cross-connector reconciliation, the killer cross-channel finding:
CardExpected relationshipWhat the comparison reveals
Commerce-platform per-product margin reportsSage Intacct is the source of truthMost 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. Intacct does. This is one of the structural reasons Intacct is the only viable source for margin analysis on a multi-channel commerce business.
shopify.gross_marginShopify margin > Intacct marginShopify’s variant-level cost is rarely updated as freight surcharges hit. The Shopify number lags reality by 30-90 days; the Intacct 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-SKUIndirect, but criticalAn eroding-margin SKU still receiving high ad spend is the kill-shot. Intacct says “this product is unprofitable”, Google Ads says “we are spending money to acquire customers for it”. The intersection is “we are paying to lose money”, which the Margin Erosion Alerts card surfaces explicitly.
stripe.fees + paypal.feesIndirect, hidden margin taxPayment 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 CostIndirect, hidden margin taxCarrying 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.
Margin Erosion AlertsDrill-downWhen this headline percentage drops, that card surfaces the SKU-level (or Project-level) cohort responsible.
The cross-channel killer view is that an eroding-margin SKU still receiving paid traffic is pure waste. Intacct alone cannot see ad spend; ad platforms alone cannot see landed-cost-loaded margin. Vortex IQ joins them. On a typical mid-market commerce account this finding usually exceeds the cost of the subscription within the first quarter, which is why this card plus the Margin Erosion Alerts cross-channel card is the AI OS positioning anchor. Sage Intacct’s dimensional model adds the Project, Customer, and Class cuts that NetSuite’s Class / Department / Location segmentation supports through saved searches but Intacct supports natively.

Known limitations / merchant FAQs

What is a healthy gross margin? Industry-dependent: SaaS subscription 70-85%, services and digital agency 40-55%, B2B distribution 18-32%, wholesale apparel 28-42%, DTC apparel 50-65%, electronics 22-35%, food and beverage 30-45%, industrial distribution 18-28%, beauty and cosmetics 55-75%. Compare to your own 12-month rolling baseline first; absolute benchmarks mislead across categories. A 2pp move in either direction is the actionable signal regardless of starting level. Why the 2pp alert threshold? Gross margin moves slowly under normal operations. A 2pp drop period over period almost always signals a real change: a supplier price tick, a freight surcharge, a promotional creep, a customer-mix shift toward lower-margin accounts, or a Project labour overrun. Tighter thresholds (1pp) generate noise on small-revenue accounts; looser thresholds (5pp) miss real erosion until it has already damaged the year. 2pp is the level that produces a manageable number of true positives across mid-market merchants. Sage Intacct vs NetSuite on this card? Arithmetic identical. Where Intacct shines is the Project dimension, which is purpose-built for project-based businesses (digital agencies, consultancies, B2B implementations) and tags every revenue and COGS line at posting. NetSuite’s Project module exists but the dimensional carry-through requires saved-search engineering. For services-led commerce running on Intacct, the Project margin pivot is one click away; on NetSuite it is typically a 30-minute SuiteAnalytics workbook build. For pure product margin reporting both systems produce the same percentage; the difference is the speed of dimensional drill-down. Sage Intacct vs Sage 50 / 100 / 200 / X3? Different products. This connector targets Sage Intacct only. Sage 50 and 100 are SMB desktop products with simpler P&L structures and no first-class dimensions. Sage 200 is a UK / EU SMB product. Sage X3 is a different mid-market ERP. The card definition is identical conceptually but the API and dimensional model differ. Does this card account for marketplace fees, payment processing fees, and ad spend? Not by default. The card uses GL-classified revenue and COGS only, which excludes Amazon / eBay marketplace fees (usually OpEx in Intacct’s standard Chart), Stripe / PayPal processing fees (usually OpEx), and ad spend (always OpEx). For a “true contribution margin” view, pair with a Cross-Channel Contribution Margin card that 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. Multi-Entity Console: per-entity vs consolidated? Both are useful. The consolidated view is the boardroom and audit number; per-entity views are operational because pricing power and cost structure differ by geography. A SKU eroding in the West Coast entity may be stable in the East Coast entity if pricing is set independently and cost flows differ. Consolidated can hide single-entity erosion when other entities compensate. Project margin, the dimensional cut every Intacct merchant uses? The Project dimension on Intacct is the killer feature for services-heavy and project-based commerce. Every revenue and COGS line tags a Project at posting; the same headline percentage decomposes into per-Project margins in one click. For digital agencies running fixed-fee Projects, the Project margin pivot detects scope creep within days, not at quarterly Project close. For B2B implementations and consultancies, it tracks Project profitability against budget in real time. NetSuite has a Project module and Class segmentation but the dimensional carry-through is heavier; Intacct’s is purpose-built for this use case. Does the card respect ASC 606 deferred revenue? Yes if the merchant uses Intacct Contracts and Revenue Management. The numerator counts only recognised revenue, so deferred subscription revenue, multi-period contracts, and bundled product-plus-service offerings split correctly. SaaS merchants without Contracts will see the percentage track booked revenue (full invoice at billing); the headline is then more volatile because front-loaded annual contracts spike the percentage in billing months. FX revaluation timing, does it move per-entity margins? Marginally. Revenue and COGS recognise at transaction-date FX and do not revalue. The percentage stays stable across FX revaluation runs. What moves is the consolidated dollar value of period margin (because remote-entity 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 net-of-discount unit revenue. If a SKU lists at 100,shipsat100, ships at 80 after a 20% promotional discount, and costs 50,themarginiscomputedas(50, the margin is computed as (80 - 50)/50) / 80 = 37.5%, not the list-price-margin of 50%. Heavily promoted SKUs show the discounted margin, which is the operationally meaningful number. Some Controllers prefer to see list-price margin separately to detect promotional creep; tune the field map. REST vs XML API, does freshness matter? No effect on the percentage. Sage Intacct exposes GL Detail through both APIs. Vortex IQ uses XML for the bulk GL extract and REST for incremental refresh on individual transaction events. Freshness is typically 5 to 15 minutes from the most recent posting. For real-time intra-day, intacct.com is always live. My Implementation Partner says margin should be tracked monthly, not weekly. What do you recommend? Most Implementation Partners review monthly during book close. Vortex IQ runs this card every 15 minutes so the Controller catches structural drift inside the period, not at month-end when it is 30 days late. Both views are useful; the daily Nerve Centre check spots problems early, the monthly Partner review confirms the close. A 5.9pp compression like the worked example would show up on the Partner’s monthly Income Statement Comparative; with the card it surfaces within hours of the GL postings that caused it. Implementation Partner role on this metric? The Partner usually owns the Chart of Accounts mapping for revenue and COGS, the Project dimension structure, the Class taxonomy, and the saved Comparative Income Statement reports. If this card returns a different percentage from the Partner’s monthly board pack, the cause is almost always: (1) a Chart account that the Partner classifies as revenue but the field map classifies as Other Income (or vice versa), (2) a marketplace-fee reclassification policy difference, (3) an ASC 606 Contracts module configuration issue. Vortex IQ’s field map is the place to align.

Tracked live in Vortex IQ Nerve Centre

Gross Margin Percentage is one of hundreds of KPI pulses Vortex IQ tracks across Sage and 70+ other ecommerce connectors. Nerve Centre runs the detection layer; Vortex Mind investigates the cause when something moves; Ask Viq lets you interrogate any number in plain English. Start for free or book a demo to see this metric running on your own data.