Why 5MB, specifically

It's not a coincidence that Google Ads, Meta, AppLovin, Unity Ads, Vungle, Mintegral, and TikTok all converge on the same number. Playable ads run inside a mobile webview embedded in another app, often on a cellular connection, and the creative has to load and become interactive within a second or two or the user has already swiped past it. 5 MB is roughly the point every one of these networks independently settled on as "loads fast enough on average mobile conditions without being so restrictive that a real playable can't fit." It's a rendering and bandwidth budget more than an arbitrary rule, which is why it shows up everywhere instead of varying network to network.

NetworkHard capRecommended target
Google Ads5 MB
Meta (Facebook)5 MB2 MB
AppLovin5 MB
Unity Ads5 MB2 MB
Vungle (Liftoff)5 MB
Mintegral5 MB
TikTok5 MB (post-compression)

Meta and Unity Ads publish 2 MB as an explicit recommendation on top of the 5 MB hard cap, because both note that rendering and review get less forgiving the closer a creative sits to the ceiling. Every other network in the list enforces 5 MB as the number that actually gates upload — there's no network here with a materially different byte limit, only different packaging rules for what counts against it (a ZIP that can span multiple files vs. a single self-contained HTML file).

What actually pushes a build over the line

  • Base64 encoding overhead. AppLovin, Meta, Unity Ads, and Vungle require every asset embedded inline with zero external requests, and the standard way to embed binary data as text is base64 — which turns every 3 bytes of source data into 4 bytes of encoded text, roughly 33% overhead. A build that's comfortably under 5 MB as raw files can cross the line the moment it's encoded for a network that requires inline embedding.
  • Uncompressed source assets. Full-resolution PNGs where a compressed JPEG or WebP would do, uncompressed WAV audio, or texture atlases sized well beyond the canvas a playable actually renders at. This weight originates at the source and carries straight through conversion — no packaging step removes it.
  • Unused or duplicate assets. Textures, sounds, and scene data left over from earlier creative iterations, or multiple aspect-ratio/language variants bundled into one export when only one is ever shown, still get packaged and still count against the same cap.
  • Video and audio bitrate. Embedded video is by far the densest asset type in a playable — a few seconds of lightly compressed video can outweigh every other asset combined. The bitrate and codec chosen when that clip was exported matters more than anything applied downstream.

Measure the real number, not the source ZIP

Checking your raw export's file size and comparing it to 5 MB is a guess, not a measurement, and it can mislead in either direction. The real converted size can be larger than the raw export because base64 embedding adds overhead a relative-path reference didn't need, or smaller because a raw export often carries multiple cache generations that get dropped during proper conversion. Either way, the only number that matters is the size of the final, network-specific, encoded package — which is what each network's own upload actually measures against its cap.

PlayableKit's free Size Checker runs your real export through the same conversion pipeline used for paid builds, once per network, and reports the actual resulting byte size against each network's real limit — no estimating, no guessing from the upload.

Fixing it, in priority order

  1. Compress source assets before export. This is the highest-leverage fix and the only one that happens upstream, in the Unity project — no downstream conversion step can shrink an oversized texture or an uncompressed audio clip after the fact.
  2. Re-encode video and audio at a sane bitrate. If the playable embeds video, the resolution and bitrate chosen at export dwarf everything else in the size budget. Fix this before touching anything else if video is present.
  3. Strip unused and duplicate assets. Remove textures, audio, and variants the specific instance you're shipping doesn't reference. This is often the fastest win because it requires no re-authoring, just cleanup.
  4. Check the real converted size per network, not once. Because base64 overhead and packaging rules differ by network, a build that passes for Google can still fail for Meta from the same source. Re-check after every asset change rather than treating one pass as permanent.
Worth knowing: PlayableKit's converter and Size Checker measure and package your build accurately, but neither is an image or audio re-compression tool — if your source assets are heavy, the converted output will be heavy too. For a deeper breakdown of exactly how base64 inflation and per-network encoding differences interact, see Playable ad compression and size limits, explained honestly. If your build is a Unity Playworks/Luna export specifically, Unity Playworks/Luna build too large: what to check covers the causes particular to that pipeline.