Suppose your store raises prices 10%. Did you make more money or lose it? Without knowing your price elasticity of demand, you are guessing. Log-log regression reduces the answer to a single coefficient: the slope of log volume on log price.
Worked Example (Simulated): Recovering a Built-In Elasticity
Question: In these simulated data, how does volume change as price changes?
Inputs: Simulated data, seed 417. The script makes 240 rows. Each row has a log price and a log volume. It sets the input elasticity to -0.800 and adds random noise with a standard deviation of 0.12. Log price is drawn at random, independent of everything else, so nothing else moves price.
Method: Fit a straight line to log volume against log price. The slope is the estimated elasticity. The interval below is an approximate 95% interval, based on the fitted line's error.
Complete Python script:
import numpy as np
seed = 417
rng = np.random.default_rng(seed)
n = 240
true_elasticity = -0.8
noise_sd = 0.12
log_price = rng.normal(0.0, 0.15, size=n)
log_volume = 5.0 + true_elasticity * log_price + rng.normal(0.0, noise_sd, size=n)
x = np.column_stack((np.ones(n), log_price))
intercept, estimate = np.linalg.lstsq(x, log_volume, rcond=None)[0]
residuals = log_volume - x @ np.array([intercept, estimate])
df = n - x.shape[1]
variance = (residuals @ residuals) / df
se = np.sqrt(variance / np.sum((log_price - log_price.mean()) ** 2))
ci_low = estimate - 1.96 * se
ci_high = estimate + 1.96 * se
volume_ratio = 1.10 ** estimate
print(f"Simulated data, seed {seed}")
print(f"Rows: {n}; input elasticity: {true_elasticity:.3f}; "
f"noise SD: {noise_sd:.2f}")
print(f"Estimated elasticity: {estimate:.3f}")
print(f"Approximate 95% interval: [{ci_low:.3f}, {ci_high:.3f}]")
print(f"At a 10% price rise, estimated volume ratio: {volume_ratio:.3f}")
change = (volume_ratio - 1) * 100
print(f"At a 10% price rise, estimated volume change: {change:.1f}%")
Printed output from running the script with python3:
Simulated data, seed 417
Rows: 240; input elasticity: -0.800; noise SD: 0.12
Estimated elasticity: -0.745
Approximate 95% interval: [-0.846, -0.644]
At a 10% price rise, estimated volume ratio: 0.931
At a 10% price rise, estimated volume change: -6.9%
Result: The estimated elasticity is -0.745, with an approximate 95% interval of -0.846 to -0.644. That interval holds the built-in value of -0.8. In this fit, a 10% price rise goes with a 6.9% drop in volume. The built-in value gives 1.10 raised to the power -0.8, which is 0.927, a 7.3% fall, so the fit is close but not exact.
Limit: These data are made by a script. Price varies at random here, so the elasticity is clean by construction. Real prices are set by sellers who respond to demand, which can bias the estimate. The example shows how the method works. It does not tell us how real shoppers respond to price changes.
What Price Elasticity Measures
Price elasticity analysis answers one question: how much does quantity demanded change when price changes? Not "will sales go up or down", everyone knows higher prices reduce volume. The critical metric is the magnitude of the response. In this illustrative contrast the elasticities -0.5 and -2.5 are assumed inputs and demand has constant elasticity, so a 10% price increase multiplies volume by 1.10 raised to the elasticity. If elasticity is -0.5 (inelastic), volume falls 4.7% and revenue rises 4.9%. If elasticity is -2.5 (elastic), the same price increase drops volume 21.2% and revenue falls 13.3%. The difference between profit and loss is the elasticity coefficient.
The method is log-log regression of log(volume) on log(price), with controls for product type, region and time where you have them. The coefficient on log(price) IS the elasticity, so no additional calculation is needed. Before you act on a coefficient, read its confidence interval and ask whether the price variation behind it is plausibly unrelated to demand.
Reading the Coefficient and Its Interval
The coefficient is the percentage change in quantity demanded for a 1% change in price. The negative sign reflects the law of demand: higher prices reduce quantity. The magnitude is what matters for pricing strategy. An absolute value below 1 is inelastic: volume falls by a smaller percentage than price rises, so revenue rises. An absolute value above 1 is elastic: revenue falls when price rises. At exactly 1 the percentage changes match and revenue is flat.
The confidence interval shows the range of elasticities consistent with the data. If the interval spans -1, the data cannot say whether demand is elastic or inelastic, and the revenue effect of a price rise could go either way. In the simulated example above the interval, -0.846 to -0.644, lies entirely on the inelastic side of -1.
The elasticity can also differ by segment. Buyers of a premium version may have different price sensitivity from buyers of a basic one, and regional markets may face different competitive pressure. An aggregate elasticity can mask this, so fit separate models by product type and region when you have enough data in each segment, and compare the intervals before you set separate prices.
Log-Price vs Log-Volume
A scatter of log(volume) against log(price) is a visual diagnostic for the model assumption: constant elasticity. A roughly straight, downward-sloping cloud supports the log-log form, and the slope of the best-fit line through the points IS the elasticity coefficient. If the relationship were curved or showed different slopes at different price levels, a single elasticity coefficient would be misleading, because elasticity would vary with price. The scatter is only a rough check, so look at the residuals as well.
The scatter also shows dispersion around the trend line. That dispersion tells you how much volume varies at a given price; it does not tell you whether price changes caused the volume changes. With observational data the slope is an association. Endogeneity is possible: high-demand weeks can push prices and volume up together, which biases the estimated price effect, and no amount of scatter around the line rules that out. Treat the coefficient as a description of how price and volume moved together, and use a randomized price test or another identification strategy before reading it as the causal demand response to your own price changes.
Observations with the same log(price) show variation in log(volume). Some of that is regional and temporal heterogeneity: some stores sell more volume at the same price because their markets are larger. The regression controls for region and year fixed effects to partial out these factors and isolate the price effect. The scatter shows the raw data; the regression coefficient shows the price effect after controlling for the confounders you included.
Seasonality and Time-Varying Demand
Demand curves shift. The elasticity coefficient represents the average slope of the demand curve across all weeks. During high-demand weeks the whole curve shifts right: consumers are willing to buy more at every price. That may give you temporary pricing power if shoppers in those weeks are less price-sensitive, but that is a hypothesis to test, not a result. A model with year fixed effects captures a trend but not week-of-year effects, so the coefficient pools across high and low demand weeks. For a more granular model, run separate regressions for high-demand weeks versus baseline weeks, or include week-of-year dummies and interact them with log(price) to estimate time-varying elasticity.
A plot of volume over time is also a rough sanity check on the data: volume that moves in a seasonal pattern without sudden unexplained jumps is what you want. If you see chaotic volatility or structural breaks, question data quality or suspect external shocks that violate the stable demand curve assumption.
What the Research Question Actually Is
Before you run price elasticity analysis, you need a clear hypothesis. The research question is not "what happens to sales if we change prices?". That's too vague. The testable hypothesis is: "What is the percentage change in quantity demanded for a 1% change in price, controlling for product type, region, and time?" The log-log regression coefficient directly answers this question with a confidence interval. If the confidence interval excludes -1, you can reject the null hypothesis of unit elasticity and conclude demand is either elastic or inelastic.
Here's what you're NOT testing: whether your specific price change will increase revenue or profit. Elasticity tells you the demand curve slope, but profit maximization also depends on your cost structure, competitive response, and strategic goals. With a constant elasticity of -1 or smaller in magnitude, the model has no interior profit-maximizing price, so you need margin data and a demand curve that allows curvature. Elasticity is an input to pricing strategy, not the strategy itself.
When Observational Data Works (and When It Doesn't)
Correlation is interesting. Causation requires an experiment. Except when it doesn't. Price elasticity analysis on observational data can approach a causal estimate only if price variation is exogenous to demand and you control for confounders, and that cannot be proven from the data alone. Price differences from supply shocks, regional competition or cost changes may help identify price effects only when the variation is plausibly unrelated to local demand. That is an argument for exogenous variation, not a demonstration of it: high-demand weeks can also raise prices, so the coefficient is best read as an association, and the causal reading needs a randomized test or another identification strategy.
A log-log regression with region fixed effects (every region has a baseline demand level), year fixed effects (national trend), and product type asks: within a region-year-type combination, when price is 1% higher, is volume X% lower? If the only reason price varies within these cells is supply shocks (exogenous to local demand), the coefficient is causal. If price varies because retailers raise prices when they anticipate high demand (endogenous), the coefficient is biased. You'd underestimate elasticity because high prices coincide with high demand weeks.
Did you randomize? For your own pricing decisions, a randomized price test is stronger. Randomly assign stores or weeks to high versus low prices and measure volume. Randomization guarantees price changes are exogenous, not correlated with unobserved demand shocks. Calculate the minimum detectable effect before you start, so the test is not underpowered.
But randomized pricing tests are expensive and slow. Observational elasticity analysis on your transaction history is fast and cheap. Use it to generate priors: if observational data suggests elasticity around -1, design your randomized test to detect differences from -1 (not from 0). Observational analysis isn't perfect, but it's a useful starting point when you have rich price-volume data with natural variation.
Common Pitfalls in Price Elasticity Analysis
- Using linear regression instead of log-log: Linear models require you to calculate elasticity as (dQ/dP) x (P/Q), which varies by price level. Log-log gives you a constant elasticity directly from the coefficient.
- Ignoring product or regional heterogeneity: Aggregate elasticity masks critical differences. Run segmented models by product type and region.
- Confusing statistical significance with practical significance: A tight confidence interval can still sit on both sides of -1, in which case it does not settle whether demand is elastic or inelastic. Focus on the economic magnitude, such as the revenue change at each end of the interval, not p-values.
- Forgetting about costs: Elasticity tells you the demand curve, not the optimal price. You need margin data to calculate revenue-maximizing or profit-maximizing prices.
- Assuming elasticity is stable over time: Demand curves shift. Re-estimate elasticity after major market changes (new competitors, economic shocks, product reformulations).
How to Interpret Your Results
Suppose you have run the log-log regression on your own data (a hypothetical result, not from the simulated example). The coefficient on log(price) is -1.63 with a 95% confidence interval of -1.89 to -1.37. What does this tell you? First, demand is elastic: |elasticity| > 1. In a constant-elasticity model, a 10% price increase lowers volume by 14.4%. Second, the confidence interval is fairly wide (0.52 units), so you are less certain about the true elasticity than in the simulated example above, where the interval was about 0.2 units wide. Third, the interval excludes -1, so you can reject unit elasticity at the 5% level. Demand is elastic, not unitary or inelastic.
What pricing decision does this support? With constant elasticity, the profit-maximizing margin follows the Lerner rule: (price - cost) / price = -1 / elasticity. With elasticity -1.63 that is 1 / 1.63 = 61%, which means price = cost x 1.63 / (1.63 - 1) = 2.59 x cost. The rule only has a finite answer when demand is elastic (|elasticity| > 1). When |elasticity| is 1 or below, with constant elasticity and a fixed unit cost, the model gives no finite optimum. If your current margin is 40% (price = 1.67 x cost), the model points to a higher price, but it extrapolates a constant-elasticity curve far from where the data sits, so treat 2.59 x cost as a direction to test, not a target. Revenue and profit move differently here: with elastic demand, revenue falls as price rises, yet profit can still rise because each remaining unit earns more margin.
The profit-maximizing price requires knowing your marginal cost. If cost is $0.60 per unit and you're selling at $1.00 (40% margin), an elasticity of -1.63 implies that a 10% price increase to $1.10 lowers volume 14.4% (a volume ratio of 0.856) but raises margin per unit from $0.40 to $0.50. Profit per unit sold rises 25%, but you sell fewer units. Net profit change: 1.25 x 0.856 = 1.07, a 7.0% profit increase (cost held fixed, elasticity assumed constant). The increase pays across the whole interval: 4.4% at -1.89 and 9.7% at -1.37. It stops paying only when demand is more elastic than -2.34. At -2.50 the same increase changes profit by -1.5%. This is why the confidence interval matters: you need to know where the interval sits relative to that break-even point before deciding.
Here's the decision framework for this example: compute the elasticity at which the move stops paying (-2.34 for a 40% margin and a 10% price increase, from solving 1.25 x 1.10 raised to the elasticity = 1). If the most elastic end of your confidence interval is still above that value, the increase pays under the model's assumptions. If that end is below it, the interval spans the decision: run a tighter experiment to narrow the confidence interval before making a large pricing change.
Setting Up Your Own Price Elasticity Analysis
You need three data columns: price, quantity, and time. Optionally add product type, region, and any other segmentation variables. Format your data with one row per observation (e.g., one row per product-store-week combination). Calculate log(price) and log(quantity) as new columns. Run the regression: lm(log_quantity ~ log_price + product_type + region + year) in R or statsmodels.OLS(log_quantity, [log_price, product_type, region, year]) in Python. The coefficient on log_price is your elasticity estimate.
Plan your sample size before you run the regression. Segmented analysis, by product type or region, needs enough observations in every segment, and the number of segments multiplies the data you need. Read the confidence interval to judge whether you have enough: a wide interval means the data cannot pin the elasticity down.
Did you randomize the price variation? If not, you're relying on observational data. Check for confounders: do prices correlate with demand shocks (e.g., higher prices during high-demand weeks)? If yes, add time fixed effects (week-of-year dummies) to control for seasonality. Do prices correlate with stockouts or promotions? Add indicator variables. The goal is to isolate exogenous price variation: price changes that aren't caused by demand shifts you're trying to measure. The cleaner your price variation, the more credible your causal estimate.
Interpret the coefficient with confidence intervals. A point estimate without a confidence interval is useless for decision-making. The 95% confidence interval tells you the range of elasticities consistent with your data. A narrow interval gives a precise estimate. A wide one, such as -2.50 to -1.70, means high uncertainty, and you should collect more data or run a tighter experiment before making pricing decisions. Report both the point estimate and the interval; ignore anyone who claims precision you don't have.
Your turn
Bring your own data and the question you actually need answered.
MCP AnalyticsData science by email Send us your data and your question, and we will reply. ds@mcpanalytics.ai
Frequently Asked Questions
Why use log-log regression instead of linear regression for price elasticity?
The coefficient on log(price) in a log-log model IS the elasticity. It represents the percentage change in quantity for a 1% change in price, exactly the definition of price elasticity. Linear models require additional calculation steps and assume constant absolute changes rather than constant percentage responses. For demand analysis, percentage changes are the economically meaningful metric. Log-log regression directly estimates what you care about: how a 10% price increase affects volume, not how a $0.10 increase affects volume (which depends on whether baseline price is $0.50 or $5.00).
What does an elasticity of -0.8 mean in practical terms?
An elasticity of -0.8 means demand is inelastic: a 1% price increase goes with a 0.8% drop in volume. In a constant-elasticity model, a 10% price increase multiplies volume by 0.927, a 7.3% drop in unit sales (the 8.0% shortcut is only a linear approximation). Revenue is the price ratio times the volume ratio, 1.10 x 0.927 = 1.019, about 1.9% higher. Whether the rise pays also depends on your costs. In the simulated example the fit gave -0.745 with an interval from -0.846 to -0.644, which holds the built-in -0.8; those data are made up and their prices vary at random by construction.
Why can an elasticity estimated from sales history be biased?
Sellers often raise prices when they expect high demand. High prices and high volume then show up together, and the estimate looks less elastic than the true response. A randomized price test avoids this, because the price change cannot follow demand. The simulated example has no such problem only because its prices were drawn at random, independent of everything else.
How much data do I need for a reliable price elasticity estimate?
You need enough variation in both price and volume, and no fixed row count fits every case. Read the width of the confidence interval instead: a wide interval means the data cannot pin down the elasticity, so collect more data or run a tighter experiment before you change prices. In the simulated example, 240 rows with a noise level of 0.12 gave an interval about 0.2 units wide. Segmented estimates, by product type or region, need data in every segment.
Can I use price elasticity analysis on observational data or do I need a controlled experiment?
You can use observational data if you have enough natural price variation and control for confounders such as seasonality, region and product type. That variation is not randomized, so the estimate is an association and unobserved demand shifts could still bias it. For causal claims about YOUR pricing decisions, a randomized price test is stronger, because it guarantees exogenous variation. Randomized tests are expensive and slow, so observational estimates are a useful starting point for designing them: if observational data suggests an elasticity near -1, design the test to detect differences from -1, not from 0.
Related Topics in Pricing Analytics
Price elasticity is one piece of the pricing strategy puzzle. Once you know your demand curve slope, you need to combine it with cost data to calculate profit-maximizing prices. You also need to consider competitive response: if you raise prices and competitors don't, your elasticity may be higher than the historical estimate because customers can now switch to cheaper alternatives. Dynamic pricing extends elasticity analysis to time-varying contexts: how does elasticity change during peak versus off-peak periods? Conjoint analysis complements elasticity by measuring willingness to pay for product features, not just overall price sensitivity.
For products with network effects or switching costs, elasticity may not be constant. Early in the product lifecycle, elasticity may be low (few substitutes, low awareness) but rise as competitors enter. After customers lock in (subscription, platform lock-in), elasticity may fall again. Elasticity analysis assumes a stable demand curve; if your market structure is changing, re-estimate it to track shifts. Cohort-based elasticity analysis (elasticity by customer tenure or acquisition channel) can reveal these dynamics.
Before we draw conclusions about optimal pricing, let's check one more thing: did you check the model assumptions? Log-log regression assumes constant elasticity (linear relationship in log-log space), no omitted variables correlated with price and volume, and homoskedastic errors. Plot residuals versus fitted values to check for heteroskedasticity. Plot log(volume) versus log(price) to visually confirm linearity. Run robustness checks: does elasticity change if you add week-of-year fixed effects? Does it change if you drop the top and bottom 5% of price observations (outliers)? If the coefficient is stable across specifications, you can trust it. If it jumps around, you have model uncertainty: report the range and design experiments to resolve it.