Skip to content

Price compression: index your shelf out-the-door before you cut

4 min read

By BudAlly

Published Updated

Operators quoted in the trade press agree on one thing: "cutting prices too aggressively is the biggest mistake retailers make when prices fall." This is the procedure for cutting precisely instead.

The shape of the problem

US retail sales fell in 2025 for the first time on record, and the signature is everywhere: transactions up 6.5%, basket down 5.5% (Headset, year to June 2026). Michigan revenue fell 5.3% on a 2.1% unit decline. New Mexico flower went from $10.61 to $4.04 a gram in under three years. Oversupply — roughly 73M pounds of capacity against 50M of demand — means the pressure isn't going away.

Under compression, the pricing error is almost never "too high across the board." It's a handful of SKUs 15–20% above market while others sit below cost — and a blanket cut that fixes the first by destroying the second.

Step 1 — Put every price on the same basis

Competitor menus show prices three ways: pre-tax, tax-inclusive, or "as displayed" with no statement. Your own shelf price is pre-tax. Convert everything to out-the-door:

StateOTD formula (retail)Notes
Californiashelf × 1.15 × (1 + local sales-tax rate)15% excise on retail; local rate by city — Sacramento ~8.75% [verify]
Michiganshelf × 1.1610% adult-use excise + 6% sales; the 24% wholesale tax is already inside your cost
New Mexicoshelf × (1 + 0.14 + local GRT)14% excise from Jul 2026; GRT by location code; medical exempt
New Yorkper OCM potency/weight-based rulesDifferent base; compute per product [verify]

Record each competitor observation with its tax basis (pre-tax / tax-included / unknown) and convert. An "unknown" basis is excluded from the index until someone checks it.

Step 2 — Match SKUs, not names

"Blue Dream 3.5 g" at two stores can be different brands, different sizes, different forms. Match on brand + size + form; score the match; auto-accept at 0.90 and above; review 0.75–0.89; exclude below. In a 410-SKU store that typically yields 130–140 matched SKUs — enough for an index, not enough to reprice everything.

Step 3 — Index, then look at gaps by category

Basket index = your OTD basket of matched SKUs ÷ the market median OTD basket × 100. An index of 112 means you're 12% above the local median. More useful is the category split: in the demo tenant, vapes 121, concentrates 115, flower 108, edibles 104, pre-rolls 97. The problem is vapes and concentrates; flower is nearly at market; pre-rolls are already below it. A blanket 10% cut would have thrown away margin on pre-rolls and edibles and still left vapes 9% high.

Step 4 — Know the floor before you touch anything

Floor = landed cost + your margin floor (the demo uses 35%) + any state floor (New York's wholesale multiple is under verification). Landed cost includes freight and, in Michigan, the 24% wholesale tax. A proposed price below the floor is not a proposal; it's a markdown decision for a human with the reason attached.

Step 5 — Propose, approve, apply, confirm

Each proposal: SKU, current shelf → OTD, market median OTD with its source and sample size, gap, proposed shelf, margin after. Three from the demo:

SKUShelf → OTDMarket median (source, n)ProposalMargin after
Blue Dream 3.5 g$38.00 → $47.52$41.90 (licensed, 23 stores)$34.00 → $42.5257.4%
Live resin vape 1 g$45.00 → $56.28$46.90 (network, k = 14)$39.00 → $48.7753.8%
Pre-roll 5-pack$24.00 → $30.02$32.50 (licensed, 17)no change — under market—

A person approves. On a POS with a price-write API the change is drafted there; on Dutchie it becomes a task ("change it in Dutchie, then confirm") and the next sync verifies it.

Where the data must come from

  • Licensed market data — Headset or equivalent, where the license covers SKU-level internal use in your state.
  • Your own checks — a budtender visiting three competitors on Tuesday and recording prices with the tax basis. Low-tech, defensible.
  • Network medians — realized prices from state-system receipts across opted-in stores, shown only with 8 or more contributors, and never including rows from Dutchie-connected stores (its developer terms).
  • Not scraping. Weedmaps, Leafly and Dutchie menus are protected by terms of service; Dutchie's developer terms ban it outright. Scraper-built datasets carry contract risk that survives the CFAA cases, and that risk sits next to your license. BudAlly rejects uploads with scraper provenance.

The discipline

Index monthly. Reprice weekly, by category, above the floor, with a source on every figure. Cut where you're high; hold where you're at market; raise where you're below and the velocity says you can. Compression is a reason to be precise, not a reason to be fast.

BudAlly's price intelligence does steps 1–5 on any POS from licensed data, your own checks and the k ≥ 8 network — see it on a Sacramento store.

Questions

What is an out-the-door price?
The shelf price plus every tax the customer pays at the register. Comparing shelf prices across stores is misleading because some menus show tax-inclusive prices and states compute excise and sales tax on different bases; OTD puts every price on the customer's basis.
Where should competitor price data come from?
Licensed market data (for example Headset, where the license covers your state and use), your own recorded in-store checks, and anonymized network medians with enough contributors. Not from scraping Weedmaps, Leafly or Dutchie menus — their terms prohibit it and the risk sits next to your license.

See the ledger on your own data.

Free variance audit · read-only · no call.

Start free audit
© 2026 BudAlly, Inc. · Team Winston and Treez are trademarks of their owners. Posts are not legal or tax advice.All postsCompare