How much does a price change move grocery demand?

Two years of real purchases from 2,500 households, 580 packaged products, with loyalty discounts, in-store displays and mailers. Prices do not move at random: sales coincide with promotions and shoppers stock up. Removing those biases one at a time answers when a discount pays for itself.

-1.50own-price elasticity, double ML
40%overstatement if promotions are ignored (-2.10)
+0.11last week's discount lowers this week's sales
50%+gross margin needed for a 10% cut to pay, even for beer

01Each control changes the answer

Bar chart of the elasticity under five estimators: -0.21 pooled, -2.10 with fixed effects, -1.47 with display and mailer, -1.50 with last week price, -1.50 with double ML.
Pooled OLS compares cheap and expensive products. Fixed effects compare each product with itself but credit promotions to the price. Controlling display and mailer brings the elasticity to -1.5, and double ML with flexible controls confirms it.

02Categories differ, and discounts rarely pay on their own

Horizontal bars of elasticity by category with 95% intervals: beer, frozen pizza, cookies and soft drinks around -2; bread and soup near -1 with intervals crossing it; yogurt near zero.
Impulse categories are the most elastic; staples sit near unit elasticity, and yogurt barely responds to price.

A 10% discount raises profit on the product itself only above a break-even gross margin: 50% for beer, 54% for soft drinks, 87% for bread, 96% for soup, and never for yogurt. Discounts that make sense earn their keep through traffic, basket size or supplier funding, which a product-level elasticity does not measure.