Shopify Still Can’t Do This: Variant Pricing That Actually Works

__TLDR_MARKER__

Shopify gives you two ways to change what a variant costs: mark it down directly, or create a discount that applies at checkout. They are not the same thing. The built-in discount builder lets you target specific variants, but selecting them requires browsing your catalog and checking boxes one at a time Shopify’s variant search only filters by title, vendor, and product type. Not by option values, price range, inventory level, or tags. Every sale you build this way, you rebuild from scratch. The selection doesn’t carry over. Shopify’s native discount engine caps each rule at 100 specifically-selected items — past that ceiling, you’re forced into static collection targeting with no condition logic.

When Shopify merchants talk about variant pricing being broken, they usually mean something specific: they want to run a promotion on certain variants, the red ones, the XL ones, the ones in a particular collection that are still in stock, and they want to set it up without spending an afternoon doing it. Shopify will let you build that discount. Getting it built is the problem. But before getting into how, it’s worth being clear on which tool you’re actually reaching for, because Shopify gives you two and merchants use them interchangeably when they shouldn’t.

Markdown vs. discount: not the same thing

When you want a variant to cost less, you have two options in Shopify.

The first is a markdown: you go into the product editor, lower the price on the variant, and optionally set a compare-at price to show the original as a strikethrough. The reduced price shows immediately on the product page. No discount code, no checkout logic. The price is just lower now, permanently, until someone changes it back. This is the right tool for clearance items, permanent price reductions, or anything where you want the sale price to live on the product page itself.

The second is a Shopify discount: you leave the variant price alone and create a discount rule that applies at checkout. The customer sees the original price on the product page, then the discount applied in the cart. This is the right tool for time-limited promotions, campaigns with codes, anything you want to schedule and expire automatically, and anything where you need Shopify’s discount stacking logic.

The confusion comes from the fact that both look like “a sale” to the customer. But markdowns are permanent edits to your product data, and discounts are separate rules that run at checkout. If you want a promo to turn off automatically on Sunday night, a markdown won’t do it. Someone has to go back and manually undo every price. If you want the sale price to show on the product page before anyone adds anything to their cart, a checkout discount won’t do it either.

Most of what the rest of this post is about is the checkout discount path, specifically why building those discounts at the variant level in native Shopify is harder than it should be.

What Shopify’s discount builder actually lets you do

When you create a product discount in Shopify, you can target specific products and variants. That part works. The issue is how you find and select them.

The workflow is: search for a product, open it, browse its variants, check the ones you want, then search for the next product. Repeat until your selection is complete. There’s no way to filter variants across your catalog by attributes that actually matter for a promotion. You can search by product title, vendor, or product type, and that’s roughly the extent of it. No option values, no price ranges, no inventory filters, no tags, no SKU patterns.

So “20% off all Size XL in my Summer collection” becomes: open the Summer collection, click into every product that has an XL, check the XL, move on. For a catalog of thirty products that’s a half hour. For three hundred it’s a day.

Why the limited search matters more than you’d expect

The variants you actually want to discount rarely map cleanly to what Shopify’s search can find. Promotions are usually more specific than “this product type” or “this vendor.” They’re things like:

  • Clear slow-moving colors before a new season comes in
  • Run a flash sale on everything in a specific price bracket
  • Discount overstocked sizes without touching everything else
  • Give a promotional rate on items that have been on sale less than 30 days

None of those conditions exist in Shopify’s built-in variant filter. You’re approximating them manually, product by product, or you’re giving up on precision and discounting more than you intended to.

There’s also no memory between campaigns. Next promo, you start the selection over. The list you built for the last sale doesn’t carry over into this one.

The workarounds merchants actually use

The standard approaches each trade one problem for another.

Collections as a targeting proxy. If you can get the right variants into a collection, you can target that collection in a discount. The problem is that Shopify’s automatic collection rules work at the product level, not the variant level. A collection built around a tag applies to the whole product, every variant, not just the size or color you wanted.

Compare-at price editing. This is the markdown path, and when it’s the right call, it’s the right call: clearance items, permanent reductions, anything where you want the sale price on the product page. Where it goes wrong is when merchants reach for it as a substitute for a real discount because building the discount is too painful. Then the sale ends and someone has to manually undo a hundred price edits.

Shopify Functions. The actual correct answer for complex discount logic at checkout, and it requires a developer to build and maintain. Not accessible to most merchants without ongoing development resources.

What rule-based targeting changes

The better model is defining conditions instead of making selections. Specify that you want variants in a particular collection, priced under $50, with inventory above zero, and let the system find every variant across your catalog that matches. Preview them before the rule goes live. Save the rule, schedule it, and run it.

When the next sale comes around, adjust the conditions or clone the rule. You’re not rebuilding the list from scratch because there was never a list to begin with. Just the logic that generates one.

There’s still the ceiling itself to deal with: Shopify’s native discount engine caps each rule at 100 specifically-selected items. A fully-selected product counts as 1, a single variant counts as 1. For a catalog with hundreds of products — or a campaign that targets a specific size or color across the whole catalog — that ceiling closes in fast. Past it, the native tools stop helping. You’re either splitting the campaign across many rules and managing them by hand, or you’re giving up the precision and discounting more than you intended.

What actually helps is lifting the ceiling, not working around it. One rule, dynamic conditions, applied across the whole catalog — with a live preview of what’s matched before you save.

This is what we built [Variant Discounts](https://apps.shopify.com/snackery-variant-discounts) to do. Built on Shopify Functions and Shopify’s Collection Sources API, one rule covers up to 100,000 variants — organized into a collection that keeps itself up to date as your catalog changes, so newly matching items are covered without touching the rule. The condition builder covers collection, tag, vendor, SKU, price range, inventory level, sale percentage, product options like color and size, and custom metafields. AND/OR logic for stacking conditions across groups. A live variant preview with a running count before you save. Discounts apply at checkout, so your product data stays exactly as you left it.

If you’ve been doing this manually, either spending the time on selection or settling for a discount that’s broader than it should be, the right starting point is your next promotion. Before you start checking boxes, try building it as a rule instead and see how many products and variants it finds in under two minutes.