This guide is for WooCommerce store managers and web developers who need to bulk-apply scheduled sale prices and dates in WooCommerce using an import/export CSV file.
It will cover how to apply sale prices, utilise array formulas for peak efficiency, and schedule sale dates in Google Sheets before re-importing the updated CSV into WooCommerce, whilst checking for any potential issues along the way.
These issues can include caching, stalled scheduled tasks, and outdated lookup tables, which may prevent scheduled sale prices from displaying correctly.
Create a sample product with a scheduled sale
- Log in to your WordPress admin.
- Go to Products.
- Find one product you intend to put on sale.
- Edit the product.
- Locate the pricing fields.
- The Regular Price field should already have a value.
- Add a value to the Sale Price field.
- Add a Schedule (start and end date).
- Save the product.
This single product will serve as your reference for correct date formats and sale price structure when applying values in bulk.
Export products to CSV
- Go to Products → All Products.
- Click Export.
- Export all columns (we will hide unneeded ones later).
- Download the CSV file.
- Upload it to Google Sheets and give it a descriptive name.
Before doing any editing, duplicate the tab. Name the original “OG Source” and make it Red (This will remind you not to edit it).
Name the duplicate “Working“. This way, we have a backup of our product data that we can revert to if any mistakes are made. From now on, work in the duplicated tab (the Working tab).
Identify your example product in Google Sheets
Find the product you edited in WooCommerce.
Simple products
The sale price and sale schedule dates will be clearly visible in their respective columns.
Variable products
These are more complex:
- WooCommerce splits products into parent (variable) and children (variations).
- The parent groups the variations but does not hold price values.
- Sale prices and schedules apply only to the variation rows, not the parent (variable) row.
Use your edited product to identify:
- The correct sale price format, column, cell, etc
- The correct date_on_sale_from and date_on_sale_to cells, either in the simple row or the variation row.
Filter the products you want to include in the sale
A quick disclaimer.
Do not modify: ID, Parent, Slug, GUID, or product type rows.
Changing these can permanently break product relationships.
This prevents the most common WooCommerce CSV mistakes.
With that in mind, use Google Sheets filters to select only the products that your sale should apply to. You may filter by category, tag, etc.
You should now have a filtered list that includes simple products and variable parents, but likely none of the variations.
If you’ve filtered using category, tag, etc, you’ll likely have noticed that the variation rows do not have a category or tag applied, making it impossible to include them in your filters.
To get around this problem, copy and paste your filtered list of simple and variable products into a new spreadsheet tab called “Edited“.
Don’t forget to include the header row.
How to include variations in your list
1. Add a new column to the “Working” tab on the right-hand side of the “Parent” column.
2. Add a heading to the column “Formula“.
3. Add the following formula to the first cell in the new column (not the header row): =ARRAYFORMULA(IF(XLOOKUP(AF2:AF, Edited!C2:C, Edited!A2:A, "")="", 0, 1))
4. Copy the “Formula” column and paste it exactly where it was as values only (this is done by pressing on the column, selecting paste special, and selecting values only) rather than keeping the formulas active.
5. Filter the “Formula” column to only include the “1” cells. This is done by selecting the entire spreadsheet and clicking Data > Create a filter, and then pressing the little triangle at the top of the column.
6. Move the formula column to the end column by dragging and dropping the column, so you can copy the data without the extra column, or add a blank column next to the parent column in the “Edited” tab, so when you paste the data, there is no column mismatch.
7. Copy and paste your new list of rows from the filtered “Working” tab into the bottom of the “Edited” tab. If you paste the top row back in (which tells you what each figure represents, ID, Type, Name, etc.), then delete it if duplicated.
8. You can then choose to hide some of the data that is not needed for setting sales (such as descriptions or stock in this case) to neaten it up a bit; this is purely optional. If you choose to do this, you can click the top of the column, then select “hide column.” You can also select the whole document and choose to clip overflow in the format section.
Once completed, this should look similar to this (I have chosen to clip columns and hide unnecessary columns in this example):

You should now have a complete list of:
- Simple products (shouldn’t have a parent)
- Variable parent products (for reference only) (shouldn’t have a parent)
- Product variations (where sale prices will actually be applied) (should have a parent)
Apply bulk sale prices and schedules
Important: Do not apply sale prices or schedules to variable parent products; these fields belong only on simple products and variations.
Sale schedule format
Copy the date values from your example product to ensure the format matches WooCommerce expectations.
Alternatively, use this schema: https://woocommerce.com/document/product-csv-importer-exporter/#product-csv-import-schema/
| Field | WooCommerce Meta | Example | Notes |
|---|---|---|---|
| Date sale price starts | date_on_sale_from | 2013-06-07 | Start of day, or leave blank |
| Date sale price ends | date_on_sale_to | 2013-06-07 | End of day, or leave blank |
You can use an array formula for this to avoid adding variables. This is useful if you have a lot of products.
In the case of the example data I used the following array formula. You should be able to add it to your “Date sale price starts”, “Date sale price ends”, and “Sale price” columns (assuming none of your products have values in these cells).
=ARRAYFORMULA(IF(REGEXMATCH(B2:B, "simple|variation"), "2013-06-07", ""))
B2:Bis the Type column<>means not equal to- “2013-06-07” is the value that will be inserted in to the column if the product type is not equal to “variable”.
You can swap out “2013-06-07” for the date your sale starts/ends for the respective columns, and even use a formula for the sale price knocking a discount off of your existing regular price.
An example of this might be:
=ARRAYFORMULA(IF(REGEXMATCH(B2:B, "simple|variation"), Y2:Y*0.8, ""))
Y2:Yis the regular price column- The formula applies a 20% discount (
Y2:Y*0.8)
Once applied, this is how your products should look:

Prepare the CSV for re-upload
Slim down the sheet before exporting – you don’t need to re-upload all that data.
You should keep:
- ID
- SKU
- Type
- Name
- Parent
Recommended to keep:
- Product title (for readability)
Required for your sale changes:
- Sale price
- Date sale price starts
- Date sale price ends
Export the sheet as a CSV file. Top left File > Download > CSV
Import the CSV back into WooCommerce
- Go to Products → All Products.
- Click Import.
- Upload your CSV.
- Review the field mapping.
- It should match automatically since the file came from WooCommerce.
- Double-check to be safe.
- Run the importer.
WooCommerce will now apply your updated sale prices and schedules.
Common issues that prevent scheduled sale prices from showing
1. Cached product data (cache not invalidated)
Even after WooCommerce updates prices, cached pages or cached product metadata may continue showing old pricing.
Typical cache sources:
- Page/cache plugins
- CDN caching
- Redis/Memcached object caching
- WooCommerce fragment caching
Symptoms:
- Guests see old pricing; logged-in users see sale prices.
- The sale appears only after a manual cache purge.
- Some pages update, others do not.
Why this matters: Caches don’t refresh automatically when a scheduled sale activates.
2. Scheduled sale tasks stuck in Action Scheduler
WooCommerce uses Action Scheduler to activate sales. If tasks fail, sale prices never switch on.
Check in WooCommerce → Status → Scheduled Actions for entries like:
woocommerce_scheduled_sales
If tasks are pending, failed, or cancelled, they never ran.
Why this matters: Even correct data won’t apply if the scheduled sale action didn’t execute.
3. Product lookup tables not updated
WooCommerce uses lookup tables for product pricing and ranges.
If these tables are stale:
- Sale badges don’t show
- Variable product price ranges are wrong
- Admin shows the sale price, but the front end does not
Fix by going to WooCommerce → Status → Tools → Regenerate Product Lookup Tables.
Why this matters: Lookup tables determine what prices appear on the front end.








