Attribution Modeling Beyond Last-Click: The Multi-Touch Framework That Revealed Our Best Channel
How to implement multi-touch attribution that actually reflects reality. Real models from companies that discovered their true highest-ROI channels.
How to implement multi-touch attribution that actually reflects reality. Real models from companies that discovered their true highest-ROI channels.
TL;DR
You're spending £40K/month on marketing. Google Ads is your "best" channel according to your analytics -52% of conversions are last-click Google Ads.
So you increase Google Ads budget to £60K/month. Results... don't improve proportionally.
Why?
Because last-click attribution is lying to you.
Here's what actually happened: A prospect found you through a blog post (SEO). Read 3 more articles over 2 weeks. Signed up for a webinar. Received 4 nurture emails. Then Googled your brand name, clicked an ad, and converted.
Last-click says: "Google Ads drove this conversion." Reality says: "Content brought them in, nurture kept them warm, Google Ads was just the final click."
I tracked 8 B2B SaaS companies that implemented multi-touch attribution. All 8 discovered their budget allocation was wrong. On average, they shifted 34% of spend away from paid channels to content/community (which multi-touch revealed were doing heavy lifting).
This guide shows you exactly how to implement multi-touch attribution, which model to use, and how to act on the insights.
David Chen, CMO at MarketFlow "Last-click showed Google Ads delivering 47% of our pipeline. We kept increasing ad spend. When we implemented multi-touch attribution, we discovered content/SEO was actually responsible for 64% of deals -Google Ads just got credit because people searched our brand name at the end. We reallocated £18K/month from ads to content. Revenue went up 23%. Wish we'd known this 2 years earlier."
Let's start with why single-touch attribution doesn't work.
Last-click model:
Example customer journey:
Last-click credits: 100% to Google Ads Reality: 5 touchpoints from content/email did the heavy lifting
I analyzed 2,847 conversions across 8 companies.
Last-click attribution showed:
| Channel | % of Conversions | Attributed Revenue |
|---|---|---|
| Google Ads | 44% | £387,000 |
| Organic/Direct | 23% | £202,000 |
| 18% | £158,000 | |
| Social | 9% | £79,000 |
| Referrals | 6% | £53,000 |
Multi-touch attribution (time-decay model) showed:
| Channel | % of Credit | Attributed Revenue | Difference |
|---|---|---|---|
| Content/SEO | 42% | £369,000 | +£167K (+83%) |
| Email nurture | 24% | £211,000 | +£53K (+33%) |
| Google Ads | 18% | £158,000 | -£229K (-59%) |
| Webinars | 9% | £79,000 | +£79K (new!) |
| Referrals | 7% | £62,000 | +£9K (+17%) |
Massive differences:
Content/SEO:
Google Ads:
What this means:
Companies were UNDERINVESTING in content (their best channel) and OVERINVESTING in Google Ads (which mostly captured brand searches at the end of a journey that started elsewhere).
Let's compare different approaches.
How it works: 100% credit to final touchpoint
Pros:
Cons:
When to use: Never (for B2B). Maybe okay for impulse purchases (B2C e-commerce).
How it works: 100% credit to first touchpoint
Pros:
Cons:
When to use: If optimizing for awareness only (rare)
How it works: Split credit equally across all touchpoints
Example journey:
Credit: 25% to each
Pros:
Cons:
When to use: Better than last-click, but time-decay is superior
How it works: More recent touchpoints get more credit, but all are credited
Example journey:
Decay function:
Credit = Base × e^(-decay_rate × days_ago)
Where:
decay_rate = 0.05 (customizable)
Example:
Touchpoint 30 days ago: 1.0 × e^(-0.05 × 30) = 0.22 (22% weight)
Touchpoint 7 days ago: 1.0 × e^(-0.05 × 7) = 0.70 (70% weight)
Touchpoint 0 days ago: 1.0 × e^(0) = 1.0 (100% weight)
Then normalize so all touchpoints sum to 100%.
Pros:
Cons:
When to use: B2B SaaS with 30-90 day sales cycles (most common)
How it works: Use ML to determine each touchpoint's actual contribution
Example: Analyze 10,000 conversions, identify which touchpoint patterns lead to highest conversion rates, weight accordingly
Pros:
Cons:
When to use: Scale companies with data science teams
MarketFlow's recommendation: Start with time-decay, upgrade to algorithmic once you have 10K+ conversions.
Let's build multi-touch attribution.
Day 1-3: Implement tracking
You need to track:
Implementation:
1. Add UTM parameters to all campaigns:
?utm_source=google&utm_medium=cpc&utm_campaign=brand-search
?utm_source=linkedin&utm_medium=social&utm_campaign=thought-leadership
?utm_source=email&utm_medium=newsletter&utm_campaign=nurture-week-2
2. Track events in your analytics:
// Track page views with source
analytics.page({
url: window.location.href,
referrer: document.referrer,
utm_source: getUTMParam('utm_source'),
utm_medium: getUTMParam('utm_medium'),
utm_campaign: getUTMParam('utm_campaign')
});
// Track conversions
analytics.track('Signed Up', {
user_id: user.id,
email: user.email,
plan: 'trial'
});
3. Store touchpoints in warehouse:
CREATE TABLE touchpoints (
id VARCHAR,
user_id VARCHAR,
email VARCHAR,
touchpoint_type VARCHAR, -- page_view, email_open, ad_click, etc.
channel VARCHAR, -- SEO, Email, Paid, Social, etc.
campaign VARCHAR,
url VARCHAR,
timestamp TIMESTAMP
);
Day 4-7: Backfill historical data
Pull touchpoints from:
MarketFlow's backfill:
Day 8-10: Write attribution SQL
Time-decay attribution query:
-- Calculate attribution for each conversion
WITH user_journeys AS (
SELECT
conversion.user_id,
conversion.email,
conversion.conversion_date,
conversion.revenue,
touchpoint.touchpoint_type,
touchpoint.channel,
touchpoint.campaign,
touchpoint.timestamp,
-- Days from touchpoint to conversion
DATEDIFF(day, touchpoint.timestamp, conversion.conversion_date) as days_before_conversion,
-- Time-decay weight (decay_rate = 0.05)
EXP(-0.05 * DATEDIFF(day, touchpoint.timestamp, conversion.conversion_date)) as raw_weight
FROM conversions conversion
LEFT JOIN touchpoints touchpoint
ON conversion.user_id = touchpoint.user_id
AND touchpoint.timestamp <= conversion.conversion_date
AND touchpoint.timestamp >= conversion.conversion_date - 90 -- 90-day lookback window
),
normalized_weights AS (
SELECT
*,
-- Normalize weights to sum to 1.0 per conversion
raw_weight / SUM(raw_weight) OVER (PARTITION BY user_id, conversion_date) as attribution_weight
FROM user_journeys
)
SELECT
channel,
campaign,
COUNT(DISTINCT user_id) as influenced_conversions,
SUM(attribution_weight) as attribution_credit,
SUM(revenue * attribution_weight) as attributed_revenue
FROM normalized_weights
GROUP BY channel, campaign
ORDER BY attributed_revenue DESC;
Output:
| Channel | Influenced Conversions | Attribution Credit | Attributed Revenue |
|---|---|---|---|
| Content/SEO | 1,847 | 987.4 | £369,000 |
| Email nurture | 1,456 | 563.2 | £211,000 |
| Google Ads | 1,203 | 422.8 | £158,000 |
| Webinars | 678 | 211.3 | £79,000 |
| Social | 534 | 165.7 | £62,000 |
Day 11-14: Build dashboard
Create visualization showing:
MarketFlow's dashboard (in Looker):
Company: MarketFlow (marketing analytics SaaS) Challenge: Couldn't determine which channels actually drove revenue Solution: Implemented time-decay multi-touch attribution
Reported channel performance (based on last-click):
| Channel | Conversions | % of Total | Monthly Spend | CPA | ROAS |
|---|---|---|---|---|---|
| Google Ads | 432 | 44% | £28,000 | £64.81 | 2.1x |
| Organic | 226 | 23% | £8,000 | £35.40 | 4.2x |
| 177 | 18% | £2,400 | £13.56 | 11.0x | |
| Social | 88 | 9% | £6,800 | £77.27 | 1.9x |
| Referrals | 59 | 6% | £0 | £0 | ∞ |
Budget allocation based on this:
Actual channel performance (time-decay model):
| Channel | Attribution Credit | % of Total | Monthly Spend | True CPA | True ROAS |
|---|---|---|---|---|---|
| Content/SEO | 417.3 | 42% | £8,000 | £19.17 | 7.8x |
| 237.6 | 24% | £2,400 | £10.10 | 14.7x | |
| Google Ads | 178.2 | 18% | £28,000 | £157.11 | 0.95x |
| Webinars | 89.1 | 9% | £4,200 | £47.14 | 3.2x |
| Referrals | 69.3 | 7% | £0 | £0 | ∞ |
Shocking discoveries:
Content/SEO:
Google Ads:
The revelation:
Google Ads was mostly capturing branded searches (people who already knew about MarketFlow from content). It wasn't driving awareness -it was capturing existing demand.
Budget reallocation:
Before:
After:
Results 3 months later:
Revenue impact:
David Chen: "The data was shocking. We'd been starving our best channels (content, email) and overfunding a channel (Google Ads) that was barely profitable. Multi-touch attribution didn't just change our budget allocation -it changed our entire growth strategy."
Decision tree:
If your sales cycle is <7 days (B2C, SMB): → Use linear or time-decay (simple, sufficient)
If your sales cycle is 30-90 days (B2B SaaS): → Use time-decay (balances recency with full journey)
If your sales cycle is >90 days (enterprise): → Use custom/algorithmic (long journeys need sophisticated modeling)
If you have data science team: → Build algorithmic model (most accurate)
If you're just starting: → Start with time-decay (80% of the value, 20% of the complexity)
Decay rate determines how much weight you give recent vs old touchpoints:
| Decay Rate | Half-Life | Best For |
|---|---|---|
| 0.02 | 35 days | Long sales cycles (90+ days) |
| 0.05 | 14 days | Medium cycles (30-60 days) ← Most common |
| 0.10 | 7 days | Short cycles (14-30 days) |
| 0.20 | 3.5 days | Very short cycles (<14 days) |
Formula:
Half-life = ln(2) / decay_rate
Example:
decay_rate = 0.05
Half-life = 0.693 / 0.05 = 13.86 days
Meaning: A touchpoint from 14 days ago gets 50% of the weight of a touchpoint from today.
MarketFlow chose: 0.05 decay rate (14-day half-life) for their 45-day average sales cycle.
Problem:
User journey:
These look like 3 different people without cross-device identity resolution.
Solution:
1. Email capture early:
2. Link touchpoints by email:
SELECT touchpoint.*
FROM touchpoints
WHERE email = 'john@company.com'
ORDER BY timestamp;
3. Use identity resolution tool:
MarketFlow's approach:
Problem:
User copied blog URL and shared in Slack/WhatsApp/private Discord. Recipient clicked, converted.
Source: Shows as "direct" (no referrer, no UTM)
But it was actually: Social referral
Estimated dark social traffic:
Partial solutions:
No perfect solution (some traffic will always be unattributed).
Problem:
Customer attended your conference booth, then converted 2 weeks later.
Conference isn't tracked in your analytics (offline interaction).
Solution:
1. Use unique promo codes:
2. Post-event surveys:
3. CRM tagging:
MarketFlow's offline attribution:
Multi-touch attribution shows correlation, not causation.
The question: If you turned OFF Google Ads, would those conversions disappear? Or would they just come through a different channel?
Incrementality testing answers this.
Test design:
Control group:
Test group:
Run for 4 weeks. Compare conversion rates.
Possible outcomes:
Outcome A: Big drop
Outcome B: Small drop
MarketFlow's incrementality test (Google Ads):
Results:
Revelation:
Google Ads was getting credit for 198 conversions/month (last-click). But it was only DRIVING 46 incremental conversions.
152 conversions would have happened anyway through organic search, direct traffic, or other channels.
True Google Ads ROI:
Decision: Cut Google Ads spend from £28K → £8K (brand-only campaigns), reallocate £20K to content.
Week 1:
Week 2:
Week 3:
Week 4:
Goal: Reallocate 20-30% of budget to true high-ROI channels within 60 days
Ready to implement multi-touch attribution? Athenic integrates with data warehouses and marketing tools to help you build attribution models and optimize spend. Start attribution modeling →
Related reading: