GuideUpdated 2026-07-06

Shopify cost per item, the field that unlocks margin-aware bidding

What Shopify's cost per item field is, why filling it turns revenue ROAS into profit-aware decisions, and how to keep COGS accurate across a large catalogue.

Plain-English summary

Every Shopify variant has a Cost per item field, your cost of goods for that variant. Most stores leave it blank because nothing forces them to fill it. But cost is the missing half of margin, and margin is what separates products that look good in ROAS reports from products that actually make money. Fill it in and product-level profit analysis, including margin-aware tROAS targets, becomes possible; leave it blank and every downstream system is bidding on revenue alone.

The field nobody fills in

Open any variant in Shopify and there it is, in the Pricing block next to price and compare-at price: Cost per item. It's where your cost of goods (COGS) for that variant belongs: what you pay your supplier, per unit, before shipping and overheads.

Shopify never requires it. It doesn't affect your storefront, doesn't appear in your feed, doesn't block anything when it's blank. So on most catalogues it is blank, or filled in for the handful of products someone once analysed in a spreadsheet and never again.

That blankness is expensive, because cost per item is one half of the most decision-relevant number in ecommerce:

margin = (price − cost) / price

Price is always known: it has to be, it's on the storefront. Cost is the missing half. Fill it in and every variant gets a margin; leave it blank and margin is unknowable, no matter how sophisticated anything downstream is.

Revenue ROAS vs profit: why margin changes the answer

Ad platforms report ROAS as revenue over spend. That number treats every pound of revenue as equal: and pounds of revenue are not equal, because products carry different margins.

Two products, same price, same ad performance:

Product A Product B
Price £50 £50
Cost per item £20 £42.50
Margin 60% 15%
ROAS achieved 4.0x 4.0x
Revenue per £1 of spend £4.00 £4.00
Gross profit per £1 of spend £2.40 − £1 = £1.40 £0.60 − £1 = −£0.40

Identical in every report that stops at revenue. One is a strong performer that could take more spend; the other loses 40p on every pound of advertising. A revenue-based ROAS target (one number applied across both) will happily keep funding Product B, because nothing in the data it sees distinguishes the two.

The fix isn't a cleverer target; it's the missing input. With cost per item filled in, the right target becomes computable per product: high-margin products can profitably run at a lower ROAS (they can afford more spend per sale), low-margin products need a higher one to break even. The break-even point itself is simply 1 / margin: a 60% margin product breaks even at 1.67x ROAS, a 15% margin product not until 6.67x. The full revenue-vs-profit argument is in ROAS vs POAS.

Where cost per item fits in the Shopify data model

Cost lives at the variant level, like price, SKU and barcode: see products, variants and options. That's the right level: the red size 8 and the red size 18 of the same dress can genuinely cost different amounts, and bundles or multi-packs certainly do.

A few properties worth knowing:

  • It's a plain number in your store currency. No validation, no history: when your supplier price changes and you update the field, the old value is gone. Shopify's reports use the cost that was recorded at the time of sale, but the field itself only holds "now".
  • It's landed-ish, by your convention. Shopify doesn't define whether cost includes inbound freight or duty. Pick a convention (unit cost, or unit cost plus per-unit freight) and apply it consistently: consistency matters more than which convention you choose, because margin comparisons between products are what drive decisions.
  • It flows through Shopify's own profit reports and through anything reading your catalogue via the API. Fill it once, and every system that reads your store can compute margin. It is not a feed attribute (Google never sees it) which is exactly why it's safe to be honest in it.

Keeping it accurate at scale

Cost data decays. Suppliers reprice, exchange rates move, freight costs shift. A catalogue whose costs were right in January can be 10–15% adrift by autumn without anyone touching a thing. Three habits keep it useful:

  1. Set cost at product creation, always. It's a ten-second job when you're already entering price and supplier details, and a multi-day project when you're backfilling 4,000 variants later. Make it part of the new-product checklist.
  2. Bulk-update on supplier repricing. When a supplier sends a new price list, that's a CSV round-trip against the affected vendor's products: export, update the cost column, re-import. The safe workflow for this is covered in bulk editing product data.
  3. Prefer approximate over absent. If exact landed cost is genuinely unknowable for some lines, a considered estimate (supplier price plus your average freight percentage) still produces margins that rank products correctly. The enemy is the blank, which produces nothing: and the silent zero, which produces a fictional 100% margin. Never enter 0 as a placeholder.

Prioritise coverage where it pays: the products actually carrying your ad spend. Twenty products often account for the majority of Shopping revenue, and costing those twenty accurately delivers most of the value of costing everything.

Deep dive From cost field to tROAS target: the full chain

It's worth walking the complete chain from a number typed into Shopify to a bid decision, because each link explains why the field matters.

Step 1: cost to margin. /tools reads price and cost per item for each variant. A £50 dress with £20 cost is a 60% margin product. This happens per variant, then aggregates to the product level Shopping campaigns bid at.

Step 2: margin to break-even ROAS. Break-even is 1 / margin: the 60% margin dress breaks even at 1.67x; a 15% margin accessory at 6.67x. This one number already reframes performance: a product "hitting" a blanket 4x target may be miles above its break-even or drowning below it.

Step 3: break-even to target. A sensible tROAS target sits above break-even by whatever profit cushion the business wants. Crucially, the right target now differs by product: the high-margin dress can be pushed harder (lower target, more volume, still profitable) while the low-margin accessory needs restraint (higher target, or a hard look at whether it deserves paid traffic at all). This per-product analysis is what tROAS by product surfaces: each product's actual ROAS against its own margin-derived economics, not against one blanket number.

Step 4: analysis to approval. In BidSmart, the resulting recommendations are exactly that: recommendations. Each proposed target change is surfaced with its reasoning (margin, break-even, recent performance) and nothing executes without your explicit sign-off. Margin data sharpens what's proposed; you still decide what runs.

Now the failure mode, because it's instructive. If cost per item is blank, step 1 produces nothing and the whole chain falls back to revenue-only analysis: blanket targets, Product A and Product B from the table above treated identically. If cost is wrong (stale after a supplier increase, or a placeholder zero) the chain runs confidently on fiction: a product whose real margin fell from 40% to 22% keeps being pushed at a target that's now below its true break-even. Wrong cost data is arguably worse than none, because none at least announces itself.

Which is the deep reason for the maintenance habits above: this field isn't a record-keeping nicety, it's a live input to spend decisions. Treat its accuracy accordingly: set it at creation, refresh it on repricing, and never let a zero stand in for "unknown".

How /tools handles this

/tools reads cost per item from Shopify alongside price and uses the resulting margin in its product-level tROAS analysis: identifying which products' ROAS is genuinely profitable against their own break-even, and shaping bid recommendations accordingly. Everything is read-only against your store: cost data is never modified, and it never appears in your Google Shopping feed (it isn't a feed attribute: see the field mapping). Where cost is missing, analysis falls back to revenue-based ROAS and flags the gap, so you can see exactly which products would benefit from being costed. All resulting recommendations go through BidSmart's approval queue: nothing changes a bid or target without your sign-off.

Frequently asked questions

What is the cost per item field in Shopify?

A per-variant field holding your cost of goods, what the item costs you, before shipping and overheads. Shopify uses it for its own profit reporting, and it's the native home for COGS data. It's optional, unvalidated, and blank on most catalogues.

Does cost per item appear in my Google Shopping feed?

No, it's not a Google attribute and shoppers never see it. Its value is analytical. Cost against price gives margin per variant, and margin is what turns revenue-based ROAS into a profit-aware view of which products deserve spend.

Why does margin matter for ROAS targets?

A 4x ROAS on a 60% margin product is very profitable; the same 4x on a 15% margin product loses money after ad spend. Without cost data every product looks the same to a revenue-based target, margin is what tells them apart.

Do I have to fill in cost for every variant?

Aim for coverage on the products that carry your ad spend first. Even approximate costs beat blanks, a cost within 10% still ranks your products correctly by margin, whereas a blank gives downstream analysis nothing at all.

Put this into practice. /tools rebuilds messy product data into Merchant Center-ready feeds. Connect a store and see your Feed Health Score in minutes.
Try /tools →