Glossary
COGS for Shopify stores: cost per item, and how ad profit uses it
Cost of goods sold (COGS) is what the units you sold cost you. In Shopify the per-unit input is each variant’s cost per item, and COGS is that cost times units sold, which is what turns ad revenue into ad profit. For ad profit, enter every per-unit cost you actually pay (supplier price, inbound freight, packaging and any shipping you do not charge for) on each variant, because sizes and colours can cost different amounts.
Last checked · More glossary
What COGS means for an online store
For an online store, COGS for a period is what the units you sold cost you to buy or make. For measuring ad profit, this page also counts the per-unit costs you bear to get each unit to the customer. Accounting treatments differ on outbound shipping, and Shopify’s example leaves it out. Overheads, advertising and payment fees are kept out here so each can be seen on its own line.
As a formula: COGS = Σ (cost per item of each sold variant × units of that variant sold), over the same period as your revenue and ad spend.
Shopify describes its cost-per-item field as “the cost to you of the product or variant”: what a reseller paid the manufacturer, or a maker’s labour and materials. Its example is the price paid to the manufacturer “excluding taxes, shipping, or other costs”. For profit after advertising, this page recommends going further: include the per-unit costs you bear, such as freight, packaging and free delivery, in the same field. That also changes the profit and margin Shopify shows. Apply the same rule to every variant.
What to include per unit, and what to leave out
Include a cost if selling one more unit makes you pay it once more, and you pay it yourself. Leave it out if it is a percentage of the price, a fixed overhead, or counted somewhere else.
- Include: your supplier price per unit, per variant — or labour and materials if you make the product
- Include: inbound freight you pay, divided across the units in the shipment
- Include: packaging per unit
- Include: outbound shipping you do not charge through, as with free delivery
- Leave out: shipping you charge separately that covers itself — from both revenue and cost
- Leave out: VAT and other sales taxes you collect
- Leave out: payment fees, which are usually a percentage of the price plus a fixed amount, so they need their own line
- Leave out: ad spend, which COGS is compared against, and returns, which come off revenue
- Leave out: rent, wages, software and other costs that do not move with units sold
Know what your profit figure still includes
With Opteno’s default settings, net profit is revenue minus cost of goods minus ad spend, with revenue taken as gross sales minus refunds. Payment fees, overheads and any cost you have not entered in cost per item are not deducted, so take them off yourself before treating the figure as take-home profit.
Why per variant, not per product
Set the cost on each variant, because sizes, colours and pack sizes often cost different amounts and the mix you sell can change from week to week. A product-level average is how a losing variant hides inside a winning product.
In Shopify the cost-per-item field sits on the variant, and Shopify suggests its bulk editor or a CSV import to fill a whole catalogue at once.
Fill it early. Shopify’s profit reports include only variants that had a cost recorded when they were sold, so a cost added today does not bring earlier sales into them; Shopify calls the field static data. In Opteno, filling a missing cost completes the figures.
How Opteno sums it, and what happens when a cost is missing
Opteno adds up each sold variant’s cost per item multiplied by units sold, or applies one store-wide percentage of revenue if you set one, which then replaces per-variant costs for the whole store. When per-variant cost tracking is on (the “Enable Cost of Goods columns” switch in store settings), a sold variant with no cost makes cost of goods unavailable, and Opteno names the variant instead of counting the gap as zero. With tracking off and no store-wide percentage, cost of goods is counted as zero.
Step 1: Read the costs from Shopify
Shopify supplies products, variants, orders, refunds and cost-per-item. Google Ads spend is joined to products on the offer identifier Google reports it against.
Step 2: Multiply and add, per sold variant
Cost per item × units sold for each variant sold, summed to the product, over rolling 7, 14, 30 and 60-day windows ending yesterday.
Step 3: Or use one store-wide percentage
If you set one, cost of goods is that percentage of revenue for the whole store, in place of per-variant costs — quick to set up, but blind to which variant sold.
Step 4: Say why a figure is missing
With per-variant cost tracking on, when a sold variant has no cost-per-item, the figure comes back unavailable with the reason and the variant named. Fill it in Shopify, or set a store-wide percentage, and the figures complete themselves. With tracking off and no store-wide percentage, cost of goods is counted as zero.
Step 5: Turn revenue into profit
With Opteno’s default settings, POAS = (revenue − cost of goods) ÷ ad spend, breaking even at 1.00× for every product, and net profit = revenue − cost of goods − ad spend.
A zero cost is not a cost
Opteno’s gross margin is a catalogue figure: the lowest price minus cost among a product’s variants that have a cost. When per-variant cost tracking is on and some variants have a cost while others are blank, gross margin is unavailable rather than calculated from the ones that are filled in. A variant whose cost per item is zero is left out of it, and a product with no variant carrying a positive cost shows gross margin as unavailable. If you do not know a cost yet, leave the field blank rather than typing 0. In cost of goods a 0 is counted as a real €0 and overstates profit; in gross margin a 0 is skipped. With per-variant cost tracking on, a blank is reported as missing instead. More on the rules: /glossary/gross-margin.
COGS inside Google Ads: the cost_of_goods_sold attribute
Google has its own place for COGS: the cost_of_goods_sold attribute in Merchant Center product data, which Google uses to estimate your products’ gross profit. It is a different field from Shopify’s cost per item, so if you maintain both, keep them in step.
Google defines gross profit as revenue minus COGS, and says to use the attribute when reporting purchased product information with the global site tag. It is optional for each product, but required for automated discounts and dynamic promotions.
The format is a number plus an ISO 4217 currency code with a full stop for decimals, for example 10.01 USD. Google advises the same currency as the price reported in the conversion, and says the COGS you share is for reporting and need not be exact. Opteno’s cost of goods comes from each sold variant’s cost-per-item in Shopify, or from a store-wide percentage if you set one. More on the Google side: /guides/cost-of-goods-in-google-ads.
Worked example (illustrative numbers)
In this example, counting the per-unit costs the merchant actually pays moves POAS from 2.21× to 1.83× and net profit from €725 to €500. All numbers are invented for illustration; VAT is left out to keep the arithmetic plain.
Step 1: Build the cost per item
A T-shirt sells at €35.00 in every size. Sizes S–L: supplier €8.00 + inbound freight €0.60 + packaging €0.40 + outbound shipping €3.50 (the store offers free delivery) = €12.50. Size XXL: €10.50 + €0.60 + €0.40 + €3.50 = €15.00.
Step 2: Sum it over what sold
Last 30 days: 40 units of S–L and 10 of XXL, no refunds. Revenue = 50 × €35.00 = €1,750.00. COGS = 40 × €12.50 + 10 × €15.00 = €500.00 + €150.00 = €650.00.
Step 3: Put it against ad spend
Ad spend = €600.00. ROAS = €1,750 ÷ €600 = 2.92×. POAS = (€1,750 − €650) ÷ €600 = 1.83×. Net profit = €1,750 − €650 − €600 = €500.00.
Supplier price only
COGS = 40 × €8.00 + 10 × €10.50 = €425.00. POAS = €1,325 ÷ €600 = 2.21× and net profit €725 — overstated by €225.
One average for the product
(€12.50 + €15.00) ÷ 2 = €13.75, × 50 units = €687.50 — €37.50 too high, because 80% of units sold were the cheaper variant. If XXL were more than half of the units sold, the same average would understate COGS instead.
XXL cost left blank
Counting the blank as zero would give COGS €500.00 and POAS 2.08×. With per-variant cost tracking on, Opteno instead shows the product’s cost of goods as unavailable and names the XXL variant. With tracking off and no store-wide percentage, cost of goods is counted as zero.
Store-wide 35% instead
COGS = 35% × €1,750 = €612.50 — close in this example, but a percentage cannot see which variant sold, so it cannot warn you when the mix moves.
Opteno’s catalogue gross margin for this product would be €20.00: the lower of €35.00 − €12.50 = €22.50 and €35.00 − €15.00 = €20.00.
Questions about COGS
What counts as COGS for an online store?
At its core, the cost of each unit you sold: the supplier price, or labour and materials if you make it. For measuring ad profit, this page also counts the per-unit costs you bear to get it to the customer — inbound freight, packaging, and shipping you do not charge for — though accounting treatments differ on outbound shipping. VAT, overheads, ad spend and payment fees are kept out so each can be seen on its own line.
Where do I enter cost of goods in Shopify?
In the cost-per-item field on each product or variant; Shopify suggests the bulk editor or a CSV import for many products at once. Its profit reports only count sales of variants that had a cost recorded when they were sold.
Should shipping be part of COGS?
Outbound shipping you absorb, such as free delivery, belongs in it. If you charge shipping separately and it covers itself, leave it out of both revenue and cost. Shopify’s own example excludes shipping, so pick one treatment and use it everywhere.
How does COGS change ROAS and POAS?
ROAS is revenue ÷ ad spend and never sees your costs. With Opteno’s default settings, POAS is (revenue − COGS) ÷ ad spend and breaks even at 1.00× for every product. In the worked example, the same sales show a ROAS of 2.92× and a POAS of 1.83×.
What does Opteno do if some variants have no cost per item?
With per-variant cost tracking on (the “Enable Cost of Goods columns” switch in store settings), it reports the affected figure as unavailable, naming the variant, rather than treating the blank as zero. With tracking off and no store-wide percentage, cost of goods is counted as zero. Fill the cost in Shopify, or set a store-wide percentage, which then applies to revenue for the whole store in place of per-variant costs.
Do I also need Google’s cost_of_goods_sold attribute?
Only for Google’s own features: Merchant Center lists it as optional per product but required for automated discounts and dynamic promotions, and uses it to estimate gross profit from purchase data. Opteno’s cost of goods comes from Shopify’s cost-per-item, or from a store-wide percentage if you set one.
See which products are losing you money
Connect Shopify and Google Ads in under five minutes. From $14.99 a month, cancel whenever you want, and no change to your store or your campaigns without your approval.