Conversion Attribution Window Issues | Blue Frog Docs

Conversion Attribution Window Issues

Understanding and fixing conversion attribution window configuration problems

Conversion Attribution Window Issues

What This Means

Attribution windows define the time period during which a conversion can be credited to a marketing touchpoint (click or view). Attribution window issues can lead to:

  • Under-reporting conversions due to narrow windows
  • Over-attribution from overly generous windows
  • Inconsistent attribution across platforms
  • Misallocated marketing budget
  • Inaccurate ROI calculations
  • Cross-device attribution gaps
  • Lost conversions outside the tracking window

Different platforms use different default windows (e.g., Facebook: 7-day click, 1-day view; Google Ads: 30-day click), creating discrepancies in reporting.

How to Diagnose

Compare Platform Attribution Windows

// Check attribution window settings across platforms
const platformWindows = {
  facebook: {
    clickWindow: 7,  // days
    viewWindow: 1
  },
  googleAds: {
    clickWindow: 30,
    viewWindow: null
  },
  linkedin: {
    clickWindow: 30,
    viewWindow: null
  }
};

function analyzeAttributionGaps(platformA, platformB) {
  const clickGap = Math.abs(platformA.clickWindow - platformB.clickWindow);
  const viewGap = Math.abs((platformA.viewWindow || 0) - (platformB.viewWindow || 0));

  return { clickGap, viewGap };
}

Monitor Attribution Metrics

  • Conversion lag time (time from click to conversion)
  • Percentage of conversions falling outside attribution window
  • Multi-touch attribution path length
  • Cross-device conversion rates

Analyze Conversion Delays

-- Find average time from click to conversion
SELECT
  AVG(conversion_timestamp - click_timestamp) as avg_conversion_delay,
  PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY conversion_timestamp - click_timestamp) as median_delay,
  PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY conversion_timestamp - click_timestamp) as p95_delay
FROM conversions
WHERE conversion_timestamp > click_timestamp;

Common Issues

  • Attribution window shorter than typical customer journey
  • Mismatched windows across marketing platforms
  • Not accounting for view-through conversions
  • Cross-device conversions falling outside window
  • Seasonal products requiring longer windows

General Fixes

  1. Align attribution windows across platforms - Use consistent windows for fair comparison

    const standardAttributionWindow = {
      clickWindow: 30,  // 30-day click attribution
      viewWindow: 1      // 1-day view attribution
    };
    
    // Configure each platform to match
    function configureAttributionWindow(platform, settings) {
      platform.setAttributionWindow({
        click: settings.clickWindow * 24 * 60 * 60 * 1000,  // Convert to ms
        view: settings.viewWindow * 24 * 60 * 60 * 1000
      });
    }
    
  2. Choose window based on customer journey - Analyze typical conversion lag

    function recommendAttributionWindow(conversionData) {
      // Get 95th percentile conversion delay
      const delays = conversionData.map(c => c.conversionDelay);
      delays.sort((a, b) => a - b);
      const p95Index = Math.floor(delays.length * 0.95);
      const p95Delay = delays[p95Index];
    
      // Convert to days and round up
      const recommendedDays = Math.ceil(p95Delay / (24 * 60 * 60 * 1000));
    
      console.log(`Recommended attribution window: ${recommendedDays} days`);
      console.log(`This captures 95% of conversions`);
    
      return recommendedDays;
    }
    
  3. Implement data-driven attribution - Use multi-touch attribution models

    // Simple position-based attribution (40% first touch, 40% last touch, 20% middle)
    function positionBasedAttribution(touchpoints, conversionValue) {
      if (touchpoints.length === 1) {
        return [{ ...touchpoints[0], credit: conversionValue }];
      }
    
      const firstCredit = conversionValue * 0.4;
      const lastCredit = conversionValue * 0.4;
      const middleCredit = conversionValue * 0.2 / (touchpoints.length - 2);
    
      return touchpoints.map((touchpoint, index) => {
        let credit = 0;
        if (index === 0) credit = firstCredit;
        else if (index === touchpoints.length - 1) credit = lastCredit;
        else credit = middleCredit;
    
        return { ...touchpoint, credit };
      });
    }
    
  4. Use server-side tracking - Extend attribution beyond cookie lifetime

    // Store user journey server-side
    async function trackUserJourney(userId, event) {
      await db.insertEvent({
        userId,
        eventType: event.type,
        source: event.source,
        timestamp: Date.now(),
        sessionId: event.sessionId
      });
    
      // Attribute conversions to all relevant touchpoints
      if (event.type === 'conversion') {
        await attributeConversion(userId, event);
      }
    }
    
  5. Account for cross-device conversions - Track user identity across devices

    function linkDevices(userId, deviceId) {
      // Link devices to same user for attribution
      userGraph.addEdge(userId, deviceId);
    
      // Merge conversion paths across devices
      const allDevices = userGraph.getConnectedDevices(userId);
      const mergedPath = mergeTouchpointsFromDevices(allDevices);
    
      return mergedPath;
    }
    
  6. Configure platform-specific windows - Optimize per platform

    const platformConfigs = {
      facebook: {
        clickWindow: 7,   // Shorter window for social
        viewWindow: 1,
        reason: 'Impulse-driven purchases'
      },
      googleAds: {
        clickWindow: 30,  // Longer for search intent
        viewWindow: null,
        reason: 'Research-based purchases'
      },
      email: {
        clickWindow: 14,  // Medium window for nurture
        viewWindow: null,
        reason: 'Considered purchases'
      }
    };
    
  7. Implement incrementality testing - Measure true lift from marketing

    // A/B test to measure incremental conversions
    async function incrementalityTest(userId) {
      const inTestGroup = userId % 2 === 0;
    
      if (inTestGroup) {
        // Show ad
        showAd(userId);
        trackImpression(userId, { testGroup: 'treatment' });
      } else {
        // Control - no ad
        trackImpression(userId, { testGroup: 'control' });
      }
    
      // Compare conversion rates between groups
      // Difference = incremental lift from ads
    }
    
  8. Use probabilistic matching - Attribute cross-device conversions

    function probabilisticMatch(device1, device2) {
      const signals = {
        ipAddress: device1.ip === device2.ip ? 0.3 : 0,
        userAgent: similarityScore(device1.ua, device2.ua) * 0.2,
        timezone: device1.tz === device2.tz ? 0.1 : 0,
        behavior: behavioralSimilarity(device1, device2) * 0.4
      };
    
      const matchProbability = Object.values(signals).reduce((a, b) => a + b, 0);
    
      return matchProbability > 0.7; // High confidence threshold
    }
    
  9. Document attribution methodology - Maintain consistency in reporting

    const attributionConfig = {
      model: 'position-based',
      clickWindow: 30,
      viewWindow: 1,
      crossDevice: true,
      deduplication: 'last-click-wins',
      updatedAt: '2024-01-01',
      notes: 'Standard attribution for all campaigns'
    };
    

Platform-Specific Guides

Platform Guide
Google Ads Attribution Models
Meta Ads Attribution Settings
Google Analytics 4 Attribution Modeling
LinkedIn Ads Conversion Tracking
HubSpot Attribution Reporting

Further Reading

// SYS.FOOTER