Monetizing Short-Form Vertical Video (9:16) on Web and In-App: VAST Specs and Swipe-Feed Pre-Loading
In an infinite vertical swipe feed rendering at 60 frames per second, an unbuffered VAST 4.3 media file requires between 450 and 900 milliseconds to resolve

In an infinite vertical swipe feed rendering at 60 frames per second, an unbuffered VAST 4.3 media file requires between 450 and 900 milliseconds to resolve DNS, complete TLS handshakes, and decode the initial H.264 IDR keyframe on a mobile device. When a user flicks vertically to the next video card in under 200 milliseconds, traditional just-in-time programmatic ad requests fail to render in time. The user either encounters a blank black container and swipes past the placement before the first frame paints, or the publisher is forced to lock the scroll container, breaking the physics of the feed and increasing session abandonment.
Solving this latency gap requires decoupling the programmatic auction and media byte-range pre-fetching from the VAST impression tracking execution. However, pre-loading video ads in a vertical feed creates a secondary engineering hazard: if an off-screen video player initializes a VAST response in the background and fires the impression beacon before the user scrolls the card into the active viewport, the publisher generates unviewable impressions, distorts billable render rates, and triggers automated demand-side platform (DSP) bid shading or supply path throttling.
At Sky Boosts, our unified SSP and monetization platform architected a deterministic vertical video pipeline spanning Prebid.js 11.x, Prebid Server, Prebid Mobile SDK, and Google Ad Manager (GAM 360 and AdX). By combining explicit OpenRTB 2.6 aspect ratio signaling, lookahead byte-range caching, strict viewport-gated VAST pixel execution, and dynamic 16:9-to-9:16 canvas adaptation, publishers can capture premium short-form video budgets across mobile web and native applications without compromising viewability or user retention.
The Rise of 9:16 Vertical Video Inventory Outside Social Walled Gardens
For years, short-form vertical video budgets remained locked inside closed social applications because independent publishers lacked standardized UI containers and programmatic signaling for 9:16 streams. Today, news organizations, sports networks, financial platforms, and entertainment portals deploy dedicated vertical swipe feeds directly inside their mobile web properties and native iOS and Android applications. Instead of isolating video monetization inside tiny outstream placements embedded within text articles, publishers are adopting full-screen swipeable carousels that mirror the gesture mechanics of social video feeds.
In traditional mobile app monetization, video yield has historically relied on two discrete placement patterns: opt-in value exchanges using a rewarded video format or natural content transitions utilizing a full-screen interstitial format. While both formats remain core revenue drivers with high completion rates, they interrupt the primary user journey at fixed state changes, such as completing a game level or navigating between article pages. Swipe-feed vertical video introduces a continuous consumption loop where sponsored video cards are interleaved every four to six organic clips. Because the user can swipe past an ad card at any moment with a single thumb flick, the programmatic stack must operate with zero visual latency and immediate visual impact during the first two seconds of playback.
Moving social-style 9:16 creative campaigns onto the open web and in-app ecosystem also exposes buyers to inventory quality concerns if supply paths are not tightly governed. Tier-1 agency holding companies and brand advertisers shifting vertical video budgets out of walled gardens demand verifiable viewability, clean completion metrics, and strict brand suitability. Sky Boosts enforces 100% Google-friendly and HUMAN and Pixalate IVT-clean inventory standards across all vertical video streams, operating with zero alcohol, gambling, adult, tobacco, or restricted content categories. By pairing curated brand-safe supply with reliable Net-30 and Net-60 publisher payment terms, our platform enables publishers to capture high-CPM vertical video demand that clears at a substantial premium over standard display or muted outstream units.
Signaling Vertical Aspect Ratios in OpenRTB (w:1080, h:1920 or w:360, h:640)
A common mistake in vertical video monetization occurs in the bid request translation layer. Many publishers build a 9:16 player container in their front-end layout but leave their Prebid or GAM ad tag parameters configured with legacy horizontal defaults (640x480 or 640x360), expecting the buyer to automatically detect the vertical container on render. When an OpenRTB 2.6 bid request reaches a DSP with w: 640 and h: 360, the bidder's creative selection engine filters out all 9:16 vertical VAST assets and returns only horizontal 16:9 creatives. Even worse, if the publisher's player subsequently crops a returned 16:9 video to fill the 9:16 screen, critical brand logos and legal disclosures along the left and right edges are cut off, violating creative rendering policies.
To unlock native vertical creative pools in tier-1 DSPs, AdX, and Amazon TAM or UAM, the OpenRTB imp.video object must explicitly signal a 9:16 aspect ratio. However, engineering teams must account for how different buy-side platforms interpret pixel dimensions in mobile bid requests. Across the programmatic ecosystem, DSPs fall into two distinct validation patterns when evaluating vertical video dimensions:
- Viewport CSS Pixel Matching (
w: 360, h: 640orw: 390, h: 844): Certain mobile-first DSPs compare theimp.video.wandimp.video.hfields directly against the device-independent pixel (DIP) viewport geometry reported indevice.wanddevice.h. If the bid request claims a player size larger than the logical screen size without accounting fordevice.pxratio, strict validation heuristics may flag the request as anomalous. - Creative Resolution Matching (
w: 1080, h: 1920orw: 720, h: 1280): Conversely, several major brand video DSPs matchimp.video.wandimp.video.hdirectly against the encoded resolution of the creative asset stored in their VAST trafficking library. Because creative agencies master vertical video ads at1080x1920(Full HD portrait) or720x1280, passing only360x640can cause legacy creative matchers to skip high-definition 1080p vertical line items unless alternative sizes or aspect ratio extensions are declared.
To maximize bid density across both buyer architectures, Sky Boosts normalizes vertical video requests inside our Prebid Server and SSP adapter pipelines. We declare the primary logical or high-definition 9:16 dimensions in imp.video.w and imp.video.h while simultaneously populating imp.video.ext and player size arrays, alongside accurate IAB OpenRTB 2.6 placement classifications (plcmt: 1 for instream feeds where video is the primary content of the view, linearity: 1, and pos: 7 for full-screen).
{
"id": "8f92a1c4-710b-4d3e-9a2b-5581c09e1120",
"imp": [
{
"id": "1",
"video": {
"mimes": ["video/mp4", "video/webm", "application/x-mpegURL"],
"minduration": 5,
"maxduration": 30,
"protocols": [7, 8, 11, 12, 13, 14],
"w": 1080,
"h": 1920,
"startdelay": 0,
"placement": 1,
"plcmt": 1,
"linearity": 1,
"skip": 0,
"minbitrate": 800,
"maxbitrate": 4500,
"playbackmethod": [1, 2],
"pos": 7,
"api": [7],
"ext": {
"aspect_ratio": "9:16",
"viewport_w": 390,
"viewport_h": 844
}
},
"bidfloor": 6.50,
"bidfloorcur": "USD"
}
],
"device": {
"w": 390,
"h": 844,
"pxratio": 3.0,
"ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15"
}
}
In addition to aspect ratio geometry, bitrate governance (minbitrate and maxbitrate) is critical in swipe feeds. If a DSP returns a raw 25 Mbps mezzanine file inside the VAST <MediaFile> array, a mobile client on a cellular 4G or congested 5G connection will stall while buffering. By constraining maxbitrate to 4500 kbps and prioritizing adaptive HLS (application/x-mpegURL) alongside MP4 progressive streams compressed between 1.5 Mbps and 3.5 Mbps, the video player can select a rendition that decodes immediately upon swipe without visual artifacts.
Pre-Loading Next-Card Video Ads in Infinite Swipe Feeds Without Wasting Impressions
When a user consumes an infinite swipe feed, the transition between cards is governed by native scroll physics (such as UICollectionView paging on iOS, ViewPager2 on Android, or CSS scroll-snap-type: y mandatory on mobile web). To guarantee that an ad card at position N+1 plays on the very first frame as the user swipes down from organic card N, the ad auction and initial media buffering must occur while the user is still watching card N or N-1.

If a publisher implements lookahead buffering by simply instantiating a standard VAST video player inside the off-screen DOM node at card N+1 and calling loadAd(), the player will immediately parse the VAST XML, load the media file, and fire the VAST <Impression> pixel while the ad card is still sitting 844 pixels below the bottom edge of the screen. If the user closes the application or navigates back to the home screen while still on card N, that pre-loaded ad at N+1 never enters the viewport.
Firing impression beacons during off-screen pre-fetching creates severe commercial and compliance damage:
- MRC and Active View Viewability Collapse: Because the
<Impression>pixel fired off-screen and the user exited before scrolling down, the ad registers 0% viewability and zero milliseconds of in-view playback time. When an ad slot's aggregate viewability falls below 70%, automated DSP algorithms either exclude the placement from brand inclusion lists or apply aggressive bid shading that cuts clearing CPMs by 40% to 60%. - Direct Violation of IAB Standards: The IAB Tech Lab VAST 4.x specification explicitly mandates that the
<Impression>tracking URI must only be requested when the first frame of the video ad is actually displayed to the user, never during background pre-fetching in swipe feeds. - Auction Expiration versus Render Discrepancies: When an SSP fires a server-side billing notification upon auction win rather than upon client-side VAST
<Impression>execution, unrendered pre-fetched ads create massive reconciliation discrepancies between SSP auction logs and DSP impression trackers.
To achieve instantaneous playback without firing premature tracking pixels, the feed controller must separate the VAST lifecycle into three discrete stages across consecutive feed cards:
- Card
N-2(Auction Resolution): The client initiates the Prebid.js 11.x or Prebid Mobile auction and requests the GAM master video tag for the upcoming ad slot at cardN. The winning VAST XML response is fetched, unwrapped (resolving any<Wrapper>chains up to a maximum wrapper depth of 3), and parsed into an in-memory JavaScript or native data structure. No tracking URLs are requested at this stage. - Card
N-1(Byte-Range Media Pre-Warming): The player extracts the optimal<MediaFile>URL from the parsed VAST object and attaches it to an off-screen<video>element or nativeAVPlayerItemconfigured with muted audio synchronization andpreload="auto". On web implementations using Media Source Extensions (MSE) or Range HTTP headers (Range: bytes=0-1048575), the client fetches only the initialization segment (moovatom) and the first 1 MB of video data (roughly 2 to 3 seconds of 1080p video). This populates the hardware video decoder with the first decoded keyframe without downloading the entire 15 MB video file across cellular connections. - Card
N(Active Viewport Snap and First-Frame Execution): As the user swipes cardNinto the active viewport, the scroll container snaps into place, the pre-warmed video element starts playback in under 16 milliseconds (a single 60Hz display refresh cycle), and the VAST tracking engine releases the queued<Impression>and<Tracking event="start">beacons.
Firing the VAST Pixel Only on Active Viewport Snap and Passing ${AUCTION_IMP_TS}
Implementing strict viewport-gated VAST tracking on mobile web requires synchronizing the W3C IntersectionObserver API with the HTML5 requestVideoFrameCallback() method (or the playing event paired with currentTime > 0 fallback on older WebKit builds). Checking IntersectionObserver alone is insufficient because an ad container can enter the viewport while the video decoder is temporarily stalled; similarly, checking playing alone is insufficient if the browser begins playback 50 pixels before the scroll-snap transition completes.
Furthermore, because a pre-fetched VAST payload may sit in client memory for 10 to 45 seconds while the user watches organic videos at cards N-2 and N-1, engineering teams must pass accurate timing telemetry back to the SSP and DSPs. By populating the ${AUCTION_IMP_TS} macro (representing the Unix epoch timestamp in milliseconds when the impression is actually rendered) alongside Prebid cache TTL extensions configured for 180 to 300 seconds, the monetization stack preserves full attribution fidelity across delayed swipe-feed impressions.
class SwipeFeedVastController {
constructor(cardElement, vastPayload) {
this.cardElement = cardElement;
this.videoEl = cardElement.querySelector('video.vast-player');
this.vastPayload = vastPayload; // Parsed VAST 4.3 object held in memory
this.impressionFired = false;
this.isSnappedInViewport = false;
this.prewarmMediaBuffer();
this.bindViewportObserver();
}
prewarmMediaBuffer() {
this.videoEl.preload = 'auto';
this.videoEl.src = this.vastPayload.selectedMediaFileUrl;
this.videoEl.load();
}
bindViewportObserver() {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting && entry.intersectionRatio >= 0.85) {
this.isSnappedInViewport = true;
this.initiatePlaybackAndTrack();
} else if (entry.intersectionRatio < 0.20 && !this.videoEl.paused) {
this.videoEl.pause();
}
});
}, { threshold: [0.20, 0.85] });
observer.observe(this.cardElement);
}
initiatePlaybackAndTrack() {
const playPromise = this.videoEl.play();
if (playPromise !== undefined) {
playPromise.then(() => {
if ('requestVideoFrameCallback' in HTMLVideoElement.prototype) {
this.videoEl.requestVideoFrameCallback(() => this.fireImpressionBeacons());
} else {
this.fireImpressionBeacons();
}
}).catch((err) => {
this.vastPayload.errorUrls.forEach((url) => navigator.sendBeacon(url.replace('[ERRORCODE]', '400')));
});
}
}
fireImpressionBeacons() {
if (this.impressionFired || !this.isSnappedInViewport) return;
this.impressionFired = true;
const renderTimestamp = Date.now().toString();
const allStartBeacons = [
...this.vastPayload.impressionUrls,
...(this.vastPayload.trackingEvents.start || [])
];
allStartBeacons.forEach((rawUrl) => {
const resolvedUrl = rawUrl
.replace(/\$\{AUCTION_IMP_TS\}/g, renderTimestamp)
.replace(/\[CACHEBUSTING\]/g, Math.floor(Math.random() * 1e8));
navigator.sendBeacon(resolvedUrl);
});
}
}
By requiring an intersectionRatio of 0.85 (confirming the CSS scroll-snap animation has settled into the primary screen) and awaiting requestVideoFrameCallback before dispatching navigator.sendBeacon(), the publisher guarantees 100% compliance with IAB VAST 4.3 impression guidelines and achieves near-100% MRC viewability on every rendered ad card.
Repurposing 16:9 Horizontal Demand with Blurred Background Canvas Wrappers
Even when a publisher configures OpenRTB 2.6 bid requests to signal 9:16 vertical capabilities accurately, restricting the auction exclusively to native 9:16 video creatives leaves significant yield on the table. While social-derived 9:16 programmatic demand is expanding rapidly, a substantial share of enterprise brand video budgets across GAM Open Bidding, AdX, and tier-1 DSPs is still trafficked exclusively in horizontal 16:9 (1920x1080 or 1280x720) VAST tags. If an ad slot rejects 16:9 bids, overall bid density drops, auction competition thins out, and clearing prices fall below optimal floor elasticity thresholds.
However, rendering a 16:9 horizontal video directly inside a 9:16 vertical swipe card using default aspect-fit scaling leaves 68% of the vertical screen covered in empty black letterbox bars above and below the video frame. Users conditioned by native vertical feeds immediately recognize black letterbox bars as low-effort commercial interruptions and swipe past the card within 500 milliseconds, destroying video completion rates (VTR).
To capture the full depth of 16:9 horizontal demand while preserving the immersive aesthetic of a 9:16 vertical feed, publishers can implement a dual-layer blurred background canvas wrapper. When the VAST parser inspects the winning <MediaFile> node and detects a horizontal aspect ratio (width > height), the player centers the primary <video> element vertically at 100% viewport width while projecting an ambient, real-time blurred backdrop onto a <canvas> element spanning the full 100vw x 100dvh 9:16 container behind the video.
To prevent the ambient background canvas from taxing the mobile GPU or triggering thermal throttling during 60fps scroll transitions, the rendering loop must downsample the backdrop draw calls:
- Ultra-Low-Resolution Canvas Buffer: Instead of matching the device's physical pixel resolution (
1170x2532on a modern iPhone), set the internal coordinate space of the background<canvas>to just64pixels wide by114pixels high (width="64" height="114"), then stretch it to 100% of the 9:16 card via CSS (width: 100%; height: 100%; object-fit: cover;). Because the backdrop will be heavily blurred, a64x114pixel buffer provides smooth color gradients while reducing GPU fill-rate overhead by 99.8%. - Throttled Frame Sampling with Hardware Filters: Rather than redrawing the background canvas at 60 frames per second, sample the primary
<video>element at 15 frames per second usingctx.filter = 'blur(8px) brightness(0.60) saturate(1.25)'andctx.drawImage(videoEl, 0, 0, 64, 114). The slight luminance reduction (brightness(0.60)) ensures the crisp foreground 16:9 video pops visually against the ambient color field, while top and bottom gradient overlays keep feed UI controls (such as mute toggles, brand attribution headers, and CTA buttons) completely legible. - Strict OMID and Google IMA SDK Geometry Separation: From a programmatic compliance standpoint, the background
<canvas>is purely decorative container chrome and must never be registered as the video player element. The foreground 16:9<video>element must remain completely uncropped, unobstructed (z-indexpositioned cleanly above the canvas), and bound directly to the IAB Open Measurement (OMID) verification script or Google IMA SDKAdDisplayContainer. Callingpointer-events: noneon the background canvas guarantees that user taps on the ambient backdrop do not register accidental click-throughs, protecting the publisher from invalid click activity penalties.
For engineering and AdOps teams scaling short-form vertical video across web and in-app environments, the architecture comes down to three non-negotiable rules: pass explicit 9:16 aspect ratio signals alongside dual-size support in OpenRTB 2.6 so both vertical and horizontal DSP line items can compete in a unified auction; decouple byte-range media pre-warming at card N-1 from viewport-gated VAST <Impression> execution at card N using IntersectionObserver and ${AUCTION_IMP_TS}; and wrap winning 16:9 horizontal creatives in a low-overhead ambient canvas backdrop. Executing this stack eliminates black-frame swipe latency, protects 90%+ viewability scores, and maximizes blended eCPM across every swipe in the feed.