{"id":1764,"date":"2026-07-16T13:00:00","date_gmt":"2026-07-16T18:00:00","guid":{"rendered":"https:\/\/tolinku.com\/blog\/?p=1764"},"modified":"2026-03-07T03:50:08","modified_gmt":"2026-03-07T08:50:08","slug":"incrementality-testing-mobile","status":"publish","type":"post","link":"https:\/\/tolinku.com\/blog\/incrementality-testing-mobile\/","title":{"rendered":"Incrementality Testing for Mobile Marketing"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Attribution tells you who converted after seeing your ad. Incrementality testing tells you who converted because of your ad. The difference is critical: if 60% of the users your campaign &quot;converted&quot; would have converted anyway, your true ROAS is 40% of what your attribution dashboard shows.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This guide covers how to run incrementality tests for mobile marketing. For A\/B testing deep links, see <a href=\"https:\/\/tolinku.com\/blog\/ab-testing-deep-links-landing-pages\/\">A\/B testing deep links and landing pages<\/a>. For attribution models, see <a href=\"https:\/\/tolinku.com\/blog\/last-click-vs-multi-touch-attribution\/\">last-click vs multi-touch attribution<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What Incrementality Measures<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">The Core Question<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">&quot;If I had not run this campaign, how many conversions would I have lost?&quot;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Attributed conversions:<\/strong> 10,000 installs credited to a Facebook campaign.<\/li>\n<li><strong>Incremental conversions:<\/strong> 4,000 installs that would not have happened without the campaign.<\/li>\n<li><strong>Non-incremental:<\/strong> 6,000 installs that would have happened anyway (organic users who also saw an ad).<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The incrementality rate is 40% (4,000 \/ 10,000). The true CPI is 2.5x higher than the attributed CPI.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Test Design<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Intent-to-Treat (ITT) Test<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The most common incrementality test for mobile:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Define the target audience (e.g., all users in the US who match your targeting criteria).<\/li>\n<li>Randomly split into a test group (80%) and a holdout group (20%).<\/li>\n<li>The test group sees your ads.<\/li>\n<li>The holdout group does not see your ads (they are excluded from the ad campaign).<\/li>\n<li>After the test period, compare conversion rates between the two groups.<\/li>\n<\/ol>\n\n\n\n<pre><code>Test Group (80%):     Sees ads \u2192 2.5% install rate\nHoldout Group (20%):  No ads   \u2192 1.5% install rate\n\nIncremental lift: 2.5% - 1.5% = 1.0 percentage points\nIncrementality rate: 1.0% \/ 2.5% = 40%\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Ghost Ads \/ PSA Test<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of simply not showing ads to the holdout group, show them a public service announcement (PSA) or charity ad. This controls for the &quot;any ad exposure&quot; effect:<\/p>\n\n\n\n<pre><code>Test Group:    Sees your ad  \u2192 2.5% install rate\nPSA Group:     Sees PSA ad   \u2192 1.6% install rate\n\nIncremental lift: 2.5% - 1.6% = 0.9 percentage points\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Geographic Holdout<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of user-level randomization, exclude entire geographic regions:<\/p>\n\n\n\n<pre><code>Test markets (80% of cities):    Run campaigns normally\nHoldout markets (20% of cities): No campaigns\n\nCompare install rates in test vs holdout markets\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Geographic holdouts are easier to implement (no need for user-level targeting exclusions) but require more cities to achieve statistical significance.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Running the Test<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Define Hypotheses<\/h3>\n\n\n\n<pre><code>H0 (null): The campaign has no incremental impact on installs\nH1 (alternative): The campaign drives incremental installs\n\nTarget: 95% confidence level\nMinimum detectable effect: 20% lift\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Calculate Sample Size<\/h3>\n\n\n\n<pre><code class=\"language-python\">from scipy import stats\nimport math\n\ndef required_sample_size(\n    baseline_rate: float,\n    minimum_detectable_effect: float,\n    confidence: float = 0.95,\n    power: float = 0.80\n) -&gt; int:\n    alpha = 1 - confidence\n    z_alpha = stats.norm.ppf(1 - alpha \/ 2)\n    z_beta = stats.norm.ppf(power)\n\n    p1 = baseline_rate\n    p2 = baseline_rate * (1 + minimum_detectable_effect)\n\n    n = ((z_alpha * math.sqrt(2 * p1 * (1 - p1)) +\n          z_beta * math.sqrt(p1 * (1 - p1) + p2 * (1 - p2))) \/\n         (p2 - p1)) ** 2\n\n    return math.ceil(n)\n\n# Example: 1.5% baseline, detect 20% lift, 95% confidence\nsample_size = required_sample_size(0.015, 0.20)\n# Result: ~85,000 users per group\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Run the Test<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Duration: 2-4 weeks minimum (longer for lower-frequency events).<\/li>\n<li>Monitor for contamination (holdout users seeing ads through shared devices).<\/li>\n<li>Do not peek at results before the planned end date (p-hacking risk).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Analyze Results<\/h3>\n\n\n\n<pre><code class=\"language-python\">def analyze_incrementality(\n    test_conversions: int, test_size: int,\n    holdout_conversions: int, holdout_size: int\n):\n    test_rate = test_conversions \/ test_size\n    holdout_rate = holdout_conversions \/ holdout_size\n\n    lift = test_rate - holdout_rate\n    relative_lift = lift \/ holdout_rate if holdout_rate &gt; 0 else float(&#39;inf&#39;)\n    incrementality_rate = lift \/ test_rate if test_rate &gt; 0 else 0\n\n    # Statistical significance (chi-squared test)\n    chi2, p_value = stats.chi2_contingency([\n        [test_conversions, test_size - test_conversions],\n        [holdout_conversions, holdout_size - holdout_conversions]\n    ])[:2]\n\n    return {\n        &#39;test_rate&#39;: test_rate,\n        &#39;holdout_rate&#39;: holdout_rate,\n        &#39;absolute_lift&#39;: lift,\n        &#39;relative_lift&#39;: relative_lift,\n        &#39;incrementality_rate&#39;: incrementality_rate,\n        &#39;p_value&#39;: p_value,\n        &#39;significant&#39;: p_value &lt; 0.05\n    }\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Interpreting Results<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Scenario Analysis<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Scenario<\/th>\n<th>Test Rate<\/th>\n<th>Holdout Rate<\/th>\n<th>Lift<\/th>\n<th>Action<\/th>\n<\/tr>\n<\/thead>\n<tbody><tr>\n<td>High incrementality<\/td>\n<td>3.0%<\/td>\n<td>1.0%<\/td>\n<td>2.0pp<\/td>\n<td>Scale the campaign<\/td>\n<\/tr>\n<tr>\n<td>Moderate incrementality<\/td>\n<td>2.5%<\/td>\n<td>1.5%<\/td>\n<td>1.0pp<\/td>\n<td>Continue, optimize targeting<\/td>\n<\/tr>\n<tr>\n<td>Low incrementality<\/td>\n<td>2.0%<\/td>\n<td>1.8%<\/td>\n<td>0.2pp<\/td>\n<td>Reduce spend, retest<\/td>\n<\/tr>\n<tr>\n<td>No incrementality<\/td>\n<td>2.0%<\/td>\n<td>2.0%<\/td>\n<td>0.0pp<\/td>\n<td>Stop the campaign<\/td>\n<\/tr>\n<tr>\n<td>Negative impact<\/td>\n<td>1.5%<\/td>\n<td>2.0%<\/td>\n<td>-0.5pp<\/td>\n<td>Stop immediately (ad fatigue)<\/td>\n<\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Calculating True ROAS<\/h3>\n\n\n\n<pre><code>Campaign spend: $50,000\nAttributed installs: 10,000\nAttributed CPI: $5.00\n\nIncrementality rate: 40%\nIncremental installs: 4,000\nTrue incremental CPI: $12.50\n\nIf LTV per user is $15:\n  Attributed ROAS: $15 \/ $5 = 300% (looks great)\n  True incremental ROAS: $15 \/ $12.50 = 120% (barely profitable)\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Testing Frequency<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Campaign Type<\/th>\n<th>Test Frequency<\/th>\n<th>Duration<\/th>\n<\/tr>\n<\/thead>\n<tbody><tr>\n<td>Always-on campaigns<\/td>\n<td>Quarterly<\/td>\n<td>4 weeks<\/td>\n<\/tr>\n<tr>\n<td>New channel launch<\/td>\n<td>Before scaling<\/td>\n<td>2-4 weeks<\/td>\n<\/tr>\n<tr>\n<td>Major creative change<\/td>\n<td>After launch<\/td>\n<td>2 weeks<\/td>\n<\/tr>\n<tr>\n<td>Seasonal campaigns<\/td>\n<td>Before and during<\/td>\n<td>1-2 weeks<\/td>\n<\/tr>\n<tr>\n<td>Retargeting<\/td>\n<td>Bi-annually<\/td>\n<td>4 weeks<\/td>\n<\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Retargeting campaigns often have the lowest incrementality because they target users who are already likely to convert.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Common Pitfalls<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Testing too briefly.<\/strong> Underpowered tests produce unreliable results. Run until you reach the required sample size.<\/li>\n<li><strong>Contamination.<\/strong> If holdout users see your ads through another channel (e.g., a friend&#39;s shared link), the test is contaminated.<\/li>\n<li><strong>Seasonality.<\/strong> Running a test during Black Friday will produce different results than running it in January.<\/li>\n<li><strong>Selection bias.<\/strong> The test and holdout groups must be truly random. If the holdout group is systematically different, results are invalid.<\/li>\n<li><strong>One-time tests.<\/strong> Incrementality changes over time. A campaign that was incremental 6 months ago may not be incremental today.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Tolinku for Experimentation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/tolinku.com\/features\/ab-testing\">Tolinku<\/a> supports A\/B testing for deep links, which can be used as part of incrementality testing. Route different user segments to different experiences and measure conversion differences. Configure experiments in the <a href=\"https:\/\/tolinku.com\/features\/analytics\">Tolinku dashboard<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For attribution models, see <a href=\"https:\/\/tolinku.com\/blog\/last-click-vs-multi-touch-attribution\/\">last-click vs multi-touch attribution<\/a>. For mobile attribution, see <a href=\"https:\/\/tolinku.com\/blog\/mobile-attribution-developers-guide\/\">mobile attribution: a developer&#39;s guide<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Measure the true incremental impact of your mobile campaigns. Design holdout tests, calculate lift, and prove marketing effectiveness.<\/p>\n","protected":false},"author":2,"featured_media":1763,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"rank_math_title":"Incrementality Testing for Mobile Marketing","rank_math_description":"Measure the true incremental impact of your mobile campaigns. Design holdout tests, calculate lift, and prove marketing effectiveness.","rank_math_focus_keyword":"incrementality testing mobile","rank_math_canonical_url":"","rank_math_facebook_title":"","rank_math_facebook_description":"","rank_math_facebook_image":"https:\/\/tolinku.com\/blog\/wp-content\/uploads\/2026\/03\/og-incrementality-testing-mobile.png","rank_math_facebook_image_id":"","rank_math_twitter_title":"","rank_math_twitter_description":"","rank_math_twitter_image":"https:\/\/tolinku.com\/blog\/wp-content\/uploads\/2026\/03\/og-incrementality-testing-mobile.png","footnotes":""},"categories":[14],"tags":[60,37,28,520,20,225,531,69],"class_list":["post-1764","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-analytics","tag-ab-testing","tag-analytics","tag-attribution","tag-campaign-measurement","tag-deep-linking","tag-experimentation","tag-incrementality","tag-mobile-development"],"_links":{"self":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1764","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/comments?post=1764"}],"version-history":[{"count":3,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1764\/revisions"}],"predecessor-version":[{"id":2702,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1764\/revisions\/2702"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/media\/1763"}],"wp:attachment":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/media?parent=1764"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/categories?post=1764"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/tags?post=1764"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}