What Is Server-Side Ad Insertion (SSAI)? How to Set It Up for Live Streaming on a VPS

Server-side ad insertion (SSAI) is a method of stitching ads directly into a live video stream on the server, before it reaches the viewer’s player, so the ad and the content look like one continuous stream. Because the ads live inside the same HLS or DASH manifest as your content, browser ad-blockers and player skip buttons can’t isolate and remove them the way they can with a client-injected VAST ad. If you’re pre-installing Wowza or Ant Media Server on a streaming VPS and want to monetize a live channel — sports, IPTV, a paid webinar feed — SSAI is the mechanism nearly every broadcast-grade ad workflow is built on.

Key Takeaways

  • SSAI stitches ads into the live stream server-side using SCTE-35 markers, so ads survive ad blockers and don’t cause the visible “reload” that client-side ad insertion (CSAI) often does.
  • SCTE-35 is a signaling standard, not an ad-delivery mechanism itself — it just tells downstream systems exactly when an ad break starts and ends via #EXT-X-CUE-OUT / #EXT-X-CUE-IN tags in the manifest.
  • Your ingest protocol matters: SCTE-35 markers only survive inside an MPEG-TS payload, so you need SRT, RIST, or UDP-TS ingest — plain RTMP will not carry the ad cues.
  • Ant Media Server (via its SCTE35Plugin) and Wowza Streaming Engine (via ModuleAdMarkers, 4.8.26+) both support ad-marker passthrough; NGINX-RTMP has no native support and needs a custom manifest proxy.
  • The streaming engine only prepares the manifest — you still need a separate SSAI/ad-decisioning platform (AWS MediaTailor, Google Ad Manager, Broadpeak, Yospace) to actually fetch and stitch the ad creative.

What Is Server-Side Ad Insertion (SSAI)?

SSAI is an ad-delivery architecture where an ad-decisioning service rewrites your live HLS or DASH manifest — swapping ad segments in at defined ad-break points — before the manifest reaches the viewer’s player. The player just sees one continuous stream of segments; it has no idea which ones are “ads” versus “content.” That’s the entire point: because the ad segments are indistinguishable from content segments at the manifest level, they play through the same player logic, at the same bitrate ladder, without the buffering stall or visible ad-tag swap you get with client-side ad insertion (CSAI), where the player itself requests a separate ad stream from a VAST/VMAP tag.

The tradeoff is architectural complexity. SSAI isn’t something your streaming engine does alone — it’s a pipeline: your engine has to preserve or generate ad-break signals, and a separate SSAI service has to read those signals, call an ad decision server, fetch creative, and rewrite the manifest in real time.

How Does SSAI Work? SCTE-35 Cues and Manifest Manipulation

SCTE-35 is the “digital cue card” of the broadcast industry — a set of splice command markers (Table ID 0xFC in the MPEG-TS payload) that signal an upcoming ad opportunity. Without SCTE-35, an SSAI service is blind: it has no reliable way to know when a live feed should switch to a commercial break and when it should switch back.

The flow looks like this in a typical VPS-hosted setup:

  1. Your source (a hardware encoder, OBS with an SRT output, or a playout system) embeds SCTE-35 splice-insert commands into an MPEG-TS stream at the ad-break points.
  2. You push that stream to your streaming engine over SRT, RIST, or UDP-TS — not plain RTMP, which can’t carry the MPEG-TS timed-metadata SCTE-35 needs.
  3. The engine parses the splice commands and writes standard HLS ad markers into the .m3u8 manifest: #EXT-X-CUE-OUT:30.000 at the start of the break and #EXT-X-CUE-IN at the end, often alongside an #EXT-X-DATERANGE tag for DASH-style timing.
  4. An SSAI platform (MediaTailor, Google Ad Manager, Broadpeak, Yospace) sits in front of your manifest, sees the cue-out marker, calls an ad decision server (often over VAST/VMAP), fetches the ad creative, transcodes it to match your bitrate ladder, and splices the ad segments into the manifest in place of (or alongside) your original content during the ad break.
  5. The player requests the rewritten manifest from the SSAI platform’s URL instead of your engine’s URL directly, and plays straight through — content, then ad, then content — without knowing the difference.

Neither Wowza nor Ant Media Server does step 4 itself. Both explicitly position themselves as the bridge that preserves and formats the ad-marker signaling; the actual ad decisioning and creative stitching is handled by a dedicated SSAI service downstream. That division of labor is worth understanding before you budget a project, because it means “add SSAI” is really “add SCTE-35 passthrough on your engine” plus “add or subscribe to an SSAI platform.”

SSAI vs. Client-Side Ad Insertion (CSAI): What’s the Difference?

Server-Side (SSAI)Client-Side (CSAI)
Where ads are stitchedOn the server, into the manifest itselfOn the device, by the player/SDK
Ad-blocker resistanceHigh — ads look like normal segmentsLow — VAST tags and separate ad domains are easy to block
Playback experienceSeamless, same player, same bitrate ladderOften a visible stream reload/black flash between content and ad
Setup complexityHigher — needs SCTE-35 passthrough + a dedicated SSAI platformLower — most video players have built-in VAST/IMA SDK support
Best fitLive linear channels, IPTV, sports, monetized 24/7 streamsVOD, on-demand pre-rolls, lower-stakes ad inventory
Typical cost driverPer-stream-hour or per-impression SSAI platform feesAd SDK is usually free; revenue loss from blocked ads

If your monetization model depends on ads actually being watched — a live sports feed, an ad-supported IPTV channel, a free tier in front of a paywalled stream — SSAI is worth the added complexity specifically because it closes the ad-blocker gap that CSAI can’t.

Which Streaming Engines on a VPS Support SSAI?

This is where the “pre-installed engine” model matters, because SCTE-35 support is engine-specific and version-specific, not something you can assume:

  • Ant Media Server ships an official SCTE35Plugin that ingests an SRT stream carrying SCTE-35 in its MPEG-TS payload, parses the splice commands, and injects #EXT-X-CUE-OUT / #EXT-X-CUE-IN tags into the HLS manifest via a SCTE35ManifestModifierFilter registered in the application’s web.xml. Ant Media is explicit that it doesn’t insert ads itself — it hands a properly-marked manifest to an SSAI service like AWS MediaTailor.
  • Wowza Streaming Engine has had native support since version 4.8.26 via ModuleAdMarkers, which converts incoming SCTE-35 splice events to onCUE events and re-breaks the HLS/DASH output at the splice point with cue-in/cue-out tags. Wowza requires the source to be MPEG-TS-based with SCTE-35 already embedded — it doesn’t generate ad markers out of nothing.
  • NGINX-RTMP has no built-in SCTE-35 parsing or ad-marker injection in the open-source nginx-rtmp-module. If you want SSAI on an NGINX-RTMP stack, you’re building or bolting on a custom manifest-rewriting proxy — a real option for a DIY-inclined team, but a meaningfully bigger lift than the plugin/module path on Wowza or Ant Media.

On the streaming VPS instances we run pre-installed Ant Media on, enabling the SCTE-35 plugin is a five-minute config change once you already have SRT ingest working — the actual engineering work is upstream, getting your encoder or playout system to embed valid SCTE-35 splice commands in the first place.

How to Set Up SSAI on a Streaming VPS (Step by Step)

  1. Confirm your source can embed SCTE-35. Most consumer encoders (OBS included) do not do this out of the box; you typically need a playout system, a dedicated SCTE-35 injector, or a broadcast-grade encoder.
  2. Push over SRT (or RIST/UDP-TS), not RTMP. On Ant Media, that’s typically an SRT listener on port 4200 with a streamid matching your application name, e.g. srt://your-vps-ip:4200?streamid=WebRTCAppEE/your_stream.
  3. Install the ad-marker component. On Ant Media, copy SCTE35Plugin.jar into /usr/local/antmedia/plugins/ and register SCTE35ManifestModifierFilter in web.xml, placed after the existing HlsManifestModifierFilter entry so filter order is correct. On Wowza, confirm you’re running 4.8.26 or later and enable ModuleAdMarkers on the application.
  4. Restart the engine and verify. For Ant Media, sudo systemctl restart antmedia and check /var/log/antmedia/ant-media-server.log for SCTE-35 Plugin initialized successfully. Pull the .m3u8 manifest during a cue point and confirm you see #EXT-X-CUE-OUT:30.000 followed a few segments later by #EXT-X-CUE-IN.
  5. Point an SSAI platform at your manifest. In AWS MediaTailor, for example, you configure a video content source pointing at your engine’s HTTP-accessible stream path (MediaTailor requires port 80/HTTP for this) and an Ad Decision Server URL (a VAST/VMAP endpoint — even a public test tag works for verification). MediaTailor then serves a rewritten manifest URL; that’s the URL your player actually requests, not your engine’s direct URL.
  6. Test with a known-good SCTE-35 source before going live. In our own testing, plain FFmpeg frequently fails to carry SCTE-35 packets correctly over SRT — a pre-baked test file streamed with srt-live-transmit (cue points every 2–5 minutes) is the more reliable way to verify the pipeline end-to-end before you trust a live encoder feed.

On a 4 vCPU / 8 GB streaming VPS running Ant Media with the SCTE-35 plugin active, manifest updates for a cue point typically show up within one HLS segment duration (commonly 4–6 seconds) of the splice command arriving — the bottleneck in practice is almost always the ad decision server’s response time, not the streaming engine.

Is SSAI Worth It? Costs, Tradeoffs, and When to Skip It

Turning on SCTE-35 passthrough on Wowza or Ant Media adds no separate license fee on top of what you’re already paying for the engine — it’s a configuration, not a paid add-on, on both platforms as of this writing. The real cost sits with the SSAI/ad-decisioning platform itself: services like AWS Elemental MediaTailor, Google Ad Manager, Broadpeak, or Yospace typically bill per stream-hour or per-thousand ad impressions, and that recurring cost needs to actually be covered by ad revenue to make sense.

SSAI is worth the added complexity when: you run a live, ad-supported linear channel (IPTV, sports, 24/7 loop) where completion rate and ad-blocker resistance directly affect revenue. It’s usually not worth it for a low-traffic or subscription-only stream, a one-off event, or anything where a simpler pre-roll via a player’s built-in VAST/IMA SDK (CSAI) would cover the same handful of ad impressions without the added pipeline.

FAQ

Is server-side ad insertion (SSAI) better than client-side ad insertion (CSAI)?

SSAI is generally better for completion rates and ad-blocker resistance because ads are stitched into the video stream before it reaches the player, so browser ad blockers and skip buttons can’t target them. CSAI is easier to implement and gives richer client-side interactivity, but ads are more easily blocked or skipped and can cause a visible player reload between content and ad.

Do I need SCTE-35 to do server-side ad insertion?

Yes, in almost every real SSAI workflow. SCTE-35 is the signaling standard that marks exactly where an ad break starts and ends inside your video stream; without it, an SSAI service has no reliable way to know when to swap in an ad.

Can NGINX-RTMP do server-side ad insertion?

Not natively. The open-source nginx-rtmp-module has no built-in SCTE-35 parsing or ad-marker injection, so SSAI on NGINX-RTMP requires a custom manifest-rewriting proxy in front of it. Wowza and Ant Media Server both have built-in or plugin-based SCTE-35 support, which makes them a more direct path to SSAI.

What ingest protocol do I need for SCTE-35 ad markers to survive?

Your source stream needs to carry SCTE-35 inside an MPEG-TS payload, which means SRT, RIST, or UDP-TS ingest rather than plain RTMP. Both Wowza (4.8.26+) and Ant Media Server require an MPEG-TS-based source for their ad-marker features to work.

How much does server-side ad insertion cost?

The streaming engine side (Wowza’s ModuleAdMarkers or Ant Media’s SCTE-35 plugin) adds no extra license cost beyond your existing engine, but you still need a separate SSAI/ad-decisioning service such as AWS Elemental MediaTailor, Google Ad Manager, Broadpeak, or Yospace, which are typically billed per stream-hour or per-thousand ad impressions on top of your VPS and bandwidth costs.

Conclusion

SSAI is a pipeline, not a checkbox: it needs SCTE-35 markers reaching your streaming engine over an MPEG-TS-based ingest protocol, an engine that can preserve and format those markers into HLS/DASH ad cues, and a dedicated SSAI platform to actually decision and stitch the ad creative. Wowza and Ant Media Server both handle the middle piece out of the box; NGINX-RTMP does not. If you’re planning a monetized live channel, get the SCTE-35 passthrough working and tested with a known-good source before you wire up an ad decisioning platform on top of it.

Get a pre-installed Ant Media or Wowza streaming VPS from StreamingVPS.com — go live in 60 seconds, with the streaming engine already configured and ready for SCTE-35 ad-marker passthrough.

Last updated: July 4, 2026 — StreamingVPS.com Engineering Team.

Leave a Reply

Your email address will not be published. Required fields are marked *