Key takeaways

  • WooCommerce has no import limit. Your hosting does, and images are what exhaust it.
  • Batches of 200 to 500 products are reliable on typical shared hosting.
  • Updates match on SKU or ID. Blank or changing SKUs guarantee duplicates.
  • For catalogues that change, a feed beats a file. It re-syncs instead of re-uploading.

There are two genuinely different problems hiding behind "bulk import products into WooCommerce".

The first is a one-time load: you have a catalogue, you want it in WooCommerce, and once it is there you will maintain it by hand. A CSV is the right tool.

The second is an ongoing relationship with a catalogue you do not control, such as a supplier or a store you are mirroring. Prices move, stock moves, products appear and vanish. A CSV is the wrong tool, and using it anyway is why people end up re-uploading files every Monday morning.

The CSV route, done properly

WooCommerce's built-in importer lives at Products, All Products, Import. Upload, map columns, run.

Four settings decide whether it works:

Update existing products

Off for a first import. On for corrections and re-runs. When on, WooCommerce matches incoming rows against existing products by ID first, then SKU.

If a row matches nothing, it creates a new product. This is the mechanism behind almost every "why do I have 4,000 products when I imported 2,000" question: the second run had different SKUs, or none.

Column mapping

WooCommerce auto-detects its own standard headers. Anything it does not recognise defaults to Do not import, and it does not warn you. Scroll the entire mapping list before running. This is where custom fields silently disappear.

Batch size

Not exposed in the UI. Effectively governed by PHP max_execution_time, memory_limit and your host's request timeout. The importer processes rows in AJAX chunks, so a job that exceeds those limits dies partway with a generic error.

Images

The real bottleneck. Every URL in the Images column is downloaded into the media library during the import request. Not queued, not backgrounded. A 2,000 product catalogue averaging six images each means 12,000 HTTP fetches plus thumbnail generation, inside a request your host wants to finish in 60 seconds.

Size your batches by images, not products. A text-only import of 2,000 rows is fine. The same 2,000 rows with galleries needs splitting into batches of 200. If your import dies at an unpredictable point each time, images are almost always the reason.

Preparing the file

Before you upload anything, run these checks. Each one prevents a specific failure:

  • Encoding is UTF-8. In Excel, Save As, CSV UTF-8. Anything else mangles accented characters.
  • Every product has a unique SKU. Not for WooCommerce's sake, for your future self's. Without stable SKUs you can never safely re-import.
  • Prices are bare decimals. No currency symbols, no thousands separators. 1299.00, not $1,299.00.
  • Image URLs are absolute and reachable. Paste three into a private browser window and confirm they load.
  • Parent rows precede variation rows. Sort by Parent.
  • Categories use consistent spacing. Clothing > Shirts, always with the same spaces.

The full column reference, including the attribute flags that decide whether variations display, is in the WooCommerce product CSV schema explained.

Raising the limits

If you control the server, these are the values worth changing:

memory_limit = 512M
max_execution_time = 300
max_input_vars = 5000
upload_max_filesize = 64M
post_max_size = 64M

Set them in php.ini, or via your host's control panel. Adding them to .htaccess works on some Apache setups and is ignored on most managed hosting.

On managed WordPress hosting these are frequently locked and support will not raise them. In that case batching is your only option, and you should stop fighting it.

The feed route

Everything above assumes a file. For a catalogue that keeps changing, a file is the wrong shape of solution: it is a snapshot of a moving thing, and every time the thing moves you produce another snapshot by hand.

A feed inverts this. Instead of uploading a file, WooCommerce reads a URL that always returns the current state of the catalogue. The import runs on a schedule and applies only differences:

  • New products at the source get created.
  • Price changes propagate, with your markup rule reapplied.
  • Stock changes propagate, so items that sold out upstream stop being sellable on your store.
  • Removed products get marked out of stock rather than deleted, so URLs and any accumulated SEO value survive.

This is how our free WordPress plugin works. You scrape a store on Scrapify, save it as a live feed that refreshes hourly, then connect the plugin once. It handles batching, retries and image fetching in the background, applies a percentage markup and rounding rule, and matches on SKU so re-syncs update rather than duplicate.

Every account includes it, free accounts included, and the setup is walked through step by step in the plugin guide.

Import once, stay in sync forever

Scrape a store, save it as a live feed, connect the free WordPress plugin. Products, variations, images, categories and currency conversion, re-synced automatically.

Read the plugin guide Create a feed

File or feed?

CSV importLive feed
Best forOne-time migrationCatalogues that change
Price updatesManual re-uploadAutomatic
Stock updatesManual re-uploadAutomatic
New productsManualAutomatic
Markup rulesRecalculate in the sheetSet once, applied every sync
Currency conversionManualLive rate at sync time
Timeout riskHigh on big filesLow, work is backgrounded
Works offlineYesNo, needs the source reachable

After the import

Whichever route you took, check these before considering the job finished:

  1. Count products. Products, All Products should match your row count, minus variation rows.
  2. Check the media library. Roughly your expected image total. A number far too low means image fetches failed.
  3. Open a variable product on the front end. Confirm the dropdowns render and selecting options changes the price.
  4. Sort by price ascending. Anything at 0.00 imported with a blank or malformed price.
  5. Regenerate thumbnails if images look wrong, using WP-CLI or a plugin.
  6. Re-run product lookup tables. WooCommerce, Status, Tools, Regenerate product attributes lookup table. Skipping this makes filtered navigation return wrong results.

If something did go wrong, the symptom-to-cause mapping is in 12 WooCommerce import errors and how to fix them.

Frequently asked questions

How many products can WooCommerce import at once?
There is no hard limit in WooCommerce itself, only in your hosting. The importer processes rows in batches over AJAX, so the ceiling is really PHP memory_limit, max_execution_time and how long your host lets a request run. On typical shared hosting, batches of 200 to 500 rows are reliable and 5,000 in one go usually is not.
How do I update existing products instead of duplicating them?
Tick Update existing products on the import mapping screen and make sure every row has a stable SKU or ID. WooCommerce matches on those. If your SKUs are blank or change between imports, the importer has no way to recognise the product and creates a second copy.
Can I import product images from URLs?
Yes. Put the full image URLs in the Images column, comma separated, with the featured image first. WooCommerce downloads each one into the media library during import. This is by far the slowest part of the job, so a catalogue with ten images per product needs much smaller batches than a text-only one.
What is a feed-based import?
Instead of uploading a file, WooCommerce reads a URL that always returns the current catalogue. The import can then be re-run on a schedule and only applies what changed: new products added, prices and stock updated, removed products marked out of stock. It suits dropshipping and any catalogue you do not control.

Keep reading

WooCommerce The WooCommerce Product CSV Schema Explained, Field by Field WooCommerce 12 WooCommerce Product Import Errors and How to Fix Each One Guides How to Stock a New Store With Products in Under an Hour