Read the SKU Economics table
Quick Reference
Inputs
Shopify products, orders and refunds from the last 30 days. Your product costs: landed cost, shipping, pick and pack, payment fees. Per-SKU cost overrides and store-wide default costs. Inventory on hand and lead times, for the stock-status flag, 3PL returns billing, where a returns-handling feed is connected
Outputs
One row per product with ten columns: Product, Profit Class, Price, Margin, GP / Unit, Orders 30d, Units 30d, Gross Profit 30d, Next Move and Flags. A dash rather than a number wherever the figure is undefined or unmeasured. A flag cluster per product covering margin, returns, cost provenance, velocity, stock status and open alerts. Three extra returns columns when the High Returns lens is on
Outcomes
Tell a product that earns well per unit from one that earns most of your money. Know which figures on a row you can trust and which are still waiting on cost data. Sort the catalog by the column that matches the decision you are making. Recognize why a cell is blank instead of assuming the product is broken
The table on the Decide tab of Catalog Profit gives you one row per product and ten columns, and it is built to answer two questions at once: is this product earning? and can I trust that number? This page explains every column, what a dash means, how sorting behaves, and which columns stand down depending on the lens you are in.
What the SKU economics table is
It is the main table on the Decide tab of Catalog Profit. Each row is one product. The columns move left to right from identity to money to action: who the product is, what class MarginOS put it in, what it sells for, what it earns per unit and in total, what to do about it, and what MarginOS wants to warn you about.
Every figure in the row is calculated before the page loads. The table formats and labels; it never does its own arithmetic. That is deliberate — it means the number in a row, the number in that product’s drawer, and the number in your CSV export are the same number from the same place, not three calculations that agree today and drift apart later.
Two things change the shape of the table. Switching the business-line lens away from DTC stands the money columns down. Turning on the High Returns lens adds three returns columns and stands Next Move down. Both are covered below.
Before you start
- You need at least one completed Shopify sync. Products with no sales in the last 30 days still appear; they simply carry no money.
- The money columns — Margin, GP / Unit and Gross Profit 30d — only carry figures on the DTC business-line lens. On any other lens they read — with the tooltip “Costs not modeled for this business line yet.”
- Every figure on this table is a 30-day window unless the column name says otherwise.
- Your cost setup drives how much of this table is trustworthy. If a lot of rows carry a missing-cost flag, fix that first in your cost structure or on the Fix data tab.
Read a product row in five steps
- Start with the Product cell. It carries the product name, its SKU and its category. If the product is not Active in Shopify, its status appears here too — DRAFT, ARCHIVED, or Removed from Shopify for a product that was deleted at the source. A row with one of those labels needs a different decision from a live one.
- Check Margin before you read any dollar figure. Margin is the percentage of revenue this product kept after its costs over the last 30 days. A red figure marks a High Velocity, Low Yield product: it sells at or above your hero velocity level, and its margin is below the low-yield line. A thin margin on a slow seller stays in the normal colour. A dash means the product had no revenue in the window, so the percentage is undefined — that is not the same as zero.
- Read GP / Unit and Gross Profit 30d together. GP / Unit is what one unit earns you; Gross Profit 30d is what the product earned in total. A healthy per-unit figure on a product nobody buys is not a win, and a thin per-unit figure on a product that moves thousands of units usually is.
- Sanity-check the volume columns. Orders 30d counts the distinct orders that contained this product. Units 30d counts net units — units sold minus units returned. A big gap between a high Units figure and a low Orders figure means people buy this one in multiples.
- Finish on Next Move and Flags. Next Move is the single action MarginOS recommends for this product. Flags is a cluster of small icons; hover any one for its meaning. The stock-status icon is always present, and the rest appear only when they apply to this product.
Clicking anywhere on a row opens that product’s full cost breakdown.
What each column means
| Column | What it shows | Worth knowing |
|---|---|---|
| Product | Name, SKU and category. Plus the Shopify status when it is not Active, and a note when the product had no sales on your current lens. | The lens note reads like “No DTC sales in this window — sells via Wholesale. Switch the lens to see its economics.” The product is not broken; you are looking at it through the wrong lens. |
| Profit Class | Which of the five profit classes this product is in. | The classes and how MarginOS assigns them are covered in Read Catalog Profit. |
| Price | The product’s current list price. | When no list price is recorded, the cell shows the realised 30-day average selling price in lighter grey instead, and says so on hover. |
| Margin (sortable) | Gross margin percentage over the last 30 days. | Red only for a hero-velocity seller whose margin is below the low-yield line; a slow seller with a thin margin is not painted red. A dash means no revenue in the window, so there is nothing to take a percentage of. |
| GP / Unit (sortable) | Gross profit per net unit sold over the last 30 days. | If your 3PL bills you for returns handling and that feed is connected, a second line appears: After returns: $X. That is the same per-unit figure minus the modelled cost of handling this product’s returns. Its badge says how sure MarginOS is of that returns cost: Measured when your 3PL bill carries enough returns to read the rate straight off it, Evidence-backed when only a few returns are on record, so the rate rests on thinner evidence. Both lines read N/A when the product kept no units in the window. |
| Orders 30d (sortable) | How many distinct orders contained this product in the last 30 days. | A count of orders, not a share of them. A dash means the count has not been measured for this product yet — and unmeasured rows always sort to the bottom, never the top. |
| Units 30d (sortable) | Net units sold: units shipped minus units returned. | A dash means MarginOS has no sales record for this product yet, which is not the same as selling none; a measured zero still reads 0. Carries a sub-line in two situations — gross units when the High Returns lens is on, and net revenue when you are on a lens where the money columns stand down. |
| Gross Profit 30d (sortable) | Total gross profit this product produced over the window. | Red when negative. This is the column to sort by when you want to know where the money actually is, rather than where the best percentage is. |
| Next Move | The one action MarginOS recommends for this product. | Present only while the High Returns lens is off — with that lens on, the move is already implied by the lens itself. |
| Flags | Icons for negative margin, high returns, too close to cost, missing cost data, hero velocity, a manual cost override, a store-wide default cost, stock status, and a count of open alerts. | Hover any icon for its meaning. The alert count is the number of cards you will actually see if you open this product, not a raw total. |
Turning on the High Returns lens adds three more columns — returned units, return rate and the profit those returns cost you — and takes Next Move away. Sorting by one of those columns clears when you turn the lens off, because an invisible sort key cannot be explained.
How MarginOS calculates what you see here
Margin is gross profit divided by net revenue for the window, then rounded. When there is no revenue base, the answer is not zero — it is undefined, so the cell shows a dash. A measured zero still renders as 0%. The same principle runs through the whole product: see why MarginOS shows N/A instead of a made-up number.
GP / Unit is the same gross profit divided by net units sold. Gross Profit 30d is that gross profit total. What goes into gross profit — and what deliberately does not — is explained in how MarginOS calculates Gross Profit, and the margin percentage itself in how MarginOS calculates Gross Margin %.
Orders 30d is an honest count. MarginOS only reports it when every sales channel contributing to that product has a measured count; if any one of them is still missing, the cell shows a dash rather than a partial sum presented as a complete one. A wrong count that looks complete is worse than an obvious gap.
The money columns are gated by business line. On DTC, MarginOS models both the revenue and the full cost stack, so a margin figure is defensible. On wholesale, marketplace and retail lines there are off-platform fees we do not model, so rather than publish a flattering number we show a dash and say why. Volume and revenue still scope to your lens; only the margin claims stand down. Data Trust levels covers how MarginOS grades reliability more generally.
The table picks its own opening sort. By default it opens ranked by Orders 30d, highest first — the honest count of how often a product was actually bought. If your store has 3PL returns billing connected, it opens ranked by profit per unit after returns instead, because at that point we can measure what returns really cost you. Clicking any sortable header takes over from there, and clicking the same header again reverses the direction.
Example
You open Catalog Profit on the DTC lens and sort by Gross Profit 30d. The top row is a bundle: Price $84.00, Margin 44%, GP / Unit $36.96, Orders 30d 310, Units 30d 340, Gross Profit 30d $12,566. Its Next Move is blank of urgency and the only flag is a green stock icon. Nothing to do.
Three rows down is a product with Margin in red at 9%, GP / Unit $1.12, Orders 30d 480, Units 30d 610 and Gross Profit 30d $683. It is one of your busiest products and it is earning almost nothing. Its Flags cluster carries a wrench, meaning someone set a manual cost override on it, and a downward arrow for Too Close to Cost. Its Next Move reads Confirm fees.
Further down, a row shows Price $19.50, Margin —, Orders 30d — and Units 30d 0. Nothing is broken: it made no sales in the last 30 days, so there is no margin to report. The row below it shows Units 30d — instead of 0, because MarginOS has no sales record for that product yet and will not claim a zero it never measured. You leave both alone and go back to the 9% row.
Common questions
Why does a row show a dash instead of a number?
Because the honest answer is “we do not know”, and MarginOS never fills that in with a zero. There are four common reasons. You are on a business-line lens where the cost stack is not modelled, and hovering the dash says so. The product had no revenue in the window, so a margin percentage does not exist. An order count has not been measured for every channel that product sells through yet. Or, in Units 30d, MarginOS has no sales record for that product yet; a measured zero still reads 0. GP / Unit and its After returns line say N/A instead of a dash when the product kept no units in the window — it sold none, or every unit came back — so there is nothing to divide its profit across.
Why is the Price in lighter grey on some rows?
That product has no list price recorded, so MarginOS shows the price it actually achieved — total revenue divided by units sold over the last 30 days. Hover it and the cell tells you exactly that. It is a real figure, just a different one, which is why it is styled differently.
What is the difference between Orders 30d and Units 30d?
Orders counts baskets; Units counts items. One order containing four of the same product is one order and four units. Units is also net of returns, so a product that sold 100 and had 20 come back reads 80. Comparing the two tells you whether people buy this product singly or in multiples.
Why did the table open sorted by a column I did not pick?
Because MarginOS chooses the opening sort based on what it can measure about your store. Normally that is Orders 30d, highest first. If your 3PL bills you for returns handling and the feed is connected, it opens on profit per unit after returns instead. Click any sortable header to take over.
A product shows a healthy Margin but a tiny Gross Profit 30d. Which one matters?
Both, in that order. Margin tells you whether the product is worth selling; Gross Profit 30d tells you whether it is worth your attention this month. A 60% margin on nine units is a good product and a rounding error. Sort by Gross Profit 30d when you are deciding where to spend your week, and by Margin when you are deciding what to fix or reprice.
Where did the Next Move column go?
You have the High Returns lens on. That lens swaps in three returns columns and stands Next Move down, because the recommended move is the lens itself: this product leaks cash through returns, so fix it or retire it. Turn the lens off and Next Move comes back.
Related
- Read Catalog Profit — the screen this table lives on, its summary tiles and the five profit classes.
- How MarginOS calculates Gross Profit (CM1) — what is inside the profit columns.
- How MarginOS calculates Gross Margin % — the Margin column’s methodology.
- Why MarginOS shows “N/A” instead of a made-up number — the rule behind every dash on this table.
- How MarginOS flags Too Close to Cost — one of the flags you will meet in the Flags column.
- Set your store-wide COGS, shipping and pick-pack fallbacks — where to fix the missing costs this table surfaces.
- Data Trust levels — how MarginOS grades the reliability of a margin.
About the author
Founder of MarginOS, a Profit & Inventory OS for Shopify DTC brands who live and die by margin. Previously 11 years at Google across Ads and Global Business Operations, building large-scale systems. Now focused on giving DTC operators true profit by product, channel, and customer after COGS, 3PL, shipping, returns, and fees, and on showing exactly how much to trust every number behind those decisions.
Read Aron's story