WooCommerce Tips

WooCommerce Sale Prices and Variable Products: What Actually Happens When You Run a Discount

🏭

WooCommerce Guide

Your Sale Is Running. Your Variations Aren’t.

How WooCommerce handles sale prices across variable products β€” and where the native approach quietly fails when your catalog grows.

You run a clothing store. You have a hoodie in six colors, each color in five sizes β€” that’s 30 variations on a single product. When you want to run a 20% off sale, WooCommerce’s native answer is: open the product, go to the Variations tab, and set a sale price on each one individually. Thirty times. Then repeat for every other variable product in the store.

This is the real reason “WooCommerce discount variable products all variations” is one of the most searched support queries in the WooCommerce ecosystem. The behavior is technically correct β€” WooCommerce does support sale prices on variations β€” but the workflow is built around individual product editing, not promotional campaigns. When you have more than a handful of products, those are very different things.

This post covers how variable product pricing actually works, where the native approach breaks down, what the strikethrough display behavior is (and where it fails), and how to discount all variations at once without touching each one manually.

How Variable Products and Sale Prices Work Natively

In WooCommerce, a variable product is a parent product that has no price of its own. The price β€” and the sale price β€” lives on each variation. The parent product is essentially a container. It holds the name, images, description, and attributes (Size, Color, etc.), but not a dollar amount.

This is an intentional design decision. Different variations often have different prices. A size XL might cost more than a size S. A leather variant might cost more than canvas. Keeping prices at the variation level gives you the flexibility to price each one independently.

The side effect is that sale prices inherit the same pattern. If you want a sale price on a variable product, you set it variation by variation. There is no single “Sale Price” field on the parent product that cascades down to all its children.

How WooCommerce determines the parent’s displayed price

On the product listing page, WooCommerce shows the price range of a variable product β€” for example, “$29 – $49”. When any variation has a sale price, the displayed range updates to show the discounted span. But this is a calculation, not a stored value. The parent product itself never holds a sale price.

Parent Product vs. Variation: Who Actually Holds the Price?

This is the architecture question that trips people up most often. Here is the actual structure:

  • Parent product β€” stores name, description, attributes, images, and product metadata. No regular price, no sale price.
  • Each variation β€” stores its own regular price, optional sale price, optional sale start/end date, stock status, SKU, dimensions, and image.

When you open a variable product in the WordPress admin and click the Variations tab, you are looking at a list of child posts (post type: product_variation). Each one is a separate database entry. Editing the sale price on one of them writes to that variation’s post meta. It does not touch the others.

This matters because any bulk operation β€” whether from WooCommerce’s own tools or a plugin β€” has to write to every variation individually. It cannot simply change the parent and have it propagate. The cascade has to be done deliberately.

How to Set a Sale Price Across All Variations at Once

WooCommerce does provide a way to do this natively. In the Variations tab, there is a dropdown above the variation list labeled “Bulk actions.” You can use it to:

  • Set regular prices for all variations at once
  • Set sale prices for all variations at once
  • Apply a percentage increase or decrease to existing prices

To run a 20% off sale across all variations, you would select “Set sale prices” from the dropdown, enter the formula (or a fixed amount), and apply it. WooCommerce iterates through each variation and writes the sale price to each one.

This works. But it comes with several limitations worth knowing about.

The limitations of the native bulk action

It applies immediately

There is no way to schedule this for a future date. The moment you hit Apply, all variation sale prices are set and live.

It operates product by product

If you have 40 variable products in your sale, you need to open each one and run the bulk action inside each product’s Variations tab. There is no cross-product operation.

Removing sale prices requires the same steps in reverse

When your sale ends, you go back into each product, select all variations, and clear the sale price manually.

You cannot mix fixed discounts and percentage discounts in a single pass

If your product catalog has varying price points and you want to ensure a meaningful discount on each, this becomes a manual judgement call per product.

The WooCommerce bulk price editor in the Products list is different

WooCommerce’s bulk editor in the Products list (accessible by selecting products and choosing “Edit” from the bulk actions dropdown) lets you change regular prices and sale prices for simple products. For variable products, it does not touch variation-level prices β€” only the parent product record, which does not carry a sale price. This is a common point of confusion. The only place to bulk-edit variation sale prices natively is inside each individual variable product’s Variations tab.

How Strikethrough Pricing Displays on Variable Products

When a variation has a sale price set, WooCommerce shows the strikethrough format: the regular price with a line through it, and the sale price next to it. This is rendered by your theme using WooCommerce’s price HTML output.

On the product listing page (the shop or category page), WooCommerce calculates the price range across all variations and shows something like: $29 – $49 $23 – $39. If only some variations are on sale, the displayed range shifts accordingly.

On the individual product page, before a customer selects a variation, WooCommerce shows the full price range. Once a customer selects a specific variation, the displayed price updates to show just that variation’s price β€” including the strikethrough if that variation has a sale price set.

Where strikethrough display can go wrong

There is a known display inconsistency that affects some store configurations: if a variable product has mixed sale pricing β€” some variations on sale, some not β€” the price display on the product page can look inconsistent or confusing to customers. A customer who selects an unsold variation sees the full price; one who selects a sale variation sees the discounted price. There is no visual indicator before selection that tells them which is which.

The safest approach for promotions is to put all variations on sale. Partial variation sales create UX confusion and can look like an error rather than an intentional discount structure.

There is also a secondary display issue worth mentioning. When sale prices are set directly on variations via the Variations tab β€” without a scheduled start date β€” the sale badge (the “Sale!” label) may not appear consistently across all themes. Some themes only display the sale badge when the regular price and sale price are both present and differ, which should be the case. But the rendering path for variable products is more complex than for simple products, and older themes occasionally render it incorrectly at the variation level. If your sale badge is missing on a variable product, checking the variation-level sale price fields (not just the parent) is the right place to start.

The Scheduling Gap: Why You Cannot Set a Future Sale Without a Plugin

WooCommerce’s native sale price fields do support a date range. On each variation, you can set a “Sale price dates from” and “Sale price dates to” field. In theory, this means you can schedule a sale to start and end automatically.

In practice, this scheduling depends on WP-Cron to fire at the right moment. WP-Cron is not a real server cron β€” it only runs when someone visits your site. On low-traffic stores or at precise off-peak start times (like midnight on a Friday before Black Friday), your sale may not activate exactly when you scheduled it. We covered this in detail in how to run a flash sale without staying up until midnight and the follow-up on WooCommerce scheduled sales not starting on time.

For variable products, this problem compounds. Even if you set scheduled sale dates on each variation individually β€” which requires opening every product, expanding every variation, and entering the dates by hand β€” you are still relying on WP-Cron to process each variation’s sale date at the right moment.

This is the scheduling gap that most apparel and accessories stores eventually run into. The native tooling requires significant manual setup per variation, and then the reliability of the activation timing is not guaranteed.

The scale problem compounds quickly

If you have 20 variable products with an average of 12 variations each, a single sale requires setting sale prices and date fields on 240 individual variation records. Then removing them when the sale ends. That’s 480 data entry operations for a routine promotional event β€” before you’ve written a single email or social post about the sale itself.

The Takedown Problem Is Just as Bad as the Setup

Most store owners focus on getting the sale live. The part that tends to cause more actual customer complaints is ending it cleanly.

When a sale ends, every variation that was discounted needs its sale price cleared. If you miss even a few variations, those products continue to show the crossed-out “was” price. Customers see an inconsistency β€” some products still look discounted, others don’t β€” and it undermines trust in your pricing.

If you set dates natively on each variation, WooCommerce should clear the sale price automatically at the scheduled end time. But again, WP-Cron unreliability means “should” is not the same as “will.” A sale that ends at midnight may still be showing discounted prices at 9am the next morning if no traffic triggered the cron job.

And if you set sale prices manually without dates β€” which many store owners do because the date fields are easy to miss β€” there is no automatic removal at all. You end up with what post 15 in this series covers: sale prices that don’t go away when the sale ends. On variable products, this is especially hard to spot because each variation holds its own sale price independently.

How a Campaign-Based Approach Handles Variable Products Differently

The fundamental shift a campaign-based approach makes is moving the discount operation from the product level to a campaign level. Instead of writing sale prices into each variation’s post meta, the campaign system calculates and applies the discount at runtime β€” and removes it cleanly when the campaign ends.

This changes the variable product problem entirely. When you target a variable product in a campaign, the plugin handles variation coverage automatically. You do not select which variations to discount. You select the product, set the discount percentage or amount, schedule the campaign, and the system applies the discount to all variations when the campaign activates.

The sale badge displays correctly on both the product listing page and the individual product page. When a customer selects a variation, they see the discounted price with the regular price struck through. When the campaign ends, the discount is removed from all variations simultaneously. No leftover sale prices, no missed variations, no manual cleanup.

This is what Smart Cycle Discounts does for variable products specifically. You add a variable product to a campaign as you would any other product. The campaign engine resolves the variation targeting internally β€” you are working at the campaign and product level, not the variation level. A Black Friday campaign with 40 variable products and 300+ total variations is set up the same way as a campaign with 5 simple products: select the products, configure the discount, schedule the dates.

A concrete example

An apparel store running a seasonal sale creates a campaign: 25% off selected hoodies and jackets, running Friday through Sunday. They add 8 variable products β€” each with 20-30 variations. Campaign goes to Scheduled status. Friday morning at 9am, the campaign activates. All variations across all 8 products show discounted prices with strikethrough. Sunday night the campaign expires. All variation prices return to regular. The store owner did not open a single product page during the entire process.

What campaign-level targeting also gives you

Beyond the variation coverage, there are a few other things the campaign model handles that the native approach does not:

  • Conflict detection. If two campaigns both include the same variable product, the priority system determines which discount applies. You do not end up with stacked discounts or unexpected price combinations across variations.
  • Reliable scheduling. The campaign activation is not dependent on WP-Cron alone. Smart Cycle Discounts uses a more reliable scheduling mechanism so your campaign goes live when you set it to go live.
  • Health checks before launch. The Campaign Health system flags operational risks β€” overlapping schedules, stock issues, priority conflicts β€” before the campaign activates. You can review and resolve problems while the campaign is still in Draft or Scheduled status.

When the Native Workflow Is Still Fine

Not every store needs a campaign system. If you are running a small store with a handful of variable products and you run sales infrequently, the native WooCommerce variation bulk action is a reasonable tool. You set sale prices manually, run the sale, then clear them when it’s done. The overhead is manageable.

The native approach starts to break down noticeably when:

  • You have more than 5-10 variable products and run sales regularly
  • You need to schedule the sale in advance (for a holiday, launch event, or planned promotion)
  • You need the sale to end automatically and cleanly at a specific time
  • You are running multiple concurrent promotions and need to ensure they do not interfere with each other
  • You need to audit which products are currently discounted and at what level

At that point you are managing a promotional operation, not just setting a sale price. The right tool for that is not the variation editor β€” it is a campaign system designed for it.

The key thing to take away

WooCommerce stores sale prices at the variation level β€” not the parent product level. This means setting or removing a discount across all variations of a variable product always requires operating on each variation individually, either manually or through an automated system. The native bulk action inside the Variations tab does this per product. A campaign-based plugin does it across your whole catalog at once, on a schedule, with no manual cleanup required.

Frequently Asked Questions

How do I apply a discount to all variations of a variable product in WooCommerce?

Open the product in the WordPress admin, go to the Variations tab, and use the “Bulk actions” dropdown above the variation list. Select “Set sale prices,” choose a fixed amount or percentage, and apply. This writes the sale price to every variation at once without opening each one individually. Note that this is immediate β€” there is no scheduling option in this workflow.

Why is the sale badge not showing on my variable product?

The sale badge on a variable product is generated by WooCommerce based on whether any variation has an active sale price. If the badge is missing, check that the variation sale prices are set correctly in the Variations tab β€” not just at the parent product level, which does not hold a sale price. A caching layer (page cache, object cache) can also delay the badge appearing after prices are changed.

Does WooCommerce show a strikethrough price on variable products before a size is selected?

Yes β€” WooCommerce displays a price range on the product page before a variation is selected (for example, $23 – $39). If any variations are on sale, the range reflects the discounted prices. Once a customer selects a specific variation, the displayed price updates to that variation’s price and strikethrough formatting. The strikethrough only appears at the variation level after selection, not at the parent level before.

Can I schedule a sale on a WooCommerce variable product without a plugin?

WooCommerce does include sale date fields on each variation, but there are two practical problems. First, you need to enter the dates on every variation individually β€” there is no way to set a scheduled sale date across all variations at once from the native interface. Second, the activation depends on WP-Cron, which only runs when traffic visits your site and is not reliable for precise timing.

WooCommerce variable product sale price not working β€” what should I check?

Check in order: (1) confirm the sale price is set at the variation level, not just the parent product β€” the parent has no price fields; (2) check that any scheduled sale dates have not already expired; (3) clear any page or object caches; (4) check for conflicting plugins that may be overriding sale prices; (5) verify the variation is not set to “Draft” or hidden status, which can prevent the discounted price from displaying.

If I use Smart Cycle Discounts to discount a variable product, do all variations get the discount?

Yes. When you add a variable product to a campaign in Smart Cycle Discounts, all variations receive the discount automatically when the campaign activates. You do not need to select or configure variations individually. The sale price displays correctly on both the product listing page and the individual product page, including the strikethrough format when a customer selects a specific variation.

What happens when only some variations of a product are on sale in WooCommerce?

WooCommerce handles partial sales by updating the displayed price range to reflect the mix. On the product page, customers will see the full regular price for unsold variations and the discounted price for sold variations after they make their selection. This can create a confusing experience β€” customers may not realize a discount exists until they select a specific option. For most promotions, discounting all variations gives a cleaner result.

The Bottom Line on Variable Products and Sale Prices

Variable products are worth understanding clearly because they behave differently from simple products at nearly every step of the discount workflow β€” from where the price is stored, to how it displays, to how you schedule and remove it.

The native tools work, but they operate at the wrong level of abstraction for running a promotional campaign. You end up managing variations when you should be managing promotions. That distinction is small when you have 3 products. It becomes the whole problem when you have 40.

If your store relies heavily on variable products β€” which most apparel, accessories, and lifestyle stores do β€” a campaign-level discount system removes the variation management entirely from your workflow. You think about which products are in the sale and when. The system handles the rest.