Marketing Mix Modeling

Why Robyn Shows Zero or Negative Paid Search ROI and What to Check

Robyn floors paid search coefficients at zero by default, so a negative ROI points to a setting. An ordered checklist of causes with the Robyn setting behind each fix.

On this page

When a Robyn model shows negative ROI for paid search, look at the sign setting before anything else, because Robyn's defaults cannot produce that number. Paid media coefficients are floored at zero unless someone changes paid_media_signs, and Robyn's analyst guide defines ROI as the incremental revenue a channel drives divided by what was spent on it, so on a revenue KPI a channel that only loses money lands between 0 and 1. A negative figure means a setting was changed. The more common complaint, a search line pinned at exactly zero, means the fit had nowhere lower to go. Both trace back to the same short list: search spend that follows demand, overlap with branded terms and promotions, and adstock or saturation ranges that do not suit search. Each fix sits in a named Robyn setting, and the last one is an incrementality test.

How Robyn's positive and negative sign constraint works

In Robyn's marketing mix modeling, the sign constraint gives every coefficient one of three settings: "positive", "negative" or "default". You set it per variable in robyn_inputs(). According to Robyn's input documentation, paid_media_signs and organic_signs default to "positive", while context_signs defaults to "default". The analyst guide explains that a variable left on "default" can take a positive or a negative coefficient depending on the modeling result, and that the other two settings are for when it makes sense to assume the direction in advance, such as competitor sales pulling your own sales down.

Robyn's model code shows how literal the constraint is. For context, paid media and organic variables, each sign becomes a lower and an upper limit handed to the ridge regression: "positive" sets the lower limit to 0, "negative" sets the upper limit to 0, and "default" leaves both ends open. A "positive" coefficient can shrink all the way to zero and no further.

What a negative coefficient on paid search is telling you

A paid search negative coefficient in Robyn points to one of two things. Either paid_media_signs was set to "default" or "negative" for that channel, or a search series such as branded clicks was entered under context_vars, where the sign stays open unless you close it. Confirm which one you have before reading anything into the number.

Zero deserves the same reading. Robyn's feature documentation says the team chose ridge over lasso because lasso tends to "zero-out" features while ridge reduces their magnitude. An exact zero on a media channel is therefore, in our reading of the code, the lower limit doing its job: with the bound removed, the fit would have put search at or below zero. Robyn leans against that outcome by default, too. With rssd_zero_penalty = TRUE, DECOMP.RSSD is inflated for models carrying zero-effect media; the documented example is a model with 50% zero-coefficient variables penalized at DECOMP.RSSD times 1.5.

A cheap diagnostic is to rerun with search on "default" and look at the sign and size of what comes back, keeping the constrained model for reporting. Take a hypothetical run in which every number is invented for illustration. A retailer models 104 weeks with one search column at $20,000 a week, $2,080,000 in total. On defaults, search returns a coefficient of 0 and an ROI of 0. With the sign opened, it returns a contribution of -$312,000, an ROI of -0.15. Read together, the two runs say the model cannot separate search from the weeks it spends hardest in; neither is evidence that search destroys revenue.

The order to troubleshoot in

Robyn MMM negative ROI troubleshooting goes faster in a fixed order, cheapest check first, and each row below names the Robyn setting behind the fix.

StepWhat to checkRobyn setting behind the fix
1Is the number negative or exactly zero? Negative means the sign is open.paid_media_signs, or a search series placed in context_vars
2Is there enough data? Robyn's analyst guide recommends a ratio of 10 observations to 1 independent variable.window_start and window_end
3Has the optimizer had enough runs?trials and iterations in robyn_run(), defaults 5 and 2,000
4Does search spend follow demand?prophet_vars, plus a demand series in context_vars
5Is brand mixed with non-brand, or search with promotions?Separate columns in paid_media_spends; a promotion flag in context_vars
6Do the adstock and saturation ranges fit search?hyperparameters: thetas, alphas and gammas
7Is there an experiment to anchor the answer?calibration_input

The three usual causes and the fix for each

The causes of a negative or zero paid search ROI in Robyn MMM, and the fix for each, come down to three patterns in the data, and more than one can be present in the same model.

Search spend that follows demand

Google's Meridian documentation (last updated September 24, 2026) describes the mechanism in one sentence: "When inherent demand is high, organic query volume will also be high, and so the total spending on search ads will be high." The same page warns that failing to control for query volume can lead to overestimation of the causal effect of paid search. In our reading, this cause can inflate search or flatten it, depending on what else is in the model.

In Robyn, the Prophet terms (trend, season, holiday) and your context variables carry baseline demand. When search spend rises and falls with them, the regression has two explanations for the same weeks, and the analyst guide warns that a model has difficulty calculating the impact of each variable when they are highly correlated. As we read it, the credit can land on search in one Pareto candidate and on the baseline in the next.

Meridian's remedy is to add Google query volume as a control. We found no dedicated query-volume input in robyn_inputs(), so the nearest equivalent is a brand or category search-interest series under context_vars, left on "default". Expect the search number to move in either direction once demand has its own column.

Overlap with branded terms and promotions

Branded search is the sharpest version of the demand problem, since the query already contains your name. Meridian's guidance is to model brand-specific and generic campaigns as separate media channels. Two Robyn contributors gave related advice in a March 2021 issue thread about a "google search brand" variable stuck at zero: split brand into more granular variables, or try different channel aggregations. Splitting has a price, because each new column counts against the 10 observations per variable.

Promotions overlap in the same way. The analyst guide treats promotions as non-media inputs, entered as pricing series or dummy variables. Search budgets often climb in promotion weeks, so a promotion flag on an open sign competes with search for exactly those weeks, and leaving the flag out lets search absorb the promotion's lift instead.

In Robyn marketing mix modeling, a paid search ROI of zero or a negative coefficient can also come from adstock and saturation ranges that leave the optimizer too little room. Robyn's rule of thumb for geometric adstock on digital channels is a theta range of c(0, 0.3), and the demo script gives its search variable that range with alphas of c(0.5, 3) and gammas of c(0.3, 1).

In the 2021 thread, one contributor's order was to increase iterations and trials, then increase thetas and gammas, then try different train and test split ratios, then different channel aggregations. A second put numbers on the hyperparameter step, theta from 0 to 0.9 and gamma from 0.1 to 1 for the zero-coefficient channels, and clarified: "By increasing the bounds, we don't mean make it higher, but rather give the model more freedom." The same contributor noted that a low gamma is usually not recommended, and the thread uses older argument names, so translate before copying.

Our own view for search is to keep theta's lower bound at 0, on the working assumption that most search response arrives in the week of the click. On saturation, the guide says a larger gamma moves the inflection point later. Always-on brand search capped by query volume sits high on its curve, where the transformed series is nearly flat and gives the regression little variation to work with.

Calibrate search before trusting either number

A zero caused by collinearity and a zero from a channel that adds nothing look identical in Robyn's output, which is why the last step is an experiment. calibration_input takes the channel, the lift start and end dates, the absolute lift, the spend, a confidence value, the metric and a required calibration_scope column, and the demo script says to use "immediate" for causal experiments. With calibration data present, Robyn optimizes a third objective, MAPE.LIFT, which the feature documentation describes as minimising the difference between predicted effect and causal effect.

In the hypothetical above, once brand and non-brand are split, a six-week geo holdout on non-brand search that measured $117,000 of incremental revenue on $90,000 of spend, a return of 1.30, would enter as one row. The analyst guide's conditions apply: the study should match the model's granularity, metric and period, and low-confidence results should stay out. Read the test carefully first (see how to analyze an incrementality test result); the same lift can also calibrate platform attribution through the multiplier method.

Our data and analytics team works on measurement questions like this one, and Attribution Doctor is a further resource on the attribution side. If the calibrated model still puts brand search near zero, that may simply be the right answer for a channel that mostly collects people already on their way to you.

Sources

Robyn's documentation and main branch were read on October 7, 2026.

Frequently asked questions

Can Robyn return a negative coefficient for paid search?
Only when the sign is open. `paid_media_signs` defaults to "positive", which sets the coefficient's lower limit to 0 in the ridge regression. A negative paid search coefficient means the channel was set to "default" or "negative", or a search series was entered under `context_vars`, where the default sign is "default".
Why is my paid search coefficient exactly zero in Robyn?
Under the default "positive" sign the coefficient cannot go below zero, so a fit that would have gone lower stops at the floor. In a 2021 issue thread a Robyn contributor wrote that the model does not guarantee non-zero coefficients. The usual drivers are search spend that tracks demand, overlap with brand terms or promotions, and hyperparameter ranges that leave the optimizer too little room.
Should I set paid_media_signs to "default" for search?
As a diagnostic, yes. One run with an open sign shows whether the fit wants search below zero and by how much. For the model you report from, keep "positive" and work on the cause. Robyn's analyst guide gives an advertiser's own media activity as its example of a variable expected to have a positive impact on sales.
What adstock and saturation ranges does Robyn suggest for paid search?
Robyn's guide gives a rule-of-thumb geometric theta range of c(0, 0.3) for digital channels, with recommended Hill bounds of c(0.5, 3) for alpha and c(0.3, 1) for gamma. The demo script applies those ranges to its search variable. In a 2021 issue thread, a contributor suggested trying theta from 0 to 0.9 and gamma from 0.1 to 1 for channels stuck at zero.
Does a zero in Robyn mean paid search is not incremental?
A zero alone cannot tell you. Collinearity with demand and a channel that adds nothing produce the same output. Robyn's demo script strongly recommends calibrating with experimental results, and `calibration_input` accepts a measured lift for the channel. A geo holdout on search, entered as a calibration row, is what separates the two explanations.

Free tools for this topic

FREE TOOLAI Search Visibility CheckerCan ChatGPT, Perplexity and Google AI see your site?FREE TOOLSEO Page AuditorA senior-level on-page audit in one paste.PLAYBOOKThe AI Search PlaybookGet cited by ChatGPT, Perplexity and Google AI Overviews.

Keep reading

GlossaryWhat Is Incrementality? The Question Attribution Can't AnswerRead →GuidesHow to Run a Quarterly Geo-Holdout Test Your CFO Will Actually TrustRead →DataHow to Actually Analyze an Incrementality Test ResultRead →
CATALIST NEWSLETTER

Monthly dose of growth marketing.

Get marketing tips, narratives, guides, and playbooks delivered to your inbox.

Protected by reCAPTCHA — Google's Privacy Policy and Terms of Service apply.