Ask ten small merchants what a SKU is and most will describe a barcode. Ask them to show you one and about half will open a spreadsheet where the item column reads Blue hoodie L (new supplier). That gap — between the identifier a business thinks it has and the one its systems can actually join on — is where a surprising share of fulfilment problems start.
This is not an argument that you need warehouse software. It is an argument that you need a stable, unique code per sellable thing, before any software can help you at all.
A SKU is your code, not the world's
A SKU — stock keeping unit — is a code you invent to identify one sellable variant of one product in your own business. Shopify calls SKUs “codes that you can use internally to track your inventory and report on your sales”. S1 Amazon puts the internal part more bluntly: SKUs are “mostly created by companies to monitor their own inventory, so the same product at a different company can have different SKUs.” S14
A GTIN is the opposite kind of number. GS1 describes it as “a globally unique number used to identify your specific product or service” and, memorably, as “the number found under a product barcode’s black and white lines”. S15 It is assigned by the brand owner under a licensed GS1 company prefix, which is what makes it unique across every retailer on earth rather than just across your shop. S16 EAN-13 and UPC-A are simply the 13- and 12-digit forms of a GTIN.
| Identifier | Who assigns it | Unique where | What it is for |
|---|---|---|---|
| SKU | You | Inside your business | Joining your own systems: stock, picking, purchasing, reporting |
| GTIN / EAN / UPC | The brand owner, via GS1 | Globally, permanently | Letting anyone in the supply chain identify the same physical product |
| MPN | The manufacturer | Within one manufacturer's range | Identifying a part when no GTIN exists; needs the brand to disambiguate |
| ASIN | Amazon | Within Amazon's catalogue | Amazon's own product page, shared by every seller of that item |
| Barcode | Nobody — it is a symbol | n/a | Carrying one of the numbers above so a scanner can read it |
| Variant ID / handle | Your platform | Within that one store | Platform internals; not portable to anything else |
Sources: GS1 on GTINs S15,S16; Shopify and Amazon on SKUs S1,S14; Google on MPN S9; Amazon on ASINs S14.
The confusion is expensive in one specific direction. Google Merchant Center tells you plainly not to put your SKU in the GTIN, MPN or brand attributes: “Don’t include internal stock keeping unit (SKU) or other values specific to your store in these attributes.” S9 Walmart Marketplace goes further and refuses them: “Model numbers or SKU numbers aren’t considered valid product IDs.” S12 Meanwhile the same feed wants your SKU — as the row key. Google’s guidance on the id attribute is “Use SKUs as IDs where possible.” S8 Two fields, two different numbers, and the failure mode when you swap them is a disapproved feed rather than an error message.
Where SKUs stop being optional
Nothing stops you launching a catalogue with the SKU field blank. That is precisely why so many catalogues have one. The requirement arrives later, from a system you do not control, usually on the day you were trying to do something else.
- Handing fulfilment to someone else. Shopify's API documents the variant SKU as “a case-sensitive identifier for the product variant in the shop. Required in order to connect to a fulfillment service.” S2 The CSV documentation repeats it: the SKU “can’t be blank if you use a custom fulfillment service.” S3 The moment a 3PL, a warehouse partner or an external packing app enters the picture, the blank field becomes a blocker.
- Uniqueness, enforced. Shopify states that “SKUs within your Shopify admin must be unique and no two product variants should include the same SKU in their details.” S1 WooCommerce says “each SKU must be unique across your store” S5 and enforces it in code — a collision raises
product_invalid_skuwith the message “Invalid or duplicated SKU.” S6 Adobe Commerce makes the field required, caps it at 64 characters and warns that “a SKU longer than 64 characters causes import to fail.” S7 - Product feeds. Google wants a unique
idper product, 1–50 characters, and recommends the SKU for it. S8 Meta's catalogue spec says “a unique content ID for the item. Use the item’s SKU if possible” and “each content ID must appear only once in your catalog.” S11 - Variant grouping. Google's
item_group_id— the attribute that ties a size run together into one product — is explicitly the parent-SKU slot: an “ID for a group of products that come in different versions (variants)”. S10 If your SKUs have no parent/child structure, you have nothing sensible to put there. - Marketplaces. Migrating an eBay listing to the modern Inventory API requires that “the item must also have a SKU value (
Item.SKUorVariation.SKU) associated with it.” S13 Having a SKU is the precondition, not an optimisation.
What breaks on the packing bench
The operational case for SKUs is simpler than the platform one. A picker holding a garment cannot verify it against an order line that says Blue hoodie L. They can verify it against a code, in about a second, with a scanner. Everything downstream — scan-to-confirm packing, receiving against a purchase order, cycle counting, multi-location stock, batch and expiry tracking — is the same trick repeated: match a physical thing to a record, by code.
It is worth being honest about the evidence here, because a lot of it is quoted badly. The most-cited academic finding on inventory record accuracy is DeHoratius and Raman's study of roughly 370,000 records across 37 stores of a single US retailer, published in Management Science in 2008: “we find 65% to be inaccurate.” S19 That is a striking number, but it is one retailer, it is bricks-and-mortar, it predates modern warehouse systems, and it counts a discrepancy of one unit as an error. It is not a statistic about your Shopify store. What it does establish is the structural point: without a per-item key you cannot even measure whether your stock figure is right, let alone fix it.
On the cost of getting it wrong, the most traceable figure in the trade press comes from research conducted in late 2012 for Intermec, surveying 250 supply chain and warehouse managers in the US, UK, France and Germany: “a single mispick costs a warehouse approximately $22”, and mispicks in one distribution centre come to “$389,000 annually, on average.” S20 Both numbers are vendor-commissioned, self-reported, fourteen years old and sized for a distribution centre rather than a three-person warehouse in Vilnius. Treat them as an order of magnitude, not a budget line.
The customer-side number is harsher and more recent. In a 2022 US consumer survey commissioned by warehouse-software firm Voxware, 81% of respondents said that if a retailer sends an incorrect order two or three times, “they will abandon shopping with that retailer altogether”; 41% of returns in the same survey were of an item that was simply the wrong thing. S21 Again: US only, vendor-commissioned, self-reported intention rather than observed behaviour. The direction is not in doubt even if the magnitude is.
The numbers you cannot compute without a stable key
Sell-through, reorder points, days of cover, margin by item, dead-stock ageing, supplier performance, the effect of a discount on a single colourway — every one of these is a GROUP BY on the item key. If the key is missing, the report is empty and you notice. If the key is unstable — renamed last spring, reused for a different product, duplicated across two variants — the report is wrong and you do not.
This is why Google's feed guidance is phrased as an instruction rather than a suggestion: “use a stable ID for each product. Once you’ve assigned an ID to a product, don’t change it”, and “don’t reuse or recycle the same ID for different products.” S8 It is the same requirement your own analytics has; Google just states it out loud because they have to run the join.
It is also worth knowing that item-level classification is noisier than the textbooks suggest. Inventory-optimisation vendor Lokad, which sells an alternative approach and says so, argues that in ABC analysis “items frequently change categories (25–50% per quarter)”. S22 Take the figure with the attribution attached — but the underlying warning is sound: a classification computed on a shifting key tells you less than it appears to.
Returns and exchanges close the loop
A return is the one moment where the whole chain runs backwards, and every step of it needs the item key. Which exact variant came back? Is it resellable, and to which bin does it go? Is the customer exchanging for a different size — that is, for a different SKU — or refunding? A returns process that identifies items by product name rather than by variant code reliably restocks the medium into the large.
The volume makes it worth getting right. A February 2022 survey of 168 US online retailers, all fulfilling more than 25,000 orders a year, put the cost of online returns at “an average 21% of order value”, with return rates averaging 20.8% in 2021 against 18.1% in 2020. S23 That is a US, mid-to-large-brand figure and should not be transplanted onto a Baltic merchant's numbers — comparable EU-wide data does not exist in public. But a fifth of order value moving backwards through a process that cannot tell one variant from another is a compounding problem.
Cross-border: the SKU is where customs data lives
A SKU is not itself a customs field. It is the hook that every customs field hangs on — and since 1 September 2025, there are more of them. UPU Convention Regulations article 20-001.2.8 “requires senders of items containing goods of a commercial nature to provide six-digit WCO Harmonized System tariff codes on the Customs declaration for each article contained in an item.” S24 The EU's own reduced H7 dataset asks for the same six-digit subheading. S25 Carriers are unsentimental about what happens if the description is vague; DHL's guidance says simply that “vague descriptions can delay customs clearance.” S26
Per article. Which means the HS code, the country of origin, the net weight and a customs-safe description have to be stored somewhere per item, once, and emitted automatically on every CN23 and commercial invoice. The only sane place to store them is against the SKU. Without one, that data has nowhere stable to live and gets retyped — per parcel, by a human, at the point in the day when everyone is trying to hit the courier cut-off.
The same logic runs through EU product-safety rules. The General Product Safety Regulation has applied since 13 December 2024 and requires products to carry an identification element — the Commission's own guidance lists “type, batch or serial number or other element enabling product identification (e.g. barcode)” — alongside the responsible economic operator's contact details. S27 Traceability duties are per item, so they are per SKU.
For Baltic merchants specifically, the marketplace layer arrives early. Eurostat's 2024 data has Lithuania with the highest share of e-selling enterprises in the EU at 43.03%, and 86.55% of Lithuanian enterprises with web sales selling through marketplaces. S28 Marketplaces are where identifier rules are enforced most strictly, so a Lithuanian catalogue tends to meet GTIN and SKU requirements sooner than a comparable shop in a market with a weaker marketplace habit.
Designing SKUs that survive contact with other systems
Most SKU advice is about aesthetics. The rules that actually matter are constraints imposed by systems downstream of you, and they are documented.
- Design for the hardest limit, not the softest. Shopify's API documents no maximum length at all S2, but Google's feed
idis capped at 1–50 characters S8 and Adobe Commerce fails an import above 64 S7. Fifty characters is the real ceiling for anyone running a Shopping feed. - Aim for roughly 8 to 16 characters. Shopify advises “no more than 16 characters” and says a format “as short as 4 to 8” can work S1; Amazon observes that SKUs “are usually made up of 8 to 10 letters and numbers” S14. The sources disagree, which is itself the answer: pick a length in that band and be consistent.
- Restrict the character set to uppercase A–Z, digits and hyphens. This is the intersection of what your downstream systems accept. Code 39 — still the default in plenty of label printers — encodes 43 characters and no lowercase at all S29,S30; Google's
idallows “alphanumeric, underscores, and dashes” S8; WooCommerce's own example isSKU-501-REDS5. Anything outside that intersection works until the day it does not. - Avoid characters humans and software confuse. Shopify names the specific trap: “zeros can be skipped by some retail software or mistaken by employees for the letter O”, and special characters “such as !, @, or & can disrupt certain software systems”. S4
- Standardise on one case, and do not use case to distinguish codes. Shopify's
skufield is “a case-sensitive identifier” S2, soABC-01andabc-01are two different SKUs to the API, while Google says outright “don’t use casing to make IDs unique”. S8 Uppercase everything as a house rule and the ambiguity disappears. - Put the most significant segment first, and give variants a shared parent. Shopify's recommended shape runs category, style, colour, size, sequence, so that “the most important information appears first” S4. The parent portion is what you feed Google's
item_group_idS10. - Never reuse a retired code. Google: “don’t reuse or recycle the same ID for different products.” S8 Walmart: “the reuse of product IDs for separate items is strictly prohibited.” S12 GS1 went furthest — it banned GTIN reuse entirely from January 2019, having previously allowed it after 30 months in apparel and 48 in grocery, because “once a GTIN is assigned to a product, it could be associated with it forever in the online world.” S17 If the standards body that invented the barcode decided recycling was not worth it, neither is yours.
- Never rename a live code. Same source, same sentence: assign it once, then leave it. S8 Renaming is the operation that silently breaks last year's reports.
- Keep prices, supplier names and GTINs out of the code. GS1's GTIN Management Standard treats a change to the price printed on a pack as a trigger for a whole new GTIN S18 — that is what happens when you bake a mutable fact into an identifier. Store those as fields against the SKU instead.
- Give bundles their own SKU. Shopify's bundles are “assigned a SKU that’s separate from individual products SKUs”, and bundle availability is computed from the components' stock — a component whose inventory is not tracked is silently excluded from that maths. S31
- Use one SKU across all your language storefronts. Google asks for “the same ID for the same product targeting different countries or different languages within the same country”. S8 A shop running LT, LV, ET and EN storefronts needs one code per variant, not four.
Retro-fitting SKUs onto a catalogue that has none
Adding SKUs to a live shop is a day of work and a decade of benefit, but the order of operations matters — mostly because the import step behaves differently depending on the platform.
- 1
Fix the scheme before you touch a product
Decide the segments, the length, the case and the separator, and write them down. A scheme invented row by row in a spreadsheet is a scheme with three conventions in it.
- 2
Assign codes to variants, not products
The sellable unit is the thing you pick, count and ship. A hoodie is not a SKU; a hoodie in navy, size L is. Give the product a parent code and each variant a child.
- 3
Know how your platform matches on import
This is the step that bites. Shopify's CSV import matches rows on the product handle, described as “the unique identifier for each product” — not on the SKU S3 — so a handle that has drifted will create a duplicate product rather than update the existing one. WooCommerce is the opposite and better-behaved here: a collision fails loudly with
product_invalid_skuand returns the conflicting product's ID plus a suggested unique code. S6 - 4
Label the shelf, not just the database
A SKU that exists only in the admin does nothing on the packing bench. Bin labels and product labels are what turn it into a scan.
- 5
Backfill the compliance fields while you are in there
HS code, country of origin, net weight, a customs-safe description. You are already touching every row; doing it now saves doing it per-parcel later.
- 6
Then freeze them
From this point the codes are append-only. Retire, never rename; add, never recycle.
None of this requires new software. It requires deciding, once, that every sellable thing in the business has a name that a machine can read — and then not changing it. Everything else you might want to automate later, from scan-verified packing to a 3PL hand-off to a Shopping feed, assumes that decision has already been made.
