Back to blog
August 14, 2026Sergei Solod11 min read

What I Learned from Testing Popunder Frequency Against User Engagement

I increased popunder frequency on a production web application and watched aggregate engagement before and after the change. I kept a 45-second initial delay and a four-minute minimum cooldown, but the more useful result was learning how cautiously a stable engagement average should be interpreted.

popunderfrequency cappingweb monetizationuser engagementweb analytics

I expected popunder frequency to produce an obvious trade-off: show ads less often and protect the user experience; show them more often and gain revenue until engagement starts to fall. Production behavior was less tidy.

After increasing the frequency on one of my production web applications, I expected a visible break in engagement. Instead, the aggregate metric continued moving roughly within its previous day-to-day range. Some days were better, some worse, but I did not see a clear sustained decline beginning with the new policy.

I eventually kept this configuration:

Initial delay: 45 seconds
Minimum cooldown after a successful popunder: 4 minutes

I also kept a frequency window that allowed no more than one successful event in the same four-minute period:

const policy = {
  initialDelaySeconds: 45,
  cooldownSeconds: 240,
  windowSeconds: 240,
  maxEventsPerWindow: 1,
};

This is illustrative pseudocode, independent of any advertising provider, SDK, application, or deployment. The implementation is less interesting than the policy behind it.

There are really two frequency decisions

I initially framed the problem as a single question: how many minutes should separate popunders? That was the wrong abstraction. There are at least two decisions: the delay before the first advertising opportunity and the minimum interval before subsequent opportunities.

Those moments are not equivalent. A new visitor has not yet decided whether the product is useful; an engaged visitor already has. I therefore decided that the first interruption deserved more protection than later ones.

Why I stopped monetizing the first seconds so aggressively

A shorter initial delay creates more eligible visitors and therefore more potential ad events. Mechanically, that is true. What it ignores is when the monetization is happening.

If advertising appears almost immediately after arrival, it becomes part of the user's first evaluation of the site. If the user first gets uninterrupted time to understand and use the product, the same advertising mechanism arrives in a different context.

I had previously used a shorter delay, but moved it to 45 seconds. That is still relatively early and was not intended as a conservative setting. It simply separated the beginning of the visit from the first monetization opportunity. I started thinking of those seconds as product-acquisition time rather than lost ad inventory.

Forty-five seconds is a threshold, not a scheduled event

The delay establishes eligibility; it does not necessarily trigger an ad at exactly 00:45. The actual event still depends on an eligible user interaction. A visitor may become eligible at 00:45 and generate the first popunder at 01:03 after the next qualifying action.

The same applies to the cooldown. Four minutes means another event cannot become eligible sooner than four minutes after the previous successful event. It does not mean an ad appears automatically every four minutes. The configured intervals are therefore minimums, and the real spacing can be longer.

The repeat interval mattered more than the initial delay

Once I was comfortable with the first delay, the repeat cadence became the more important variable. A long cooldown reduces advertising pressure, but many engaged users may then never generate a second opportunity.

I wanted two conditions at once: an engaged user should have a realistic chance of generating another monetization event, while the product should still contain meaningful uninterrupted stretches between events.

The setting I kept was four minutes. With a 45-second first delay, the earliest theoretical eligibility points are approximately 00:45, 04:45, 08:45, and 12:45. Actual events may happen later because a qualifying interaction is still required.

Why four minutes felt different from maximizing impressions

Reducing a cooldown creates more theoretical opportunities. If the only objective is ad opportunities per user, shorter is obviously better. But the product has advertising value only while it continues to have user value.

additional monetization
-
behavioral damage
=
net value

Four minutes gave users a meaningful block of ordinary product use in which another popunder was impossible. That invariant mattered more to me than the phrase “one every four minutes.”

After a monetization event, the user gets several minutes during which another one is impossible.

I expected a visible drop in engagement

Before deployment, my main hypothesis was that higher advertising frequency would produce a clear before-and-after decline in analytics. If that had happened, I would have had a strong reason to soften the policy.

Instead, aggregate engagement continued fluctuating much as it had before. I did not see a new lower baseline or an obvious sequence in which the metric remained persistently weaker after the frequency change. The failure mode I expected to be large enough to see simply did not appear clearly.

What I can actually claim

I cannot claim that the ads had no effect, that users did not mind them, that retention was perfectly unchanged, or that this configuration is globally optimal. Aggregate analytics cannot prove any of those statements.

The strongest statement supported by my observation is narrower:

After the frequency increase, I did not observe a clear sustained decline in aggregate engagement beyond the ordinary variation I had already been seeing.

That leaves room for smaller effects, differences between user groups, and behavior hidden by a single average. I tested whether the configuration remained acceptable enough to keep, not whether I had discovered a universal optimum.

A stable average can hide very different behavior

An almost unchanged aggregate average can describe very different realities. Everyone may behave similarly; some users may leave earlier while others stay longer; a small group may react negatively without moving the average much; or a real negative effect may simply be smaller than normal day-to-day variation.

For that reason I treat a stable aggregate metric as a useful warning signal, not proof of zero impact.

Engagement is not the same as literal visit length

I also avoided treating an analytics engagement metric as the exact average duration of a session. Active engagement is defined by the analytics system and does not necessarily equal elapsed time with a tab open. Users can switch focus, return later, navigate, or behave in ways that make a simple “time on site” model misleading.

I therefore did not use a formula such as “average engagement is X, so the next popunder must happen before X.” I used the metric directionally: did the post-change product appear materially weaker than before? At the aggregate level I was monitoring, the answer was no.

Cooldown and frequency window are related but not identical

The implementation used both a 240-second cooldown and a 240-second frequency window with a maximum of one successful event. They are largely redundant, but express slightly different constraints.

The cooldown says not to allow another event until enough time has passed since the previous one. The window says not to allow more than one successful event inside the defined period. I kept both because I wanted the intended invariant to remain obvious even if an integration interpreted one mechanism differently.

Two successful popunders must never occur less than four minutes apart.

One event per window does not mean one event per visit

A value such as maxEventsPerWindow = 1 does not necessarily mean one ad for the visitor's entire stay. Its scope is the configured window; after that period expires, another window may begin. Nor does the value represent one user action. It represents one successful monetization event within that frequency period.

Whenever I review frequency logic now, I ask three questions: what does the counter count, what resets it, and how long is the reset window? Without those answers, a raw value such as 1 says very little.

I separated policy from provider-specific implementation

The reusable behavior can be described without exposing vendor-specific scripts, identifiers, or parameter names:

function isEligible(state, now) {
  if (!state.hasShownFirstEvent) {
    return now - state.arrivalTime >= 45_000;
  }

  return now - state.lastEventTime >= 240_000;
}

This is explanatory pseudocode, not production source code. Providers, SDKs, and deployment architecture change; the policy is more durable: protect the beginning of the visit, allow monetization after genuine use has begun, enforce a hard cooldown, and repeat only after that cooldown.

Build success and behavioral correctness are different

A typechecker, linter, and production build can verify many engineering properties, but none of them proves that the advertising timeline behaves correctly in a browser. This feature needs behavioral validation as well.

1. Open a clean browser state.
2. Interact before the initial delay: no popunder should occur.
3. Wait beyond the initial delay.
4. Perform an eligible interaction: the first popunder may occur.
5. Keep interacting before the cooldown ends: no second popunder should occur.
6. Wait until the cooldown expires.
7. Interact again: another popunder may now occur.

A successful build and a successful behavioral test answer different questions, and both matter.

The combined advertising experience matters more than any placement

Independent advertising systems can each look reasonable while producing an aggressive combined experience. Two formats with four-minute limits can interleave, for example, so that the user experiences interruptions around 00:45, 02:45, 04:45, and 06:45.

That led me to a stronger rule:

Frequency caps should be evaluated per user experience, not per advertising script.

The user experiences the sum of interruptions, not the configuration file that produced each one. A production audit should therefore ask how many interruptive advertising events one user can actually encounter over a given period.

Raw impression count is the wrong optimization target

Generating more opportunities by reducing the cooldown is easy. The harder question is how much additional monetization can be gained without reducing the user's total economic value.

A configuration that produces fewer ads per visit can still generate more revenue over time if it preserves repeat usage. That is why I care more about revenue per user over time than impressions per visit. The second is easy to maximize; the first is the actual business problem.

A stronger experiment would look beyond one graph

My production observation was enough to tell me that the catastrophic outcome I feared did not obviously occur. It was not enough to establish every downstream effect.

A stronger experiment would compare monetization revenue per unique user, revenue per visit, advertising events per user, active engagement, meaningful product interactions, returning-user rate, retention over time, and longer-term user value.

Both sides need to be measured. Looking only at advertising output makes more advertising appear automatically better; looking only at engagement can hide meaningful revenue gains that carry little behavioral cost.

Why I kept the policy simple

I found no reason to add a growing collection of exceptions. The final logic stayed easy to explain: wait 45 seconds, allow monetization on the next eligible interaction, enforce a four-minute hard cooldown, then allow the next eligible interaction to monetize.

A small number of strong invariants is easier to reason about, test, and debug than a policy whose behavior depends on many obscure exceptions.

The asymmetry is intentional

The policy treats new and engaged users differently. A new visitor receives more protection; a visitor who continues interacting creates more monetization opportunities over time.

That means advertising pressure scales with demonstrated engagement instead of being applied at maximum intensity immediately. This conceptual change was one of the most useful results of the experiment.

What I would not conclude from this case study

I would not claim that 45 seconds is universally correct, that four minutes is the optimal interval, that higher-frequency popunders never hurt engagement, or that a stable average means users are unaffected. I also would not generalize one production workload to every web product.

Different products have different users, expectations, acquisition sources, usage patterns, and economics. The result is useful because it is specific, not because it proves a universal rule.

The part that changed my mind

Before the experiment, I expected advertising pressure and engagement to have an almost mechanical relationship: increase one enough and the other should visibly fall. Production behavior was less clean.

I increased frequency to a level I considered relatively high. Users continued interacting, and aggregate engagement stayed within its familiar day-to-day range. That does not mean the cost was zero. It means the cost was not large enough to create the obvious signal I expected in the metric I was watching.

The difference between “no effect” and “no obvious effect in this measurement” is important. Production systems rarely provide the clean causal stories we would like.

My rule now

I no longer ask how frequently I can technically show another popunder. I ask how much uninterrupted product experience a new user should receive before monetization begins, how much uninterrupted usage an engaged user should receive before another event becomes possible, and whether the added advertising increases total user value rather than merely the impression counter.

For this application, the retained answer was:

45 seconds before initial eligibility
at least 4 minutes between successful events

The values themselves are only one implementation. The rule I would reuse is broader:

Protect the beginning of the user journey, monetize demonstrated engagement more heavily than initial curiosity, and judge the result by user-level value rather than raw advertising volume.