What makes a catalogue hard to migrate
Catalogue size is not a single number. Difficulty comes from three axes at once: how many products exist, how many variants each product needs, and how many combinations of price, language and tax apply per market. A store with 40,000 simple SKUs is usually easier to move than one with 3,000 products that vary by size, colour, finish and country price.
Shopify advertises unlimited products on every plan: its pricing page lists Sell unlimited products as a feature of Basic, Grow, Advanced and Plus. The real bottleneck sits elsewhere: in how you model variants, in how fast inventory can be written through the API, and in what the theme can actually render on a product page.
That is why the first deliverable of a serious migration is not a timeline but a source catalogue inventory with numbers: active products, how many need more than three attributes, how many variants the largest product has, image count, indexed URLs, and which spec-sheet attributes are genuinely used.
- More than three attributes separate one SKU from another
- SKUs that only exist in one country or one language
- Customer-specific, company-specific or volume pricing
- Spec sheets with dozens of attributes living in legacy CMS fields
- Personalised products where the buyer types or uploads something
The platform limits worth checking before you sign
The biggest change of recent years is the variant ceiling. In its changelog of 15 October 2025, Shopify announced that all merchants can create products with up to 2,048 variants, up from the historical limit of 100. Plenty of migration content still quotes 100, so check the date on any guide you read, including this one.
What did not change is the number of options. The GraphQL Admin API documents the OPTIONS_OVER_LIMIT error, with the message that you can only specify a maximum of three options. That is the limit that really forces a rethink of the data model: if a SKU today is defined by size, colour, material and length, those four cannot all be options of the same Shopify product.
On the API side, variant mutations work in bounded batches. Shopify documents that productVariantsBulkCreate accepts up to 2,048 variants in a single operation, and that reaching 2,048 requires the REMOVE_STANDALONE_VARIANT strategy; otherwise it is 2,047 alongside the auto-created variant. productVariantsBulkDelete handles up to 250. Querying a product, you can request up to 2,048 variants with the first argument, and the variantsCount field returns how many it has.
Inventory has its own ceiling that sets the pace of the load: since API version 2025-10, the productSet mutation enforces a maximum of 50,000 inventory quantities across all variants in a single mutation. That number decides how stock loading is chunked for a large multi-location catalogue.
All of this runs through GraphQL, and it is worth settling before you choose tooling. The REST Admin API reference states that the REST Admin API is a legacy API as of 1 October 2024, and that listing, creating, updating and deleting products is deprecated as of REST version 2024-04, with GraphQL equivalents: productCreate, products, product, productsCount, productUpdate and productDelete. The same page adds that from 1 April 2025 all new public apps must be built exclusively with the GraphQL Admin API. For a migration this is not a developer footnote: it decides which loading tool you can use and rules out any legacy script that writes products over REST.
- 2,048 variants per product for all merchants, since October 2025
- 3 options per product: Admin API limit, OPTIONS_OVER_LIMIT error
- productVariantsBulkCreate: up to 2,048 per operation, 2,047 without REMOVE_STANDALONE_VARIANT
- productVariantsBulkDelete: up to 250 per operation
- productSet: up to 50,000 inventory quantities per mutation, API 2025-10
- REST Admin API: legacy as of 1 October 2024
- Products over REST (list, create, update, delete): deprecated as of version 2024-04
The ceiling nobody checks: themes, Liquid and legacy apps
The platform accepting 2,048 variants does not mean your theme will show them. The Liquid reference is explicit: product.variants returns a maximum of 250 variants when unpaginated, and the paginate tag serves up to 50 per page. A variant picker built as a loop over product.variants silently runs short once a product passes 250, and nothing throws an error: combinations are simply missing.
Apps behave the same way. The 2,048-variant changelog itself warns that merchants using apps that do not use the in-support GraphQL product APIs may see a downgraded or broken experience when creating or viewing products with more than 100 variants. That includes ERP, PIM, feed and marketplace connectors, which are exactly the critical pieces of a large catalogue.
The test is cheap and belongs before the contract, not after it. In a development store, create a product with more variants than your worst real case, install the candidate theme and the apps you plan to keep, then look at the product page, the cart, the inventory screen and the product feed. If something breaks, you still have time to change theme or app.
- Liquid: product.variants returns at most 250 variants unpaginated
- With paginate, up to 50 variants per page
- Apps outside the GraphQL product APIs: degraded experience above 100 variants
- Test the worst case in a development store before committing
Modelling what does not fit into three options
You do not break the three-option limit, you design around it. The first route is metafields and metaobjects, where spec-sheet attributes that do not drive price or stock belong. Material, certifications, consumption, compatibility or packaging dimensions do not need to be variants: they need to be structured, filterable and reusable across products.
Here the numbers are published, and they belong on the table before you draw the data model. Shopify documents up to 128 metaobject definitions on the Basic, Shopify and Advanced plans and 256 on Plus and Enterprise, with a maximum of 40 fields per definition and up to 1,000,000 entries in each one. For metafields, the cap is 256 definitions per resource type, of which 50 can be pinned; batch mutations take 25 metafields per request in metafieldsSet, with a 10MB payload ceiling, and 250 per request in metafieldsDelete.
That per-plan split matters when sizing a large catalogue: if you need dozens of structured content types (spec sheets, size guides, ingredients, compatibility tables, manufacturers), twice the metaobject definitions on Plus stops being a detail and becomes a plan criterion. Watch the Liquid render limits too: looping without pagination returns up to 50 metaobject entries, and with the paginate tag up to 250 per page.
The second route is combined listings. Shopify documents the Combined Listings app for Shopify Plus merchants and notes that a combined listing can have up to three options in addition to the options in each product included in the listing. It groups what is conceptually one product and technically several, without inflating anyone's variant count.
The third route is splitting or simplifying. An attribute with two values that nobody filters or buys on is probably noise. An attribute that multiplies the catalogue tenfold and barely sells deserves a review before it is migrated at all. A migration is the best chance you will get in years to take weight out of the catalogue.
For personalised products, the answer is not a variant per combination. Shopify documents line item properties: inputs inside the product form named properties with the property name in brackets, for example properties[Monogram], which travel with the cart line. Engraving text, custom notes or an uploaded file belong there, not in the catalogue.
A phased load plan for a large catalogue
Sequence matters more than speed. In the migrations we run, the order is always the same: audit and clean the source, lock the product model, load in batches, and only then open the cutover window. Every batch is verified before the next one starts, because a modelling mistake repeated twenty thousand times costs far more to undo than to prevent.
Cleaning happens in the old system, not in Shopify: discontinued SKUs, duplicates, unused attributes, orphan images and empty categories. Anything you do not clean beforehand gets migrated, and anything migrated has to be maintained afterwards.
Decide the loading tool early. Shopify's native CSV import works for moderate catalogues and has its own rules: the file cannot exceed 15 MB, and if the import fails or times out Shopify recommends splitting it into smaller files. Matching happens by handle, and without the overwrite option products matching an existing handle are ignored. One detail breaks integrations: changing the Option1, Option2 or Option3 value columns deletes existing variant IDs and creates new ones, which can break any third-party dependency on those IDs. CSV imports also cannot bulk-delete products.
Above a certain volume or complexity, the load moves to the GraphQL Admin API, chunked against the limits above, with retries and a record of which batch carried each product. That record is what lets you repair one mistake without reloading everything.
Verification is not done by eye. We sample each batch with fixed criteria: a set of randomly chosen products plus the known worst case, checking price, stock per location, images, metafields, collections and the rendered product page. Our Shopify migration service starts with exactly that audit of the source catalogue.
- Source audit: products, variants, images, attributes and URLs, with numbers
- Clean in the legacy system before exporting anything
- Product model locked and documented before the first batch
- Load order: products, inventory, metafields and metaobjects, collections, customers, historical orders
- Sampled verification per batch, worst case included
- Catalogue freeze during the cutover window and a written rollback plan
Redirects and search visibility
The redirect map saves more rankings than anything else in a migration, and it is the deliverable most often improvised. It has to be product to product and category to collection, not a blanket redirect to the homepage or the parent collection. When the source is Magento with the .html suffix on product URLs, almost no old URL matches the new one, so the map covers the whole catalogue.
Shopify supports bulk redirect import from a CSV, under Content, in menus, inside the URL redirects view. The published caps leave plenty of room: a store can have up to 100,000 URL redirects, and stores on the Plus plan up to 20,000,000. One limitation deserves attention: redirects only work for broken URLs. If the source URL still loads a valid page, the redirect will not apply.
Indexed facets and filter URLs from the old system need a case-by-case decision. Filter URLs with real traffic and links deserve their own Shopify collection, with a title and copy of their own; the rest redirect to the relevant collection and stay out of the sitemap. Spawning empty collections just to preserve old URLs is expensive to maintain and buys nothing.
With several languages or markets, the checklist grows to canonicals, collection pagination and hreflang across each market's domains or subfolders. After the cutover, watch Search Console daily for the first weeks: coverage, 404s, detected redirects and the trend of the URLs that used to bring the most traffic. That is where the gaps in the map become visible while they can still be fixed.
- Product-to-product and category-to-collection redirect map as a reviewable deliverable
- Bulk CSV import from URL redirects in the admin
- Up to 100,000 redirects per store, 20,000,000 on Plus
- A redirect does not apply while the source URL still returns a valid page
- Daily coverage and 404 monitoring in Search Console for the first weeks
Multi-market and B2B without duplicating the catalogue
The temptation in an international migration is to duplicate the catalogue per country. With Markets you do not have to: market customisations control settings such as currency, product availability, theme content, domains, languages and taxes over the same catalogue. Shopify also defines a backup region for buyers who do not match any active market, which is worth configuring before launch rather than after.
An expansion store earns its place when what changes is the business, not the price or the language: genuinely different assortment, separate operations and warehousing, or a separate legal entity with its own invoicing. If currency, taxes and translations are the only differences, a second store multiplies catalogue maintenance for nothing.
For wholesale, native B2B works through catalogues: you choose which products and which prices B2B customers get, including or excluding products, applying percentage price adjustments and setting fixed prices. Catalogues are assigned to a B2B market and, on Plus, directly to company locations too. One plan limit shapes the architecture: on Basic, Grow and Advanced you can have up to three active catalogue assignments across active B2B markets, and assigning the same active catalogue to two active markets counts as two assignments. That three-assignment limit does not apply on Shopify Plus.
Read the other way round: if your wholesale model needs different terms for many customer groups, the number of catalogue assignments is a concrete technical argument for Plus, and a far more solid one than the generic ones.
What to ask your agency before signing
A large-catalogue migration proposal is judged on four documents, not on the headline price. The first is the source catalogue inventory with numbers: products, variants, the product with the most variants, images, attributes and indexed URLs. If the proposal has adjectives where numbers belong, nobody has looked at the catalogue yet.
The second is the variant modelling rationale in writing: which three attributes become options, what moves to metafields or metaobjects, what is solved with combined listings and what with line item properties. The third is the redirect plan as a reviewable deliverable, with its stated coverage of total indexed URLs. The fourth is the rollback plan and the cutover window: what happens if something fails halfway through the load.
Ask for the worst-case test in a development store, with the candidate theme and apps, before the whole project is committed. It is a small amount of work and it prevents discovering in production that the variant picker stops at 250.
Weblineo has worked only with Shopify since 2016 and is a Shopify Plus Partner. If you are weighing a move from Magento, PrestaShop or an in-house build, we can audit the source catalogue and hand you the product model and the redirect map before you commit to a platform.
- Source catalogue inventory with numbers
- Documented variant modelling rationale
- Redirect plan as a deliverable, with stated coverage
- Rollback plan and cutover window
- Worst-case test with the candidate theme and apps
Frequently asked questions
How many variants per product does Shopify allow?
Since the changelog of 15 October 2025, all merchants can create products with up to 2,048 variants, up from the historical limit of 100. The number of options per product did not change: the Admin API still returns an error if more than three are specified.
If Shopify allows 2,048 variants, will my theme display them all?
Not necessarily. The Liquid reference states that product.variants returns a maximum of 250 variants unpaginated, and up to 50 per page with the paginate tag. Older themes and apps can fall short, so test your worst case in a development store before migrating.
How do I handle more than three attributes with only three options?
Attributes that do not drive price or stock go to metafields and metaobjects. To group related products there is the Combined Listings app, available to Shopify Plus merchants. For anything the buyer types or uploads, use line item properties on the product form.
Is there a redirect limit when migrating from Magento?
Shopify allows up to 100,000 URL redirects per store and up to 20,000,000 on the Plus plan, importable from a CSV. Keep in mind that a redirect only works once the source URL no longer loads a valid page.
Do I need Shopify Plus for a large catalogue?
The 2,048-variant ceiling is available to all merchants, so catalogue size alone does not require Plus. Specific cases do: combined listings, assigning B2B catalogues directly to company locations, not being subject to the three active catalogue assignments limit that applies on Basic, Grow and Advanced, and twice the metaobject definitions, 256 against 128.
Sources
- Shopify.dev: the product variant limit is now 2048 for all merchants (opens in a new tab)
- Shopify.dev: productSet limit for inventory quantities (opens in a new tab)
- Shopify.dev: migrate to the new product model (GraphQL Admin API) (opens in a new tab)
- Shopify.dev: productOptionsCreate mutation (opens in a new tab)
- Shopify.dev: Liquid product object (opens in a new tab)
- Shopify.dev: product template and line item properties (opens in a new tab)
- Shopify Help Center: variants and combined listings (opens in a new tab)
- Shopify Help Center: import products with a CSV file (opens in a new tab)
- Shopify Help Center: URL redirects (opens in a new tab)
- Shopify Help Center: Markets (opens in a new tab)
- Shopify Help Center: B2B catalogs (opens in a new tab)
- Shopify.dev: metaobject limits (opens in a new tab)
- Shopify.dev: metafield limits (opens in a new tab)
- Shopify.dev: Product resource, REST Admin API (opens in a new tab)
- Shopify pricing (opens in a new tab)
