Reels Time-Based Ad Injection Across Surfaces
Implemented a cross-surface injection system at Meta that converts unmonetized dwell time into Reels ad impressions using a custom Android session tracker.
Reels Cross Surface TBI
Company: Meta
Surface: Instagram Reels
Role: Android Software Engineer
Impact Area: Ads Monetization, Cross-Surface Signal Integration
The Problem
Not all time spent inside a mobile app is monetized equally. A user who spends five minutes editing a video in the camera, ten minutes browsing their own profile, and three minutes reading DMs has generated substantial session engagement without receiving a single ad impression. When that user returns to the Reels feed, they carry a specific characteristic that makes them a high-value monetization target: high recent engagement combined with low recent impression frequency.
Standard Reels ad delivery has no awareness of what happened on other surfaces before the user arrived. It treats every return to Reels as identical, serving the next queued ad from the standard ranking pipeline regardless of how much unmonetized time preceded the navigation. That means a user returning from 15 minutes on the camera receives the same ad experience as a user who was just on Reels 30 seconds ago.
That is a missed opportunity, and it is measurable.
The Concept: Impression Debt
I approached this problem through the concept of impression debt. Every minute a user spends on a non-monetized surface within the Meta app ecosystem is a minute where ads could not be served. This accumulated time represents latent monetization potential that has not yet been converted into revenue.
The question is: when is the right moment to act on it? The answer is clear and specific: the moment the user transitions back to a monetizable surface. That transition event is the highest-receptivity window available. The user has been active. They have not seen ads recently. And they have chosen, voluntarily, to navigate to a surface where ads are a normal part of the experience.
Reels Cross Surface TBI (Time-Based Injection) was designed to capture exactly this window.
How It Works
The feature tracks accumulated dwell time on non-monetized surfaces across a user session. Every navigation away from Reels to a surface that does not serve ads starts or continues an accumulation timer. When the user returns to Reels and the accumulated time exceeds a configurable threshold, the system injects an ad adjacent to their current position in the feed. The injection is immediate and uses a cached ad request, adding no latency to the user experience.
Three components drive this system:
SurfaceSessionTracker monitors every navigation event within the app, records which surface the user is on, and accumulates dwell time on surfaces classified as non-monetized. It emits a surface transition event on every navigation so downstream consumers can act immediately.
CrossSurfaceTBIManager subscribes to surface transition events and evaluates them on every navigation to Reels. On each return to Reels, it queries the accumulated non-monetized time and compares it against the TBI threshold. If the threshold is met, it triggers an ad injection and resets the accumulator.
TBIInjectionController receives the injection request, identifies the current position in the feed, and inserts the ad item adjacent to the organic item the user is currently viewing. Once injected, standard impression tracking handles the rest.
Surface Classification System
The accuracy of this feature depends entirely on the precision of the surface classification. I built a surface registry that categorizes every major screen in the Meta app as monetized or non-monetized.
Monetized surfaces (Reels feed, Feed, Stories with ads) contribute to impression frequency and do not accumulate non-monetized time. Non-monetized surfaces (Camera, Profile, Explore grid without ads, DM inbox, Settings) contribute to the accumulator.
Critically, this registry is updateable via remote config. New surfaces launch frequently at Meta, and the classification needed to stay current without waiting for a mobile app release cycle. Remote config-driven surface classification means any newly launched non-monetized surface can be added to the tracking registry immediately.
Threshold Calibration and Experimentation
Setting the right threshold was the most experiment-intensive part of this project. The threshold defines a meaningful boundary: below it, the user has not been away from monetized surfaces long enough to justify an injection. Above it, an injection is warranted because the impression debt is significant.
Too low a threshold triggers TBI too aggressively, injecting ads into sessions where the user barely navigated away, hurting the organic experience and potentially degrading key engagement metrics. Too high a threshold reduces coverage and leaves genuine impression debt uncaptured.
I ran a series of A/B experiments across different threshold values, measuring both direct revenue impact from TBI injections and engagement guardrail metrics including session length, swipe rate on Reels, and negative feedback rate on injected ads. The experiment data identified a threshold range that produced clear revenue lift with no statistically significant regression in engagement guardrail metrics.
The threshold is stored in remote config and is not hardcoded, which means it can be tuned per cohort, per region, or per device class without a mobile app release.
Accumulator Reset Strategy
Getting the accumulator reset logic right was non-trivial. Several reset conditions needed to be handled:
Post-injection reset. After a TBI injection fires, the accumulator resets to zero. This prevents a single large accumulated window from triggering multiple injections within the same session.
App background reset. If the app is backgrounded for longer than a configurable duration, the accumulator resets. This prevents time accumulated in a session from days ago from affecting a fresh session. Without this, a user who spent 30 minutes on the camera two days ago could be affected by a TBI trigger the next time they opened the app.
App kill reset. On process termination, the accumulator does not persist. The accumulator is session-scoped by design, reflecting engagement within a single continuous usage session.
Outcome
Cross Surface TBI expanded the Reels monetization footprint without adding new ad slots to the feed or increasing steady-state ad density. The injection is conditional and targeted, firing only for users whose recent session behavior indicates low impression frequency and high engagement. This makes the feature additive to the existing Reels ad experience rather than dilutive of it.
The feature converts a previously invisible signal (what the user was doing before they opened Reels) into a monetization action at the precise moment of highest receptivity. It runs across millions of cross-surface navigation events daily, representing a meaningful expansion of monetizable moments on the Reels surface.