Cart & checkout

Products limiter: SKU vs variant vs product caps

How quantity is counted and which cap wins when SKU, variant, and product limiters overlap on the same cart line.

This is the deep companion to the Products limiter guide. It explains exactly how the app counts quantity, the precise difference between the three limiter scopes, which one wins when several could apply to the same item, and how your message text is filled in. Read this when a limit isn't firing the way you expect, or before you build anything more involved than a single per-product cap.

How quantity is counted

Before any limit is checked, the app groups your cart lines and adds up quantity per group. A group is a unique combination of product + variant. Every cart line that points at the same variant of the same product is summed into one number, and the limit is checked against that summed per-group quantity — never against the whole cart total.

This matters because a single variant can appear on more than one cart line. Shopify splits a variant into separate lines when the lines carry different line properties — for example a personalized engraving, a gift note, or a bundle tag added by another app. Those look like two rows in the cart, but for limiter purposes they are the same group and their quantities are added together.

Two separate cart lines of the same variant are summed before the cap is applied. If a shopper has one line of 2× Size 9 with an engraving and another line of 1× Size 9 without one, the limiter sees 3, not two separate quantities of 2 and 1. A max of 2 on that variant will block the cart even though no single line exceeds 2.

A few consequences of the grouping model:

  • The cap is per variant group, so the same product across different variants is counted separately (unless a higher-priority SKU rule pulls them together — see below).
  • A "max 2" limit means 2 total of that group, however many lines the shopper accumulates.
  • Quantity is only summed within a group. The app does not add a product's variants together for a product-level cap — see The three limiter scopes, which corrects a common misconception.

The three limiter scopes

Every limiter belongs to exactly one scope. Internally the app stores them in three separate maps, each keyed differently. Understanding the key is the fastest way to predict behavior.

ScopeKeyed byWhat it matches
ProductProductEach variant group of that product, checked independently
VariantVariantOnly that one variant
SKUSKU stringEvery cart line whose SKU equals the string, across all products

Product scope

A product limiter is keyed by the product. When the app evaluates the cart, it checks the product's limit against each variant group on its own — it does not add the variants together into one family total.

Common misconception: a product limit of 3 does not mean "3 of this product across all variants combined." It means "no more than 3 of each variant." A shopper can have 3 Small and 3 Medium and 3 Large — that is 9 units of the product — without breaking a product limit of 3, because each variant group is measured separately.

If you genuinely need a single combined cap across every variant of a product, a product limiter will not do it — that family-total behavior is not something the limiter supports.

Variant scope

A variant limiter is keyed by the variant. It applies to that variant only. Other variants of the same product are not counted toward it, and each variant can carry its own independent limit. This is the most common scope for "max 2 per size" style rules.

SKU scope

A SKU limiter is keyed by the SKU string. It matches every cart line whose variant SKU equals that string, regardless of which product or variant the line belongs to. If the same SKU is shared across several products (common with a generic accessory, a gift-wrap line, or a sample), all of those lines fall under the one SKU rule.

A SKU limiter is the only scope that can reach across products. Product and variant scopes are always confined to a single product.

Priority: which cap wins

A single cart line can be eligible for a SKU rule, a variant rule, and a product rule at the same time. The app does not stack them. For each variant group it picks one scope and applies only that scope's min/max:

SKU first

If the group's variant has a SKU and a SKU limiter exists for that SKU string, the SKU rule wins. The variant and product rules are ignored for this group.

Variant next

If there is no matching SKU rule, the app looks for a variant limiter on the group's variant. If one exists, it wins.

Product last

If neither a SKU nor a variant rule matches, the app falls back to a product limiter on the group's product.

Only one scope's limit applies to a given line group. A SKU limit does not combine with a variant or product limit on the same item — the higher-priority match completely replaces the others. If you want two limits to both bite, they must apply to different groups.

Worked example

Suppose all three limiters are active at once:

LimiterScopeTargetMax
AProductT-Shirt5
BVariantT-Shirt / Medium2
CSKUTS-RED1

Now trace a cart, line group by line group:

  • T-Shirt / Small (SKU TS-BLU) — no SKU rule for TS-BLU, no variant rule on Small, so the product rule A applies: max 5.
  • T-Shirt / Medium (SKU TS-GRN) — no SKU rule for TS-GRN, but variant rule B exists on Medium, so the variant rule wins: max 2. Product rule A is ignored for this group.
  • T-Shirt / Large (SKU TS-RED) — SKU rule C matches TS-RED, so the SKU rule wins: max 1. Both the variant lookup and product rule A are skipped.

Each group resolves to exactly one cap. None of the caps add together.

Minimum and maximum

A single limiter can carry a minimum, a maximum, or both. They are enforced independently against the same group quantity:

  • Minimum — the shopper must have at least that many; a smaller quantity is blocked.
  • Maximum — the shopper can have at most that many; a larger quantity is blocked.

A min violation and a max violation produce separate error messages, so you can word each case for what the shopper did wrong. If a limiter carries both and the cart breaks both at once (only possible across different groups, since one group can't be both too few and too many), each fires its own message.

Message placeholders

The message text supports three placeholders that the extension substitutes at checkout:

PlaceholderWhat it shows
{{ min_quantity }}The minimum you set on the limiter
{{ max_quantity }}The maximum you set on the limiter
{{ product_name }}The product name (see the variant note below)

How {{ product_name }} renders depends on which scope won for that line:

  • Variant-scope match — it renders as Product Title Variant Title (the product title followed by the variant title, e.g. T-Shirt Medium).
  • Product-scope or SKU-scope match — it renders as just the product title.

If you leave the messages blank, these defaults are used:

  • Minimum: You must select at least {{ min_quantity }} {{ product_name }}
  • Maximum: You can only select a maximum of {{ max_quantity }} {{ product_name }}

Placeholder format — use the plain form. Some screens and older help articles show the placeholders with a leading #, like #{{ max_quantity }}. The extension only substitutes the plain form — {{ max_quantity }}, {{ min_quantity }}, {{ product_name }} (double curly braces, no #). If you type the # version, the # and braces are printed to the shopper literally instead of being replaced with a number. When in doubt, write {{ max_quantity }}.

Edge cases

Recipes

Goal: no shopper can buy more than 2 of a hyped variant.

Create a variant limiter on that specific variant with a maximum of 2. Because it's variant scope, only that variant is capped — other sizes or colors stay unrestricted. The shopper sees your max message the moment the group quantity passes 2.

Goal: a build-your-own bundle requires at least 3 of a component identified by SKU.

Create a SKU limiter on the component's SKU with a minimum of 3. SKU scope follows the component across whichever products expose it, and the minimum blocks checkout until the shopper has 3 in that group.

Goal: a free sample can only be taken once.

Create a SKU limiter on the sample's SKU with a maximum of 1. SKU scope is the safest choice here because it catches the sample no matter which product page or auto-add added it to the cart.

Limiter or restriction?

A limiter is a pure quantity cap on one scope. If you need anything more — multiple conditions, AND/OR logic, or a rule that depends on what else is in the cart — use a Cart Restriction instead. In particular, reach for a restriction with the per-SKU quantity selector when you want quantity enforcement combined with other conditions; reach for a SKU limiter when you only need the raw cap.

Troubleshooting

SymptomLikely cause
The cap blocks at a lower count than expectedTwo cart lines of the same variant are being summed into one group.
A product limit lets through more than the numberProduct scope checks each variant separately, not a combined family total.
The wrong limit is being appliedA higher-priority scope is winning — SKU beats variant beats product, and only one applies.
The placeholder prints as literal textThe message uses the # form; switch to the plain {{ ... }} form.
A saved limiter does nothingIt has neither a min nor a max, so it was dropped at sync time.
A SKU limit isn't matching a lineThat variant has no SKU, so SKU scope can't match it.

Where to go next

On this page