DEV Community

unity source code
unity source code

Posted on

Unity Ads vs AdMob vs AppLovin MAX: A Developer’s Guide to Unity Game Monetization in 2026

Every mobile game developer eventually hits the same wall: the game works, players are installing it, retention curves look decent — and then it's time to actually make money from it. That's when you're staring at three SDK options that all promise to be "the best," and no clear technical explanation of what actually separates them.

This is a developer-focused breakdown of Unity Ads (now Unity LevelPlay), Google AdMob, and AppLovin MAX — what's actually happening under the hood when you integrate each one, how their auction mechanics differ, what the SDK integration looks like in practice, and which one fits your project depending on your engine, your traffic, and your growth stage.

If you want the business-side breakdown with revenue benchmarks and eCPM tables, there's a companion piece covering that in more depth: Unity Ads vs. AdMob vs. AppLovin MAX: Choosing an Ad Network in 2026. This article focuses on the engineering side — what you're actually integrating and why it behaves the way it does.


Ad Network vs. Mediation Layer: The Architecture You're Actually Building

Before touching any SDK, it's worth understanding the two distinct pieces of infrastructure you're dealing with, because conflating them leads to bad architecture decisions later.

An ad network is a demand source — a company with advertisers who bid to show ads inside your app. Google's AdMob network and AppLovin's own ad exchange are both, at their core, demand sources.

A mediation SDK is an orchestration layer. It sits between your game and multiple demand sources, runs an auction (or a waterfall) for every single ad request, and routes the impression to whichever source wins. Unity LevelPlay, AdMob Mediation, and AppLovin MAX are all mediation SDKs, not just networks.

From an architecture standpoint, this means you should almost never integrate a single ad network directly and call it done. You integrate one mediation SDK, and that mediation SDK talks to multiple demand sources on your behalf, including — confusingly — sometimes the exact platform whose mediation SDK you're not using. For example, you can run AdMob as a demand source inside AppLovin MAX's mediation layer, or run Unity Ads as a bidder inside AdMob Mediation.

This is the single most common architectural mistake in indie ad integrations: developers integrate two full mediation SDKs side by side (say, both LevelPlay and MAX), assuming this doubles their demand. In practice it creates duplicate ad requests, inflated latency, and auction conflicts where both SDKs are independently trying to control the same ad unit. Pick one mediation controller. Plug everything else in as a demand source beneath it.


Unity Ads / LevelPlay: Integration and Behavior

If your game is built in Unity, this is the path of least resistance simply because the SDK lives in the editor and the Package Manager handles most of the setup.

The migration you need to know about

If you're working on an older codebase, check your dependencies immediately. The legacy com.unity.ads Advertisement package is deprecated. Unity has consolidated everything under the LevelPlay Ads Mediation package (com.unity.services.levelplay), following the ironSource merger. Waterfall-only support for the legacy integration ended, and apps still shipping the old package will see silently degrading fill and eCPM — no crash, no error log, just a slow bleed in your analytics dashboard.

If you see this in your manifest.json:

"com.unity.ads": "4.x.x"
Enter fullscreen mode Exit fullscreen mode

Replace it with the current LevelPlay package and migrate your initialization calls. A minimal LevelPlay initialization looks like this:

using Unity.Services.LevelPlay;

public class AdManager : MonoBehaviour
{
    void Start()
    {
        LevelPlay.OnInitSuccess += OnInitSuccess;
        LevelPlay.OnInitFailed += OnInitFailed;
        LevelPlay.Init("YOUR_APP_KEY");
    }

    void OnInitSuccess(LevelPlayConfiguration config)
    {
        LoadRewardedAd();
    }

    void OnInitFailed(LevelPlayInitError error)
    {
        Debug.LogError($"LevelPlay init failed: {error}");
    }

    void LoadRewardedAd()
    {
        var rewardedAd = new LevelPlayRewardedAd("YOUR_AD_UNIT_ID");
        rewardedAd.OnAdLoaded += (adInfo) => rewardedAd.ShowAd();
        rewardedAd.LoadAd();
    }
}
Enter fullscreen mode Exit fullscreen mode

What this gets you technically

  • A hybrid auction model — some networks bid in real time, others still sit in a manually ordered waterfall beneath the bidders.
  • Built-in Ad Quality tooling that reports which creatives are actually rendering, so you can programmatically block low-quality or misleading ads that hurt session length.
  • Tight coupling with Unity's build pipeline — no manual Gradle or CocoaPods wrangling for the base SDK, though individual bidding adapters still need their own dependency resolution.

Where the friction shows up

Adding additional demand partners as bidders requires configuring each adapter through the LevelPlay dashboard and importing per-network SDK adapters, which adds real weight to your build size if you're not careful about which ones you actually enable. If you're chasing minimal APK/IPA size, only enable adapters you've verified are contributing meaningful fill in your target geographies.


Google AdMob: Integration and Behavior

AdMob remains the fastest SDK to get to a working ad on screen, which is exactly why it's the default recommendation for a first release.

Basic integration

using GoogleMobileAds.Api;

public class AdMobManager : MonoBehaviour
{
    private RewardedAd rewardedAd;

    void Start()
    {
        MobileAds.Initialize(initStatus => { LoadRewardedAd(); });
    }

    void LoadRewardedAd()
    {
        var adRequest = new AdRequest();
        RewardedAd.Load("YOUR_AD_UNIT_ID", adRequest, (ad, error) =>
        {
            if (error != null || ad == null)
            {
                Debug.LogError("Rewarded ad failed to load: " + error);
                return;
            }
            rewardedAd = ad;
        });
    }

    public void ShowRewardedAd()
    {
        if (rewardedAd != null && rewardedAd.CanShowAd())
        {
            rewardedAd.Show((Reward reward) =>
            {
                // grant reward here
            });
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Technical strengths

  • Bidding infrastructure is mature. AdMob's Open Bidding lets multiple third-party networks compete alongside Google's own demand in a unified auction, and enabling it is largely a dashboard configuration change rather than a code change.
  • Firebase integration is near-seamless, since AdMob and Firebase Analytics share the same underlying event pipeline — useful if you're already tracking custom in-game events for LTV modeling.
  • Mediation adapter management is handled centrally through the AdMob console, and adapter versions are generally well maintained and quick to receive updates for new OS versions.

Technical weaknesses

  • Auction reporting is comparatively shallow. You get eCPM by ad source, but not the granular per-request bid transparency that MAX exposes.
  • Because Google's own demand competes inside the same auction Google operates, some developers build independent verification layers (comparing observed eCPM against expected benchmarks) to sanity-check performance rather than trusting the dashboard blindly.
  • SDK policy violations can trigger account-level restrictions with limited immediate developer recourse — build your ad request error handling defensively, including fallback behavior if AdMob serving is suspended.

AppLovin MAX: Integration and Behavior

MAX is the most engineering-intensive of the three, but also the one with the deepest auction and the most granular reporting.

Basic integration

using MaxSdk = MaxSdkBase;

public class MaxAdManager : MonoBehaviour
{
    void Start()
    {
        MaxSdkCallbacks.OnSdkInitializedEvent += (config) =>
        {
            InitializeRewardedAds();
        };
        MaxSdk.SetSdkKey("YOUR_SDK_KEY");
        MaxSdk.InitializeSdk();
    }

    void InitializeRewardedAds()
    {
        MaxSdkCallbacks.Rewarded.OnAdLoadedEvent += (adUnitId, adInfo) =>
        {
            MaxSdk.ShowRewardedAd(adUnitId);
        };
        MaxSdkCallbacks.Rewarded.OnAdLoadFailedEvent += (adUnitId, errorInfo) =>
        {
            Debug.LogError("Rewarded ad failed: " + errorInfo);
        };
        MaxSdk.LoadRewardedAd("YOUR_AD_UNIT_ID");
    }
}
Enter fullscreen mode Exit fullscreen mode

What sets it apart technically

  • Unified real-time bidding auction across dozens of connected networks, meaning your waterfall configuration work is largely replaced by a single continuous auction that self-optimizes.
  • MAX Rules and Audience Segments let you programmatically adjust ad frequency, floor prices, and even which ad units load based on player segment — this is done through the dashboard but reflected in real time in your app without a rebuild.
  • Detailed per-network reporting, down to individual bidder-level eCPM, latency, and fill rate — useful if you're doing serious data-driven optimization rather than "set it and forget it" monetization.

The trade-offs

  • MAX isn't self-serve in the way AdMob is. Your app goes through an approval process, and getting declined is common for apps without meaningful daily traffic.
  • Onboarding requires configuring and testing each network adapter individually if you want full bidder coverage — expect real setup time, not a quick drop-in.
  • AppLovin's own demand competes in the same auction, so, like AdMob, it isn't a fully neutral arbiter.

What actually gets an app through MAX review

  1. A live, published build on the App Store or Google Play — a test build or internal APK won't be considered.
  2. Real daily active users. A few thousand DAU makes approval straightforward; near-zero traffic apps are routinely deprioritized.
  3. Genuinely original content. If you're shipping something built from a template or source code, this is the part reviewers scrutinize most — obvious, unmodified reskins get flagged. A fast-paced action title like a 3D sniper shooter template can pass review comfortably if you've meaningfully differentiated the art, level design, or progression systems from the base build, but not if you've shipped it unchanged.
  4. A correctly configured privacy policy and SDK privacy manifest — MAX checks this as part of onboarding, and it's also required by both app stores independently.
  5. A developer account with no active policy strikes.

Bidding vs. Waterfall: The Underlying Auction Mechanics

This is worth understanding at a technical level because it explains why switching auction models moves revenue more than switching SDKs does.

Waterfall mediation works sequentially: your mediation SDK calls Network A first, and if Network A doesn't return a fill above its configured floor price, it calls Network B, then C, and so on, until something fills or the chain is exhausted. This means:

  • The network at the top of the waterfall never has to compete — it just has to clear its own floor.
  • You're manually maintaining and reordering that priority list based on historical performance, which quickly becomes stale as market conditions shift.
  • Latency compounds with each sequential call in the chain.

In-app bidding replaces this with a single simultaneous auction: every connected bidder receives the ad request at the same time, returns a bid, and the mediation layer awards the impression to the highest bidder — closer to a real-time second-price auction than a sequential waterfall. Because every bidder is forced to compete against every other bidder on every single request, publishers see meaningfully higher effective eCPM with no other change to their app.

All three platforms have moved toward bidding as the default, but they're at different points on that migration:

  • MAX is furthest along — nearly bidding-only today.
  • AdMob runs bidding and legacy waterfall groups side by side, and you configure this through the mediation groups panel.
  • LevelPlay runs a hybrid model, blending bidding networks with a manually configured waterfall underneath for partners that don't yet support real-time bidding.

For most mid-sized projects, a hybrid configuration — bidding as the primary mechanism, with a thin manual waterfall beneath it for any high-floor direct deals — remains the most reliable setup, and it's what all three platforms effectively default to today.


Format-Level Implementation Details

Ad network choice affects revenue less than how you implement individual formats. A few implementation details that matter regardless of which SDK you're using:

Rewarded video

Always gate the reward behind the OnAdCompleted (or equivalent) callback, never behind OnAdShown. Players who skip or the ad fails partway through should not receive the reward — this is both a policy requirement across all three networks and a design requirement to avoid training players to abuse the mechanic.

rewardedAd.OnAdRevenuePaid += (adInfo) =>
{
    // Log ad revenue event to your analytics/attribution pipeline
    LogAdRevenueEvent(adInfo);
};
Enter fullscreen mode Exit fullscreen mode

Logging the OnAdRevenuePaid (or equivalent impression-level revenue) callback into your analytics pipeline is worth doing on day one — it's what lets you calculate LTV that blends IAP and ad revenue together, rather than treating them as separate reporting silos.

Interstitials

Implement a cooldown timer independent of the SDK's own capping:

private float lastInterstitialTime = -999f;
private const float MinIntervalSeconds = 60f;

public bool CanShowInterstitial()
{
    return Time.time - lastInterstitialTime >= MinIntervalSeconds;
}
Enter fullscreen mode Exit fullscreen mode

Don't rely solely on network-side frequency capping — it's configured per ad unit on the dashboard, but a client-side check protects you from mistakes if the dashboard config ever gets reset or misconfigured during a migration.

Preloading

Regardless of network, always preload the next ad immediately after showing one, rather than loading on-demand when the placement triggers. Load latency on a cold request can run into multiple seconds, which is long enough to break the perceived responsiveness of a "continue" or "double reward" placement.


Genre and Traffic Considerations for Architecture Decisions

The technical setup you choose should reflect your traffic profile, not just your engine. High-session-depth genres — combat, competitive, and progression-heavy titles — tend to justify the additional engineering investment of a MAX integration sooner, because their players generate enough daily impressions to make granular bidder-level optimization worthwhile. Lighter hyper-casual titles with shorter average sessions often see a better return from spending that same engineering time on LevelPlay's simpler hybrid setup instead, since the marginal eCPM gain from MAX's deeper auction doesn't offset the added integration and testing overhead until you're at meaningful scale.

If you want a hands-on look at how core mechanics and engineering decisions affect a game's monetization potential from the ground up, this piece on the engineering behind a tap-timing hyper-casual mechanic is a good technical companion read: Building a Tap-Timing Hyper-Casual Game in Unity. It's a useful reference for how a tightly scoped core loop generates the session frequency that makes any of these ad stacks worth optimizing in the first place.


A Practical Rollout Plan for Developers

  1. Phase 1 — Launch: Integrate AdMob directly. Get your ad request lifecycle, revenue logging, and format placements working correctly before adding any mediation complexity.
  2. Phase 2 — Bidding: Enable AdMob's Open Bidding and add one or two additional bidders (Unity Ads, Meta Audience Network) as demand sources. Compare eCPM and ARPDAU against your baseline for at least two weeks before drawing conclusions — auction calibration takes time.
  3. Phase 3 — Scale: Once you're consistently seeing a few thousand DAU, apply to AppLovin MAX or fully migrate to LevelPlay as your primary mediation controller, plugging your existing networks in beneath it as bidders.
  4. Phase 4 — Ongoing optimization: Continuously A/B test placement frequency, floor prices, and reward values. Treat your monetization configuration as a living system, not a one-time integration task.

Frequently Asked Questions

Can I use more than one mediation SDK at the same time?
Technically yes, but it's not recommended. Running two full mediation SDKs (say, both LevelPlay and MAX) side by side causes duplicate ad requests, increased latency, and auction conflicts, since both SDKs try to manage the same inventory independently. Pick one controller and plug the rest in as demand sources beneath it.

Do I need to migrate off the legacy Unity Ads package?
Yes. The legacy Advertisement package no longer receives feature updates, and direct integrations see reduced fill and performance over time. Migrate to the current LevelPlay Ads Mediation package.

Why is my measured eCPM lower than published benchmarks?
Almost always traffic quality and geography, not a misconfiguration. New ad units also go through a calibration period while the auction learns your traffic patterns — give it at least a couple of weeks before troubleshooting further.

Is AppLovin MAX difficult to integrate from an engineering standpoint?
It's more involved than AdMob or LevelPlay, mainly because of individual adapter configuration and testing for each bidder you enable. The core SDK integration itself is comparable in complexity, but the surrounding dashboard configuration work is heavier.

Should I build my own revenue analytics on top of ad SDK reporting?
Yes, if you're serious about LTV modeling. Logging impression-level ad revenue callbacks into your own analytics pipeline lets you combine ad and IAP revenue into a single LTV figure, which none of the three dashboards do natively out of the box.


Closing Thoughts

From a pure engineering standpoint, none of these three SDKs is objectively "better" — they're different tools for different traffic profiles and different stages of a game's life cycle. AdMob gets you to a working ad fastest. LevelPlay integrates most naturally if you're already deep in the Unity ecosystem. MAX rewards the engineering investment once you have the daily traffic to make its deeper auction worthwhile.

The bigger lesson for developers building monetization into a new project: get your revenue event logging and format implementation details right from day one, because those choices — reward gating, preloading, cooldown enforcement, revenue callback logging — matter more to your long-term numbers than which specific SDK logo sits at the top of your dependency list.

Top comments (0)