A SKU is a string of characters that identifies one sellable thing. That is the whole specification, which is why it usually gets decided in about four seconds by whoever is filling in the first row of the spreadsheet.
Then the catalogue grows. Two years later there are eleven thousand of them, three people have invented three schemes, and nobody can answer a question as basic as “show me every size of this shirt in navy.” The SKU was not the cause of that, but it is the field that could have prevented it.
This is how I structure SKUs on catalogues that are going to keep growing, and the habits that quietly wreck them.
It is the one field nobody can fix later
Almost everything else in a product record is repairable. Titles get rewritten. Descriptions get replaced. Categories get restructured on a Tuesday afternoon and nobody outside the business notices.
SKUs are different, because other systems hold copies of them. The accounting software has them on old invoices. The warehouse has them on shelf labels. The supplier quotes them back to you in emails. A purchase order from eight months ago has them printed on it. Changing a SKU does not update any of that; it just makes the old copies wrong.
So the practical rule is that a SKU scheme has to be right enough on day one to survive being wrong later. It does not need to be elegant. It needs to be stable.
What the segments should mean
A workable SKU has segments, and each segment answers one question that a human will actually ask while looking at a list.
The pattern I use most often is brand → family → variant → size, with fixed-width segments and a single separator. Something like UTW-CRWN-NVY-L. Four segments, each one readable, and sorting the column groups related products together without any extra work.
Fixed width matters more than it sounds. If one brand code is two characters and another is five, alphabetical sorting stops being useful and every spreadsheet formula that slices the string needs exceptions. Pick a width, pad it, and never make an exception because a supplier’s name is long.
The segments should also be things that never change for the life of the product. Colour is safe. Size is safe. Season is not — the same shirt gets carried over. Price is definitely not. Anything that could be edited in the admin without anyone thinking twice does not belong in the identifier.
The parent, the child, and the thing in between
Variable products are where most schemes fall apart, because there are really two identifiers doing different jobs.
The parent is a grouping concept. It is what the customer thinks of as “the product” and what the URL points at. The child is the physical thing on the shelf that gets picked, counted, and shipped. Inventory belongs to the child. SEO belongs to the parent.
The mistake is giving the parent a SKU that looks like a child SKU — usually the first variant that happened to be created. Six months later somebody discontinues that variant and the parent is now identified by something that no longer exists.
I keep the parent as the first three segments (UTW-CRWN-NVY) and let children extend it with the fourth. The relationship is then visible in the string itself, which means it survives a CSV export, an email to a supplier, and a phone call.
Three habits that destroy a scheme
None of these look like a problem on the day they happen.
- Reusing a retired SKU. A code comes free when a product is discontinued, and someone assigns it to a new item. Every historical report that touches that code is now silently wrong.
- Encoding a fact that changes. Supplier codes, warehouse locations, and current pricing all end up in SKUs eventually. All three change without warning.
- Letting the platform generate them. Auto-generated SKUs are unique and completely meaningless, which means the humans immediately start keeping a second, real identifier in a spreadsheet somewhere.
- Allowing exceptions “just for this brand.” There is never one exception. There is a first exception.
Testing a scheme before you commit to it
Before a scheme goes anywhere near an import, I run it against four questions using real data, not examples.
Can I sort the column and get sensible grouping? Can I find every variant of one product with a single filter on part of the string? Does the longest SKU still fit on a shelf label and in the supplier’s order form? And can somebody who has never seen the catalogue read one aloud over the phone without ambiguity — which rules out characters that sound alike and the letter O next to a zero.
If a scheme survives those four with a thousand real rows, it will survive fourteen thousand. If it fails one of them at a thousand, it will fail loudly later. This is the same reasoning I apply to field mapping on a migration, and for the same reason: the cheap moment to be strict is before the import, not after.
What this is really about
SKUs are a small, boring field that quietly decides how expensive the catalogue is to operate. A good scheme means a supplier list can be reconciled by sorting a column. A bad one means someone rebuilds that relationship by hand every time, forever, and nobody ever writes down how long that takes.
The decision is not really about characters. It is about whether the structure of the catalogue is visible in the data or only in somebody’s head. If it is only in a head, the catalogue does not scale past that person. You can see how this plays out across a full build on the Universal Wholesale project, where the scheme had to hold across fourteen thousand items.



