Difference in differences: the estimator behind most marketing tests

Compare how much the treated group changed with how much the untreated group changed. It's the simplest causal estimator you'll use, and the one most likely to be quietly wrong.

Mike Taylor By Mike Taylor · Updated · 6 min read

Difference in differences (DiD, or diff in diff) estimates the effect of a change by comparing how much a treated group moved before and after the change with how much an untreated comparison group moved over the same period. The comparison group’s change stands in for what would have happened to the treated group anyway, so subtracting it strips out the trend, seasonality and anything else that hit both groups, and what’s left is your estimate of the effect.

It’s the estimator behind most marketing experiments that aren’t user-level A/B tests: the geo lift test where some regions get extra spend, the matched market test for a TV campaign, the launch in one country before another, the price change in some stores but not others. It’s also one of the oldest tools in causal inference, and its most famous application is economics rather than marketing: David Card and Alan Krueger’s 1994 study compared fast-food employment in New Jersey, which raised its minimum wage in 1992, with neighboring eastern Pennsylvania, which didn’t. I’ll show you the formula first, then the assumption it rests on and the ways it breaks in marketing data.

The difference in differences formula

The simple two-group, two-period version needs four numbers: the treated group’s average before and after, and the comparison group’s average before and after. The estimate of the treatment effect is the treated group’s change minus the comparison group’s change:

τ^DiD=(YˉT,post−YˉT,pre)−(YˉC,post−YˉC,pre)\hat{\tau}_{DiD} = \left(\bar{Y}_{T,\text{post}} - \bar{Y}_{T,\text{pre}}\right) - \left(\bar{Y}_{C,\text{post}} - \bar{Y}_{C,\text{pre}}\right)

In the course’s invented Northstar case, the campaign region rises from £100,000 to £135,000 and a similar comparison region rises from £100,000 to £120,000 without the campaign. The campaign region’s before/after change is £35,000, but £20,000 of that also happened where there was no campaign, so the DiD estimate is £15,000. Equivalently, you can think of it as building a counterfactual for the treated region (its pre-period level plus the comparison group’s change, £120,000 here) and measuring the gap between that and what actually happened.

With more regions and more weeks, the same estimate comes out of a regression with a fixed effect for every unit (which absorbs permanent differences in size), a fixed effect for every period (which absorbs shocks common to everyone), and a dummy DitD_{it} that’s one for treated units in the post-period:

Yit=αi+λt+τDit+εitY_{it} = \alpha_i + \lambda_t + \tau D_{it} + \varepsilon_{it}

This is called two-way fixed effects (TWFE), and when every treated unit starts at the same time it gives exactly the same answer as the four-means calculation. On the course’s 12-region geo dataset, both report 9. The regression form is handy because it gives you standard errors (cluster them by region, since weeks within a region aren’t independent), lets you add controls, and extends naturally to the event study below.

DiD doesn’t assume the two groups are the same. A big region and a small one are fine, because the unit fixed effects (or the before/after subtraction) remove level differences. What it does assume is that, without the treatment, the treated group would have changed by the same amount as the comparison group. That’s the parallel trends assumption, and it’s untestable in the strict sense because you never see the treated group’s untreated path after launch.

In marketing, parallel trends breaks in some predictable ways. The most common is selection: you put the campaign in the regions that were already growing (or the ones the regional manager lobbied for), so the treated group was on a steeper path before you touched it. The opposite also happens, where you pick the regions that had a bad quarter, and they bounce back on their own (regression to the mean). Different seasonality is another, such as coastal regions that peak in summer compared with inland ones, as are local shocks like a store refit, a competitor closing or a regional promotion. A local event in one treated region isn’t removed by subtracting a shared trend, which is exactly the extra one unit in the geo dataset’s DiD of 9 against a true effect of 8.

The calculator below lets you break the assumption on purpose. The violation slider says “without the campaign, the treated group would have changed by this much more than the comparison group”, and the bias in the DiD estimate is exactly that amount, one for one. Switch to weekly mode and the calculator also estimates the drift from your own data by fitting a line to the pre-period gap between the groups.

Interactive
Difference-in-differences calculator

Type four means, or paste a weekly series for your test and control groups. Then break the parallel-trends assumption on purpose and watch the estimate drift away from the truth.

DiD estimate
15
True effect, given the violation
15
Bias in the estimate
0

DiD = (treatment post − treatment pre) − (control post − control pre). The violation slider assumes the treatment group would have changed by that much more than control without the campaign, so the true effect is the DiD estimate minus the violation. Weekly mode fits a straight line to the pre-period gap to estimate the drift. Default numbers come from the course's invented examples.

The point of the slider is to make you put a number on your worry. If a plausible violation is two units and your estimate is 15, the conclusion survives; if a plausible violation is ten, the test hasn’t told you much yet. In my experience, this is a much more productive conversation to have with a finance team than arguing over whether a p-value is below 0.05, because it’s about the business story of why the regions might have diverged.

Event-study plots: checking the pre-period

An event-study plot shows the gap between treated and comparison groups period by period, relative to the launch date, usually as regression coefficients with confidence intervals and the last pre-launch period as the reference point. Before launch the coefficients should hover around zero with no slope; after launch they show how the effect builds, holds or fades. The “Diverging pre-trends” example in the weekly mode of the calculator shows what a problem looks like: the gap is already climbing before launch, and a naive DiD credits that climb to the campaign.

Flat pre-trends are reassuring, but they aren’t proof. A test can have perfect pre-period alignment and still be ruined by something that happens only in the post-period. Jonathan Roth’s 2022 paper “Pretest with Caution” also showed that standard pre-trend tests often have low power to detect violations, and that only reporting estimates which pass such a test can bias them, so treat the plot as evidence to weigh rather than a gate to pass. (His 2023 survey with Pedro Sant’Anna, Alyssa Bilinski and John Poe is the best single overview of the recent literature if you want to go deeper.) The post-launch shape matters for marketers too: if the effect is still rising at the end of your test window, you’ve probably undercounted the carryover, and if it decays to zero within a week, a longer test won’t help.

Staggered rollouts and the two-way fixed effects trap

Marketing launches are often staggered: a new channel goes live in three markets in March, five more in May and the rest in September. The tempting analysis is the TWFE regression above with a treatment dummy that switches on at each market’s own launch date. However, research over the last few years has shown that this regression can give misleading answers when effects change over time or differ between launch groups, which in marketing they almost always do.

Andrew Goodman-Bacon (2021) showed that the TWFE estimate is a weighted average of every possible two-group, two-period comparison in the data, and that some of those comparisons use already-treated markets as the control group for newly treated ones. If the early markets’ effect is still growing, their change gets subtracted from the later markets’ change, which can drag the average down and, in extreme cases, flip its sign. Brantly Callaway and Pedro Sant’Anna (2021) proposed estimating a separate effect for each launch cohort in each period, using only not-yet-treated or never-treated markets as comparisons, and then averaging those with weights you choose; their R package did implements it. Liyang Sun and Sarah Abraham (2021) showed the same contamination problem affects event-study regressions and proposed an interaction-weighted fix. The practical upshot is simple: if your treatment starts at different times in different units, use one of these estimators (or keep a clean never-treated group and analyze each cohort separately) rather than the textbook regression.

# Callaway & Sant'Anna: one effect per launch cohort and period, then aggregated
library(did)
out <- att_gt(yname = "sales", tname = "week", idname = "market_id",
              gname = "launch_week",   # 0 for markets never treated
              data = panel, control_group = "notyettreated")
es <- aggte(out, type = "dynamic")    # event-study style aggregation
ggdid(es)

How marketers use difference in differences

Geo tests are the obvious use, and on the geo lift testing page I work through the course dataset where a treatment-only before/after says 17, DiD says 9 and the known effect is 8. DiD is also how most people read a launch: a new store, a new market, a feature released on one platform first, or a rebrand in one country. It works for “off” tests too, where you pause a channel in some regions to see what it was really contributing, which is often the cleanest way to check an incrementality claim from a platform.

A few practical habits make these readouts much more trustworthy. Use as long a pre-period as you can and plot it before you compute anything. Pick the comparison group before you see post-period data, and write down why. Report the result as an incremental number with an interval and an implied iROAS, not just a percentage lift, so it can be compared with your marginal ROAS from other sources. With only a handful of regions, the usual clustered standard errors are unreliable, so a placebo check (pretend each comparison region was treated and see how often you get an effect as big as yours) is a good sanity test; the same idea is central to synthetic control, which is the natural next step when no comparison group trends like your treated unit. Before you run anything, use the statistical power calculator to check that the test can detect an effect worth acting on.

py
DiD and event-study script (Python)2x2 DiD, two-way fixed effects with region-clustered standard errors, and an event-study regression with the last pre-launch week as reference.
Download

DiD results are also some of the best evidence for anchoring a marketing mix model, because they come from a deliberate change rather than whatever variation happened to be in the historical data. The calibration page shows how to combine a test result with a model estimate, and the MMM course has a lesson where a competitor closure in the campaign region shows you, interactively, what a comparison group can and can’t remove.

Downloads

py
DiD and event-study script (Python)2x2 DiD, two-way fixed effects with region-clustered standard errors, and an event-study regression. Runs on the geo dataset or your own panel.
Download
csv
Geo experiment dataset (CSV)The 12-region synthetic geo test the script and calculator use.
Download

Frequently asked questions

What is difference in differences in simple terms?

Difference in differences measures the effect of a change by comparing how much a treated group moved before and after the change with how much an untreated group moved over the same period. Subtracting the untreated group's change removes trends and seasonality that hit both groups, leaving an estimate of the effect of the change itself.

What is the parallel trends assumption?

Parallel trends is the assumption that, without the treatment, the treated group would have changed by the same amount as the comparison group. It can't be tested directly because the treated group's untreated path is never observed, but a long pre-period in which the two groups moved together makes it more plausible.

How is difference in differences used in marketing?

Marketers use it to read geo tests, where some regions get extra spend and others don't, and to estimate the effect of launches, price changes, store openings or new channels rolled out in some markets before others. It is also the logic behind most simple matched market test readouts.

What is the difference between difference in differences and synthetic control?

Difference in differences gives every comparison unit equal weight and assumes the treated group would have followed the comparison group's average change. Synthetic control instead chooses weights for the comparison units so their blend tracks the treated unit closely before the change, which helps when no single comparison group trends like the treated one.

Can I use difference in differences with a staggered rollout?

Yes, but not with a naive two-way fixed effects regression if effects change over time or differ by group. Recent research, including Goodman-Bacon (2021) and Callaway and Sant'Anna (2021), shows that the standard regression can compare newly treated units with already-treated ones and produce misleading averages, and offers estimators that avoid those comparisons.

References

  1. Card & Krueger (1994), Minimum Wages and Employment: A Case Study of the Fast-Food Industry in New Jersey and Pennsylvania American Economic Review 84(4), 772-793. The classic two-state DiD.
  2. Goodman-Bacon (2021), Difference-in-differences with variation in treatment timing Journal of Econometrics 225(2), 254-277. Decomposition of the TWFE estimator.
  3. Callaway & Sant'Anna (2021), Difference-in-Differences with Multiple Time Periods Journal of Econometrics 225(2), 200-230. Group-time average treatment effects; implemented in the R package did.
  4. Sun & Abraham (2021), Estimating dynamic treatment effects in event studies with heterogeneous treatment effects Journal of Econometrics 225(2), 175-199.
  5. Roth (2022), Pretest with Caution: Event-Study Estimates after Testing for Parallel Trends American Economic Review: Insights 4(3), 305-322.
  6. Roth, Sant'Anna, Bilinski & Poe (2023), What's trending in difference-in-differences? Journal of Econometrics 235(2), 2218-2244. Survey of the recent literature.
  7. did: Treatment Effects with Multiple Periods and Groups (CRAN) Version 2.5.1, July 2026, by Callaway and Sant'Anna.
Mike Taylor
Mike Taylor

I've built marketing mix models for Monzo Bank, Booking.com, Time Out, The AA and others, advised Google, Appsflyer and Recast on MMM, and teach marketing mix modeling on LinkedIn Learning. Before that I co-founded a 50-person growth marketing agency. I write the Vexpower MMM course.

Keep reading

Learn MMM by doing itThe Vexpower course walks through thirty lessons on one invented brand, with simulators, Python labs and a decision case you can defend.
See the course