コンテンツにスキップ

Per-Product Volume Discounts in Shopify: Count the Same Product, Not the Whole Collection

By Stackable TeamPublished on July 27, 2026Discount Strategy#volume-discounts#quantity-breaks
Per-Product Volume Discounts in Shopify: Count the Same Product, Not the Whole Collection

Native Shopify volume discounts count quantity across every eligible item in the cart, not per individual product. When you set a minimum-quantity discount on a collection, Shopify adds up all the qualifying units together, so a customer who buys 2 of one product and 1 of another can trigger a tier you meant for buying 3 of a single item. To count the same product or the same variant on its own, you need per-product counting, which native Shopify discounts do not offer. You get it from an app that lets you choose what counts as "the same product" before the tier math runs.

This guide explains exactly how native quantity discounts count, the three counting modes (per-variant, per-product, and per-group) in plain English, why collection-pooling hands out discounts you never intended, how minimum-order-quantity pricing works, and a full worked example with dining-chair tiers counted per chair. You will finish knowing which counting mode fits each promotion and how to set it up so the tier a customer sees is the tier they actually pay.

How do native Shopify volume discounts count quantity?

Shopify's native discount builder can absolutely create a volume discount. You choose "Amount off products," scope it to a product or a collection, and add a minimum quantity of items as the purchase requirement. That part works. The problem is not whether you can build a tier. The problem is what the tier counts.

When you set a minimum quantity, Shopify treats it as a threshold against the total of all qualifying items in the cart. According to Shopify's developer documentation, the DiscountMinimumQuantity object "specifies the minimum item quantity required for discount eligibility" and "this threshold applies to qualifying items in the customer's cart." The example Shopify gives is a "Buy 3, Get 10% Off" promotion that sets the minimum quantity to 3 items. Nothing in that rule says three of the same item. It says three qualifying items, full stop.

The same pooling shows up in Buy X Get Y. Shopify's DiscountOnQuantity object powers tiered "buy more, save more" effects, and Shopify describes it with a mix-and-match example: "Buy 4 candles, get 2 candles 50% off (mix and match)." Mix and match is the giveaway. The four candles that unlock the deal can be any four candles in the eligible set. They do not have to be the same candle. And the prerequisite items in a Buy X Get Y discount can be, per the DiscountCustomerBuysInput documentation, "either collections or products," with a single quantity value covering the whole set.

So the native behavior, verified against shopify.dev, is consistent across discount types: the quantity threshold counts every eligible line item together. Scope the discount to a collection and the entire collection feeds one shared number. That is fine for a store-wide "spend more, save more" push. It is wrong for "buy more of this specific product."

IMAGE PLACEHOLDER (Image 1): How native counting pools a collection
Suggested visual: A clean 16:9 diagram on a white background. Left side shows a cart with three different chair products, quantities 2, 1, and 1, each a distinct silhouette in slate gray. A large violet arrow labeled "native minimum quantity: counts all qualifying items" points to a single pooled counter reading "4 units to one shared threshold." A small red flag reads "not 4 of the same chair." Flat vector style, brand colors violet and gold, sans-serif labels, no photography.

Why the collection scope makes this worse, not better

Merchants reach for a collection because it feels like the right container. "I sell five dining chairs, I will put them in a Chairs collection and set the discount there." It is the intuitive move, and it is the exact move that breaks the intent.

Once the discount is scoped to that collection, Shopify does not distinguish between the five chairs inside it. Every unit of every chair counts toward the same threshold. Add a product to the collection later and it silently joins the count too. Merchants on the Shopify forums describe this precisely: they want tiers "per specific chair, no combining across products," and Shopify support confirms native discounts cannot "count same products only." The collection is a filter for eligibility, not a boundary for counting.

What are the three counting modes?

Every quantity-based discount has to answer one question before it does any math: what counts as "the same product"? There are three sensible answers, and the right one depends entirely on the promotion. Naming them explicitly is the whole game, because native Shopify only ever gives you the widest one.

Per-variant: count the exact SKU only

Per-variant counting treats each variant as its own island. A large tee and a medium tee of the same style count separately, toward separate thresholds. A3 and A4 sizes of the same poster never pool.

Use per-variant when your variants are effectively different products for pricing purposes. Print sizes that cost genuinely different amounts to produce, materials that carry different margins, or anything where "5 of this exact SKU" is the real unit of the deal. If a customer should not be able to reach a tier by mixing sizes, per-variant is the mode that enforces it.

Per-product: count every variant of one product together

Per-product counting is the one most merchants actually mean when they say "buy more of this item." Every variant of a single product page counts toward the same tier. All sizes and colors of one tee style add up together, but a different tee style does not contribute.

This is the sensible default for volume tiers. A furniture merchant selling one dining chair in four finishes wants all four finishes to count as "the chair," because to the customer they are the chair. Two oak plus two walnut is four chairs, and it should hit the four-chair tier. Per-product gets that right while still refusing to count a completely different chair model.

Per-group counting lets you nominate a specific, explicit set of products that should share one threshold. A "starter kit" of a cleanser, a toner, and a moisturizer can count together, so any three units drawn from that trio unlocks the deal, without dragging your entire catalog into the count.

Per-group is the closest mode to Shopify's native collection behavior, and that is the point. Use it deliberately when you genuinely want a mix-and-match pool, like a store-wide "any 6 items, 10 percent off" promotion. The difference from native is that you are choosing the pool on purpose, item by item, rather than inheriting it by accident from whatever happens to sit in a collection.

The one mental model to hold onto: native Shopify only offers something like per-group, scoped to a collection, whether you wanted it or not. Per-variant and per-product are the two modes native counting cannot express, and they are the two most merchants actually need.

Why does collection-pooling give customers the wrong discount?

Here is the concrete failure, and it cuts both ways.

First, it triggers too easily. You meant "buy 3 of this chair, get 15 percent off." A customer adds one of each of three different chairs, hits the shared threshold of 3, and gets 15 percent off all three. That is not the loyalty behavior you were pricing for. You wanted to reward commitment to one product. Instead you discounted a browse-y sampler cart, and you handed away margin on units that were never going to move together at volume.

Second, and less obvious, it can under-reward the customer you did want. If your tiers escalate (3 to 5 units at 15 percent, 6 to 9 at 18 percent, 10 or more at 20 percent) and the count pools across a whole collection, the math gets muddy fast. A wholesale buyer taking 10 of one chair sits in the same pooled bucket as a retail shopper grabbing 2 of three different chairs. You cannot cleanly price a per-product bulk tier when the counter does not know which units belong to which product.

Third, it is fragile to maintain. Because the collection defines the count, editing the collection edits the promotion. Add a seasonal chair to the Chairs collection and every buyer of that new chair now contributes to, and benefits from, a tier you designed months ago for different products. Nothing errors. The discount just quietly starts behaving differently. Silent drift like this is the same class of problem that makes merchants distrust discount tooling in the first place: the cart still shows a number, it is just the wrong number.

The fix is not a cleverer collection. It is counting per product so the threshold means what you thought it meant.

What is minimum-order-quantity (MOQ) pricing, and how does per-product counting enable it?

Minimum-order-quantity pricing is the wholesale and bulk pattern where a product simply is not available, or is not discounted, below a floor quantity, and then earns a set rate above it. "No trade price under 12 units. At 12 or more, this unit price." It is how a lot of B2B and made-to-order catalogs work.

MOQ pricing lives or dies on per-product or per-variant counting, because the floor has to mean "12 of this thing," not "12 of anything in the category." If the count pools across a collection, a buyer assembles 12 mixed units and claims a wholesale rate on a retail order. That is the opposite of what MOQ is for.

With per-variant counting, MOQ becomes exact: no discount below 12 units of the same SKU, then a fixed unit price override at 12 and up. Retail buyers under the floor pay full price. Bulk buyers cross the floor on a single product and automatically pick up the wholesale unit price, with no separate price list to maintain and no draft-order workaround. The counting mode is doing the enforcement, which is why getting the mode right matters more than the tier numbers.

Worked example: dining-chair tiers counted per chair

Let us make this concrete with the exact scenario merchants keep describing on the forums. A furniture store sells several dining-chair styles and wants a per-chair volume deal on one of them:

  • 3 to 5 chairs: 15 percent off
  • 6 to 9 chairs: 18 percent off
  • 10 or more chairs: 20 percent off

The intent is strict. The tier should count that one chair (all finishes together), it should require a minimum of 3 to start, and it must not pool with the other chair styles in the collection. Here is how the same cart resolves under native collection-pooling versus per-product counting.

Look at rows three and four. Those are the cases that separate a promotion that works from one that leaks margin. Under native pooling, four unrelated units can unlock a tier meant for buying four of one chair. Under per-product counting, only genuine commitment to that chair (in any finish) reaches the tier, exactly as intended. The bulk rows still work perfectly, because per-product counting adds every finish of the chair together before it checks the threshold.

This is also where the minimum of 3 does its job cleanly. Because the count is per product, "at least 3 of this chair" is unambiguous. There is no way to satisfy it with a spread of one-off items, which is precisely the loophole collection-pooling leaves open.

IMAGE PLACEHOLDER (Image 2): Same cart, two counting modes, two totals
Suggested visual: A 16:9 split-panel illustration. Left panel labeled "Native: pooled across collection" shows a cart of four different chairs with a green 15 percent badge and a small red warning "unintended tier." Right panel labeled "Per-product: counts the same chair" shows the identical four-different-chairs cart with no discount and a calm gray "no tier, as intended" note. Below, a second row shows four of the same chair earning 15 percent in both panels. Brand colors violet and gold, flat vector, no photography.

How to set up per-product volume discounts, step by step

You can build a pooled volume discount natively in a few minutes. What native cannot do is choose the counting mode, so per-product and per-variant tiers need an app that exposes counting as an explicit setting. Here is the reliable sequence, whichever route you take.

1. Decide what "the same product" means for this promotion

Before you touch any builder, write the sentence out. "Buy more of this exact SKU" is per-variant. "Buy more of this product in any variant" is per-product. "Buy any mix from this specific set of items" is per-group. This one decision determines everything downstream, and it is the decision native Shopify makes for you (always the widest one).

2. Choose the counting mode explicitly

In a tool that supports it, set the counting mode first, not last. Per-product is the safe default for a "buy more of this item" tier. Switch to per-variant when different variants are genuinely different products for pricing, like print sizes or materials. Reserve per-group for deliberate mix-and-match pools, and pick the members by hand.

3. Set your tier breakpoints

Add the quantity-and-discount pairs your strategy needs: 3 to 5, 6 to 9, 10 or more, each with its own percentage or fixed amount. For MOQ pricing, make the first tier start at your floor (for example, 12 or more) and leave everything below it at full price. A fixed unit-price override, rather than a percentage, is often the cleaner expression of a wholesale rate.

4. Scope the offer to the right product or set

Attach the tiers to the specific product for per-product, or the specific variant for per-variant. If you are using per-group, this is where you nominate the members. Keep the scope tight. The counting mode already handles what pools together, so you do not need a sprawling collection to make it work.

5. Show the tiers on the product page

A quantity discount the customer cannot see is a quantity discount that does not convert. Display the tier table on the product page so shoppers can see the next breakpoint and the saving. The table should update live as they change quantity, with no page reload, and the highlighted tier should always match what checkout will charge.

6. Test a should-apply and a should-not-apply cart

Build a cart that buys enough of the one product to hit each tier, place a draft or test order, and read the checkout summary line by line to confirm the right tier fired. Then build the trap cart: a spread of different products that would trigger a pooled discount but should trigger nothing under per-product counting. Confirm it stays at full price. Silent failures are the enemy here, because a discount that fires wrongly never throws an error either.

IMAGE PLACEHOLDER (Image 3): The counting-mode selector
Suggested visual: A 16:9 product screenshot mockup of the Stackable campaign editor Counting step. Show three selectable options labeled "Per variant, count the exact SKU," "Per product, count all variants of one product" (selected, violet highlight), and "Per group, count a hand-picked set," each with a one-line plain-English preview sentence beneath. Clean Shopify Polaris admin styling, brand accent in violet. Reference the docs/screenshot-manifest.md slot volume-discounts-step-1 to capture the real screen later.

Run this reliably with Stackable

If you want per-product or per-variant tiers, native Shopify cannot express them, and this is exactly the gap Stackable was built to close, honestly and within Shopify's real rules.

  • Stackable gives you the counting mode as an explicit choice: per-variant, per-product, or per-group, so the threshold counts what you actually meant instead of pooling a whole collection by default.
  • Tiers hold from cart to checkout because the math runs inside a Shopify Function, so the price a shopper sees on the product page is the price they pay at checkout, including on Shop Pay and other accelerated checkouts.
  • The storefront tier table updates live as the customer changes quantity, with no page reload, highlighting the active tier so the next breakpoint is always visible.
  • Stackable never rewrites your product prices. The tiers exist only as checkout adjustments, so uninstalling leaves your catalog exactly as it was.

Install Stackable free and set a per-product tier that counts the right item, from cart to Shop Pay, at usestackable.com/pricing. 🚀

The bottom line

  • Native Shopify volume discounts count the minimum quantity across all qualifying items in the cart, not per product, so unrelated items can trigger a tier meant for one product.
  • Scoping to a collection makes this worse: every product in the collection feeds one shared threshold, and adding a product later silently changes the promotion.
  • Three counting modes cover every case: per-variant (exact SKU), per-product (all variants of one product), and per-group (a hand-picked set). Native Shopify only offers something like per-group, scoped to a collection.
  • Per-product is the right default for "buy more of this item." Per-variant enforces exact-SKU tiers and MOQ floors. Per-group is for deliberate mix-and-match pools.
  • Collection-pooling costs money in both directions: it triggers too easily for browse-y carts and cannot cleanly price a per-product bulk tier.
  • Always test a should-apply cart (enough of one product) and a should-not-apply cart (a spread of different products), and read the checkout summary line by line.
  • Tools like Stackable expose the counting mode explicitly and run the tier math in a Shopify Function, so the tier a shopper sees is the tier they pay, from the product page to Shop Pay.

よくある質問

よくある質問への回答

  • Across the collection. According to Shopify's documentation, a minimum-quantity discount applies its threshold to all qualifying items in the cart, not to a single product. Scope the discount to a collection and every product inside it feeds one shared count. That means a customer can reach a "buy 3" tier with three different items, which is rarely what a per-product volume deal intends.

  • Per-product counting adds up every variant of one product page toward the same tier, while ignoring other products. All sizes and colors of a single tee style count together, but a different tee style does not contribute. It matches how most merchants think about "buy more of this item," and it is the mode native Shopify cannot express on its own.

  • Per-product counts every variant of one product together, so mixing sizes or finishes of the same item still builds toward one tier. Per-variant counts only the exact SKU, so a large and a medium of the same style each build their own separate threshold. Use per-variant when different variants are effectively different products for pricing, like print sizes or materials.

  • Not with native discounts. Shopify support confirms native discounts do not support "count same products only," because the quantity threshold pools every qualifying item in the cart. To count one product (or one variant) on its own, you need an app that lets you set the counting mode explicitly before the tier math runs.

  • Because the discount is scoped to a collection and Shopify pools the quantity across it. If your tier says "buy 3, get 15 percent off" on a collection, three different products from that collection satisfy the threshold together. The customer never bought 3 of one item; they bought 3 items total. Per-product counting removes that loophole.

  • Make your first tier start at the floor quantity, for example "12 or more," and leave everything below it at full price. Crucially, count per product or per variant so the floor means "12 of this item," not "12 of anything in the category." A fixed unit-price override above the floor is usually the cleanest way to express a wholesale rate without a separate price list.

  • Use per-group when you genuinely want a mix-and-match pool, like a store-wide "any 6 items, 10 percent off" promotion or a starter kit of three specific products that share one threshold. It is the closest mode to native collection behavior, but you pick the members on purpose, item by item, instead of inheriting whatever happens to sit in a collection.

  • Yes. The same counting question applies to every quantity-based offer: volume tiers, BOGO, and quantity breaks all read from the same per-variant, per-product, or per-group logic. Native Buy X Get Y is explicitly mix-and-match, so its prerequisite quantity pools across the eligible set. If you need "buy 3 of the same product to unlock," you need per-product counting there too.

  • It should, as long as the tier math runs server-side. When a discount is built on Shopify Functions, the same calculation runs on the product page, the cart, and the checkout, including accelerated checkouts like Shop Pay, so the price cannot drift between preview and charge. Tiers that rely on theme JavaScript can show one number and charge another.

  • With native collection-scoped discounts, yes, and silently. Because the collection defines what counts, adding a product to it enrolls that product in the promotion and lets its units feed the shared threshold. Nothing errors; the discount just starts behaving differently. Counting per product avoids this, because the tier is attached to a specific item, not to whatever a collection contains.

  • There is no practical limit worth worrying about. Most merchants use three to five tiers (a common shape is 3 to 5, 6 to 9, and 10 or more), which is enough to reward escalating commitment without overwhelming the shopper. Add as many quantity breakpoints as your pricing strategy genuinely needs, each with its own percentage or fixed amount.

  • No. Per-product and per-variant counting are about how a single quantity discount counts, which works on every Shopify plan through a Functions-based app. Shopify Plus is only required for a different feature, stacking two product discounts on the same cart line. Counting the same product toward one tier does not need Plus.

Stackable Team

The team building Stackable, the reliability-first bulk and volume discount app for Shopify. We write about discount stacking, Shopify Functions, and how to run promotions that hold up at checkout.

本サイトの運営には必須Cookieを使用しており、お客様の同意をいただいた場合のみ、アクセス状況を把握するための分析Cookieを使用します。詳細は Cookieポリシー.