Skip to main content

Android AdTech Deep Dive: SSAI vs. CSA

My first post covered AdTech fundamentals. Now let's go deeper into the architecture that powers live sports streaming at OTT companies: Server-Side Ad Insertion (SSAI) vs. Client-Side Ad Insertion (CSA).

Updated 2 min readMarkdown
Android AdTech Deep Dive: SSAI vs. CSA

SSAI vs. CSA: The Core Difference:

Client-Side Ad Insertion (CSA) The app fetches ads separately and plays them before/during content.

Pros:

Full control over ad UI (skip buttons, countdowns)

Easy to debug ad playback

Works with any ad network

Cons:

Ad blocking: Users can install ad blockers since ads come from separate domains

Buffer interruptions: Ad fetch delays content playback

Higher VST: 10-20s extra on devices like Xiaomi/Oppo due to network latency

CSA is what IMA SDK uses for traditional ad playback. You'll see this in older apps.

Server-Side Ad Insertion (SSAI) Ads are stitched into the video manifest server-side before reaching the player. The player sees one continuous stream.

Pros:

Ad blocking immune: Ads look like content (same origin, no CORS)

Zero-seam UX: No buffer gaps between ad and content

Lower VST: Pre-stitched manifests load faster (we hit ~10s on Samsung/Pixel, ~20s on Xiaomi in Spain)

Cons:

Harder to debug (can't see individual ad URLs in network tab)

Limited UI control (no custom skip buttons)

Requires backend integration (AWS MediaTailor, Google DAI)

SSAI is the industry standard for live sports streaming at Hotstar, ESPN+, and Netflix Ads.

Real-World Example:

DAI URL Flow When you play a live match on OTT, here's what happens under the hood:

  1. User clicks "Play" → App requests DAI manifest URL

  2. Backend calls Google DAI / AWS MediaTailor with session token

  3. Server returns stitched MPD manifest + tracking URL

  4. ExoPlayer loads manifest → Play starts (no ad separate fetch)

  5. Client polls tracking URL for ad events (start/end/beacons)

Sample DAI URL format:

https://dai.google.com/linear/dash/pa/event/{event_id}/stream/{stream_id}/manifest.mpd

You can fetch this in prod (not just debug) using the URL reported to analytics like Conviva. Parse the MPD to see tags marking ad breaks.

About the author

  • Senior Mobile app developer specializing in OTT and AdTech | Android, Java, Kotlin, Flutter

No comments yet. Be the first to comment.