Frequently asked questions
Cross-cutting one-paragraph answers. For depth on any topic, follow the link at the end of the answer to the relevant longer article.
Table of Contents
- What’s the difference between “insert” and “update”?
- Will SSI overwrite my existing products?
- Why is my import slow?
- Can SSI import from a URL or remote feed?
- Does SSI work with WPML / Polylang?
- How do I migrate imports between sites?
- What happens if my server runs out of memory mid-import?
- Can I run SSI imports from a cron job?
- Does re-running an import duplicate my products?
- My import worked before but now fails after upgrading WordPress / WooCommerce / a plugin — what changed?
- How do I make my import not affect site visitors?
- Where do per-import staging tables go?
- Does the import run my hooks, or update search and term counts?
- How do I put several categories, tags or images in one column?
- Can I transform a value during import (mark up prices, combine columns, set stock status)?
- Can I attach images already on the server without downloading them again?
- How do I update only stock and price, without creating products for SKUs that don’t exist?
- I get a fresh CSV in the same format every day. Do I rebuild the template each time?
- Can I run several supplier imports at the same time?
- Can I be notified, or run code, when an import finishes?
- Can I import into a custom post type, not just posts and products?
- Is there a maximum CSV size, or should I split large files?
- What’s next
What’s the difference between “insert” and “update”?
SSI looks at each CSV row, finds the configured unique identifier value (typically SKU), and asks: “Is there already a WordPress post with this identifier?”
- Yes — UPDATE the existing post’s title, postmeta, taxonomies, etc.
- No — INSERT a new post.
The match-existing stage makes this decision. Subsequent update-* and insert-* stages write the result.
You can restrict the import to do only one or the other via the Import mode preset: “Only insert new items” or “Only update existing items”. See Stage selection presets for the full preset list.
Will SSI overwrite my existing products?
By default — yes, for any field your CSV maps. SSI is built around the idea that the CSV is the source of truth and the WordPress posts mirror it.
If you want to ADD new products without ever touching existing ones, use the Only insert new items import mode preset. If you want to update existing without ever adding new, use Only update existing items. See Stage selection presets.
If you only want to update specific fields (e.g. just prices), use Update prices / postmeta only — this runs only the postmeta update stage and skips the post body, taxonomies, and images entirely.
Why is my import slow?
Three usual causes, in order of frequency:
- MySQL temp tables spilling to disk during
upsert-relationships. Fix: turn on Additional Options → Optimise DB Session settings for slow stages. - Too few or too many parallel workers for your box size. Fix: see Choosing parallel workers per stage for sized recommendations.
- Missing covering indexes (only an issue on pre-2.47 versions). Fix: upgrade.
The per-stage timing table at the end of every CLI run tells you WHICH stage is slow. See Diagnosing slow imports for the full diagnostic recipe.
Can SSI import from a URL or remote feed?
Not directly. SSI imports a CSV from wp-content/uploads/super-speedy-imports/.
Workarounds:
- Schedule a
curl/wgetbefore the import (in cron): download the CSV first, then runwp ssi <id>. See Scheduling automated imports with cron for the cron-based workflow. - Use
wp ssi <id> --file=/path/to/downloaded.csvto point at a specific CSV path that doesn’t have to live in the standard uploads directory.
A REST-pull integration is not currently planned. The friction of running curl + wp ssi back-to-back hasn’t been enough to justify the auth + format-detection code needed for first-class remote-feed support.
Does SSI work with WPML / Polylang?
Polylang: yes, fully supported since 2.49. When Polylang is active, SSI assigns the site’s default Polylang language to any imported post that doesn’t already have a language — existing language assignments are left untouched (so price/stock-only re-imports don’t disturb them).
WPML: no, deliberately out of scope. WPML’s per-string database storage makes bulk import 10-100× slower than Polylang’s lighter per-post storage. Polylang is the recommended multi-language plugin for any site that runs SSI imports at scale.
How do I migrate imports between sites?
The fastest path is the JSON config export/import:
- On the source site, open the SSI admin, select your import, click Settings → Export Config. Save the resulting JSON.
- On the target site, install SSI, upload the same CSV to
wp-content/uploads/super-speedy-imports/, then in the SSI admin click Load Config and paste/upload the JSON. - Save Import. The new site now has the import configured identically.
Caveats: the post IDs of imported items will differ between sites — IDs are local. If you rely on post IDs (e.g. URLs that embed them), use slugs or canonical URLs instead, OR migrate the database itself rather than re-importing.
What happens if my server runs out of memory mid-import?
Each stage writes to per-import staging tables (wp_super_speedy_imports_batch_<id> etc.). The data the FAILING stage was writing may be partial or absent; everything from earlier stages is committed and intact.
To resume after a crash:
- Identify the failing stage from
wp_ssi_import_history_stages— look for the latest row with astart_timebut noend_time. - Re-run just that stage + any later stages:
wp ssi <id> <failing-stage>,<next>,.... - The staging tables let the re-run pick up from where the previous run died — no need to re-load the CSV.
See MySQL stopped mid-import for the full failure-recovery walk-through and Choosing parallel workers per stage to size workers to fit available RAM.
Can I run SSI imports from a cron job?
Yes. The CLI is the supported automation path:
# Daily 4am
0 4 * * * cd /var/www/your-site/htdocs && wp ssi 7
Combined with the Import mode preset, you can build cheap daily refresh jobs that only touch the data that changes. See Scheduling automated imports with cron.
Does re-running an import duplicate my products?
No, provided you’ve configured a unique identifier that’s stable between runs (typically SKU). The match-existing stage finds the existing posts and routes them to UPDATE rather than INSERT.
If you see duplicates after a re-import, the most likely cause is the unique identifier changing between runs (e.g. you re-mapped SKU to a different column). See Choosing your unique identifier for the constraints.
My import worked before but now fails after upgrading WordPress / WooCommerce / a plugin — what changed?
In order of likelihood:
- MySQL
max_allowed_packet. A WC upgrade can add new postmeta keys; the bulk INSERT batch grows; the packet exceeds the limit. Bumpmax_allowed_packetto 256M (see MySQL stopped mid-import). innodb_log_file_sizechanges between MySQL versions. A package upgrade may reset config. Re-tune via Database tuning.- Plugin conflict — a new plugin hooks
save_postand crashes. Thesave-postsutility stage in SSI re-fires this hook for every post; check the CLI output for fatal errors mentioning a specific plugin file.
How do I make my import not affect site visitors?
Two strategies:
- Time it for low-traffic windows. Run via cron at 3-5am local time.
- Restrict the parallel-worker count. Each SSI worker holds a MySQL connection that’s unavailable to web traffic. On a busy site with
max_connections = 151, eight SSI workers steal ~5% of the connection pool. Tune workers down to 2-4 for production sites.
The opt-in enable_db_tuning session bumps ONLY affect the SSI worker’s connection — they don’t affect web traffic, even when SSI is running.
Where do per-import staging tables go?
They stay around after every import on purpose, with names like wp_super_speedy_imports_batch_<id>, _terms_<id>, _hierarchies_<id>. This is so you can:
- Re-run individual stages against the same data without re-loading the CSV.
- Diagnose what happened post-mortem (
SELECT COUNT(*) WHERE post_id IS NULLtells you how many CSV rows didn’t get matched).
Each fresh load-csv run drops and recreates these tables, so they never grow unbounded. If you want to clean them up manually, drop tables matching the prefix.
Does the import run my hooks, or update search and term counts?
No. Super Speedy Imports writes to the database with direct SQL and does not fire WordPress action hooks (no save_post, no do_action) during the import. That is what makes it fast. The trade-off is that anything normally refreshed on save is left stale: WooCommerce term counts, the attribute lookup table, and search or filter plugin indexes.
After a bulk import, rebuild whatever you rely on:
- Term counts:
wp taxonomy list --field=name | xargs wp term recount - Super Speedy Search / Filters:
wp sss rebuildandwp ssf rebuild - Anything that hooks
save_post(per product): runwp ssi <id> save-posts(slower, but fires the hooks for every product). - Flush your object cache afterwards.
You can chain the rebuild onto a scheduled import: wp ssi 1 && wp taxonomy list --field=name | xargs wp term recount. See Counts, filters and search are empty after an import in the Troubleshooting guide for the full recipe.
Separate multiple values in a single column with the pipe symbol |. A comma is treated as part of one value (category names often contain commas), so comma-separated values import as a single term.
- Hierarchical taxonomies (product categories) require the pipe:
Cat A > Sub | Cat B > Sub. - Flat taxonomies (tags) accept a comma or a pipe (since 1.78).
- Multiple image URLs: pipe-separated, the first becomes the featured image.
In taxonomy, category and attribute fields the > (hierarchy) and | (multiple values) separators need a space on each side: Capacitors > Ceramic Capacitors. Image URL lists separated by | do not need the surrounding spaces.
Can I transform a value during import (mark up prices, combine columns, set stock status)?
Yes. On any field you choose either direct CSV mapping OR a PHP function, not both, because the function is the mapping: whatever it returns is stored for that row. The function receives the entire row, so you can read any column with $data[$h['Column Name']].
return function($data, $h) {
// add 30% markup to the retail price
return (int) $data[$h['Retail Price']] * 1.3;
};
Cast the input before doing arithmetic ((int) or (float)), otherwise a value like "10 days" silently becomes 7. To combine several image columns into one gallery field:
return function($data, $h) {
$images = [];
for ($i = 1; $i <= 6; $i++) {
$key = 'image_' . $i;
if (isset($h[$key]) && !empty($data[$h[$key]])) {
$images[] = trim($data[$h[$key]]);
}
}
return implode('|', $images);
};
Can I attach images already on the server without downloading them again?
Yes. Super Speedy Imports decides what to do from the value you map:
- A full URL (
http://orhttps://) is downloaded once, then reused on later imports. - A bare filename (
image1.jpg, no protocol) is searched for inwp-content/uploads. The file must already have a WordPress attachment record; a file sitting on disk with no media entry is not found. - Attachment IDs: set
_thumbnail_idto the featured media ID, andproduct_image_galleryto a comma-separated list of gallery media IDs (for example581247,581248,581249). This skips the image stages entirely.
How do I update only stock and price, without creating products for SKUs that don’t exist?
Run only the stages you need and leave out insert-posts, so unmatched SKUs are skipped rather than inserted as empty products:
wp ssi 1 load-csv && wp ssi 1 match-existing && wp ssi 1 update-postmeta
(1 is the import id.) Do not switch on “Delete items missing from import” unless the file really is your full catalogue.
I get a fresh CSV in the same format every day. Do I rebuild the template each time?
No. Build the import once and point it at the new file from the command line: wp ssi 1 --file=/path/to/todays-file.csv. The admin screen binds the template to the original file, but --file runs the same mapping against any file that has the same headers.
Can I run several supplier imports at the same time?
Yes. Each import uses its own staging tables, so you can run many at once. Background each stage chain in bash:
(wp ssi 1 load-csv && wp ssi 1 match-existing && wp ssi 1 update-postmeta) &
(wp ssi 2 load-csv && wp ssi 2 match-existing && wp ssi 2 update-postmeta) &
The only thing to watch: if two feeds contain the same SKU they will fight over the same product, so keep concurrent feeds to distinct SKUs.
Can I be notified, or run code, when an import finishes?
Chain a command with the shell operators: && runs on success, || runs on failure, ; runs regardless.
wp ssi 1 && wp mail send you@example.com --subject="Import done" || wp mail send you@example.com --subject="Import FAILED"
For code that runs inside WordPress, use the action hooks ssi_before_import_stages and ssi_after_import_stages (since 1.87). Each is passed the $import object, so you can read $import->import_id, $import->csv_file_path, $import->config and $import->headers. These are the equivalent of WP All Import’s pmxi_before_xml_import / pmxi_after_xml_import.
Can I import into a custom post type, not just posts and products?
Yes. As well as the Post and WooCommerce Product templates there is a Custom Post Type template (since 1.60). Pick your destination post type and map as usual. Because the data lands in wp_posts, wp_postmeta and the taxonomy tables, any CPT that stores its data the standard WordPress way works. A custom template is only needed if the plugin keeps its own separate tables.
Is there a maximum CSV size, or should I split large files?
There is no size limit in Super Speedy Imports, and you do not need to split large files. The maximum shown on the upload screen is your PHP upload_max_filesize, not an SSI limit. For very large files (multi-GB, millions of rows), either upload the CSV by SFTP into wp-content/uploads/super-speedy-imports/ and refresh the Imports page, or run from the command line, which has no timeouts. A 2 GB, 2 million row file is fine.
What’s next
- Quick start — importing products for new users.
- Stage selection presets for the most-asked configuration question.
- Diagnosing slow imports for performance troubleshooting.
- The rest of the Troubleshooting category for specific failure modes.