← All reports

Interstitial ads load successfully ~3% of the time

Ad request/show funnel · GA4 raw export analytics_538412813 · generated 2026-09-22

Interstitial ad loads succeed 3.0% of the time (28,449 of 943,813 attempts); rewarded video loads succeed 40.7% of the time (54,094 of 133,006). Measured from ad_request_status (status = success/ fail), the whole export, 2026-07-01 to yesterday.

The dominant cause isn't "no ad available" — it's the mediation SDK failing to reach its own server. 591,164 interstitial attempts (65% of all fails) error with a DNS/connect failure to ms.applvn.com, AppLovin MAX's own mediation host — not a shortage of ads, a networking problem.

This affects a broad slice of the base, not a few looping devices: 23% of users who requested an interstitial hit this failure at least once (5,416 of 23,436), averaging ~109 failed attempts each — consistent with a client retry loop hammering an unreachable host.

0 · What's changed in the last few days

Engineering has already root-caused part of a fresh decline in rewarded fill, separate from the DNS/connect problem above: AppLovin's mediation server is returning ad responses for the REWARDED_INTER (Rewarded Interstitial) format without the ad_format field the client's MAX SDK expects. The SDK doesn't recognize the format, treats the response as No Fill (error 204), and the ad never becomes "ready" — a player who taps gets a "not ready" toast even though AppLovin did return something. This is a client-SDK/server-format mismatch, not a lack of inventory.

The data shows a matching pattern over the last 10 days: rewarded fill rate slid from 67% on 2026-09-13 to 44% on 2026-09-21 (choppy day to day, but the last full day is well below the first), while interstitial attempt volume surged from a baseline around 3,383/day to a peak of 15,946 attempts on 2026-09-20 — roughly 5× baseline — before easing back down, tracking the same days rewarded fill was at its worst. Interstitial fill rate stayed in the low single digits throughout, so this substitution is not recovering the failed ad opportunity, just changing what's being retried.

DayAd typeAttemptsFill rate
2026-09-13inter3,3838.1%
2026-09-14inter3,6397.3%
2026-09-15inter5,5863.6%
2026-09-16inter5,7473.7%
2026-09-17inter7,8663.1%
2026-09-18inter11,4622.1%
2026-09-19inter6,0287.8%
2026-09-20inter15,9463.3%
2026-09-21inter2,93311.1%
2026-09-22inter76819.0%
2026-09-13rewarded89166.8%
2026-09-14rewarded80556.5%
2026-09-15rewarded94847.7%
2026-09-16rewarded97263.6%
2026-09-17rewarded1,22750.9%
2026-09-18rewarded1,29235.3%
2026-09-19rewarded1,42348.8%
2026-09-20rewarded2,15635.9%
2026-09-21rewarded1,21544.1%
2026-09-22rewarded46362.4%

The last-10-days query:

SELECT
  PARSE_DATE('%Y%m%d', event_date) AS day,
  (SELECT value.string_value FROM UNNEST(event_params) WHERE key='ad_type') AS ad_type,
  (SELECT value.string_value FROM UNNEST(event_params) WHERE key='status') AS status,
  COUNT(*) AS n
FROM `tiny-knightfall-idle-rpg-game.analytics_538412813.events_intraday_*`
WHERE event_name = 'ad_request_status'
  AND _TABLE_SUFFIX BETWEEN '20260913' AND '20260922'
GROUP BY day, ad_type, status
ORDER BY day, ad_type

1 · Fill rate by ad type

ad_request_status is the load outcome event — status = success or fail, with which network filled it and the raw SDK error on failure. This is the standard fill/fail-rate signal, and it's been live since build 5 (2026-07-01), so the whole export has consistent instrumentation.

Ad typeAttemptsSuccessFailFill rate
inter943,81328,449915,3643.0%
rewarded133,00654,09478,91240.7%

2 · Daily fill-rate trend

Today's shard is partial and excluded. Both lines are consistently low across the whole window — this is not a one-day blip.

interstitial rewarded
0%25%50%75%100%interstitial 11%rewarded 44%Jul 01Jul 14Jul 28Aug 11Aug 24Sep 07Sep 21

The query behind sections 1, 2, 3 and 4 — copy and re-run it:

SELECT
  PARSE_DATE('%Y%m%d', event_date) AS day,
  (SELECT value.string_value FROM UNNEST(event_params) WHERE key='ad_type') AS ad_type,
  (SELECT value.string_value FROM UNNEST(event_params) WHERE key='ad_network') AS ad_network,
  (SELECT value.string_value FROM UNNEST(event_params) WHERE key='status') AS status,
  CASE
    WHEN (SELECT value.string_value FROM UNNEST(event_params) WHERE key='error') IS NULL THEN NULL
    WHEN (SELECT value.string_value FROM UNNEST(event_params) WHERE key='error') LIKE '%applvn.com%' THEN 'AppLovin MAX mediation server unreachable (DNS/connect)'
    WHEN (SELECT value.string_value FROM UNNEST(event_params) WHERE key='error') LIKE '%No Fill%' OR (SELECT value.string_value FROM UNNEST(event_params) WHERE key='error') LIKE '%no eligible ads%' THEN 'No fill (no ad available)'
    WHEN (SELECT value.string_value FROM UNNEST(event_params) WHERE key='error') LIKE '%timeout%' OR (SELECT value.string_value FROM UNNEST(event_params) WHERE key='error') LIKE '%timed out%' THEN 'Timeout'
    WHEN (SELECT value.string_value FROM UNNEST(event_params) WHERE key='error') LIKE '%onnection%' OR (SELECT value.string_value FROM UNNEST(event_params) WHERE key='error') LIKE 'unexpected end of stream%' THEN 'Connection dropped mid-request'
    WHEN (SELECT value.string_value FROM UNNEST(event_params) WHERE key='error') LIKE '%JSONException%' THEN 'Malformed mediation response (JSON parse error)'
    ELSE 'Other'
  END AS error_bucket,
  COUNT(*) AS n
FROM `tiny-knightfall-idle-rpg-game.analytics_538412813.events_intraday_*`
WHERE event_name = 'ad_request_status'
GROUP BY day, ad_type, ad_network, status, error_bucket
ORDER BY day

3 · Which network fills, when a load does succeed

Ad typeNetworkSuccessful loadsShare
interAppLovin13,41947.2%
interMintegral7,06024.8%
interGoogle AdMob5,39919.0%
interDT Exchange8623.0%
interLiftoff Monetize6932.4%
interAPPLOVIN_EXCHANGE5361.9%
interFacebook4801.7%
rewardedAppLovin24,35845.0%
rewardedGoogle AdMob15,28928.3%
rewardedMintegral7,95614.7%
rewardedFacebook3,7466.9%
rewardedDT Exchange1,1612.1%
rewardedLiftoff Monetize9351.7%
rewardedAPPLOVIN_EXCHANGE6461.2%
rewardedIronSource30.0%

4 · Why loads fail

Ad typeReasonEventsShare of fails
interAppLovin MAX mediation server unreachable (DNS/connect)591,16464.6%
inter(no error string recorded)296,45932.4%
interNo fill (no ad available)14,1161.5%
interConnection dropped mid-request10,0791.1%
interOther3,0200.3%
interTimeout5260.1%
rewardedAppLovin MAX mediation server unreachable (DNS/connect)46,55559.0%
rewarded(no error string recorded)28,83736.5%
rewardedConnection dropped mid-request1,5502.0%
rewardedNo fill (no ad available)1,3911.8%
rewardedOther3290.4%
rewardedTimeout2500.3%

~32-37% of failures carry no error string at all (the SDK set status=fail but the error param is empty) — a real instrumentation gap; right now there's no way to tell what's behind that bucket. Genuine "no fill" (the network legitimately having nothing to serve) is a small minority of failures for both ad types.

5 · The rest of the funnel — and two unexplained gaps

EventCountPeak daily usersFirst seenLast seen
ad_request1,930,7081,1372026-07-012026-09-22
ad_request_status1,076,8197652026-07-012026-09-22
ad_reward41,2141722026-07-152026-09-22
show_ad_click34,4741972026-06-292026-09-22
ad_show29,1071532026-07-042026-09-22
show_ad_inter_backup_failed3,183282026-07-052026-09-22
show_ad_inter_backup677102026-07-052026-09-22
ad_rewarded_show_failed8932026-07-092026-09-21

The funnel query:

SELECT
  event_name,
  PARSE_DATE('%Y%m%d', event_date) AS day,
  COUNT(*) AS n,
  COUNT(DISTINCT user_pseudo_id) AS users
FROM `tiny-knightfall-idle-rpg-game.analytics_538412813.events_intraday_*`
WHERE event_name IN ('show_ad_click','ad_request','ad_request_status','ad_show','ad_reward',
                      'ad_rewarded_show_failed','show_ad_inter_backup','show_ad_inter_backup_failed')
GROUP BY event_name, day
ORDER BY event_name, day

The concentration check (section verdict, para 3):

WITH s AS (
  SELECT
    user_pseudo_id,
    (SELECT value.string_value FROM UNNEST(event_params) WHERE key='ad_type') AS ad_type,
    (SELECT value.string_value FROM UNNEST(event_params) WHERE key='status') AS status,
    (SELECT value.string_value FROM UNNEST(event_params) WHERE key='error') AS error
  FROM `tiny-knightfall-idle-rpg-game.analytics_538412813.events_intraday_*`
  WHERE event_name = 'ad_request_status'
)
SELECT
  ad_type,
  COUNT(DISTINCT user_pseudo_id) AS users_total,
  COUNT(DISTINCT IF(status='fail' AND error LIKE '%applvn.com%', user_pseudo_id, NULL)) AS users_with_dns_fail,
  COUNTIF(status='fail' AND error LIKE '%applvn.com%') AS dns_fail_events
FROM s
GROUP BY ad_type

6 · Reading this number