Pirsch Troubleshooting | OpsBlu Docs

Pirsch Troubleshooting

Troubleshoot and debug Pirsch issues — common errors, data discrepancies, and step-by-step diagnostic procedures.

Diagnose and resolve common Pirsch Analytics implementation issues. This guide covers tracking verification, data collection problems, API errors, and self-hosted deployment challenges.

Diagnostic Tools

Browser Developer Tools

Check Script Loading:

  1. Open browser DevTools (F12 or Cmd+Option+I)
  2. Navigate to Network tab
  3. Filter by "pirsch"
  4. Reload page
  5. Verify pirsch.js loads successfully (200 status)

Console Debugging:

Enable debug mode by adding data-debug="true" to your script tag:

<script defer src="https://api.pirsch.io/pirsch.js"
    id="pirschjs"
    data-code="YOUR_CODE"
    data-debug="true"></script>

Debug messages appear in browser console showing:

  • Pageview tracking attempts
  • Event firing
  • API request/response details
  • Error messages

Real-Time Dashboard

Monitor Live Traffic:

  1. Log into Pirsch dashboard
  2. Navigate to Real-Time view
  3. Open your site in another tab
  4. Verify pageview appears within 5-10 seconds
  5. Trigger custom events and watch for updates

API Testing

Test API Connectivity:

curl -X POST "https://api.pirsch.io/api/v1/hit" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/test",
    "title": "Test Page",
    "referrer": "",
    "screen_width": 1920,
    "screen_height": 1080
  }'

Successful response returns HTTP 200 with no body.

No Data Appearing

Script Not Loading

Symptoms:

  • No pageviews in dashboard
  • pirsch.js not visible in Network tab
  • No console errors

Diagnostic Steps:

  1. Verify script tag placement - Must be in <head> or end of <body>

    <head>
      <script defer src="https://api.pirsch.io/pirsch.js"
          id="pirschjs"
          data-code="YOUR_CODE"></script>
    </head>
    
  2. Check for typos - Ensure URL and attributes are correct

  3. Validate identification code - Copy from Pirsch dashboard Settings

  4. Test in incognito mode - Rules out browser extension interference

Common Causes:

  • Content Security Policy (CSP) blocking script

    Add to CSP header:

    script-src 'self' https://api.pirsch.io;
    connect-src 'self' https://api.pirsch.io;
    
  • Ad blockers - Some ad blockers block analytics scripts

    • Test with ad blocker disabled
    • Pirsch's privacy-first approach bypasses most blockers
  • Server-side caching - Cached HTML may not include new script

    • Clear CDN/caching layer
    • Force refresh (Ctrl+F5)

Domain Configuration Issues

Symptoms:

  • Script loads but no data appears
  • Console shows "domain not found" error

Resolution:

  1. Navigate to Pirsch dashboard → Settings → Domains
  2. Verify domain exactly matches your site (exclude protocol)
    • Correct: example.com or www.example.com
    • Incorrect: https://example.com
  3. Check subdomain configuration
    • blog.example.com and example.com are different domains
    • Add each subdomain separately or use wildcard
  4. Ensure domain is active (not paused)

Data Processing Delay

Symptoms:

  • Script loads correctly
  • Real-time view empty
  • Data appears hours later

Expected Behavior:

  • Real-time data - Appears within 5-30 seconds
  • Historical reports - Process within 1-2 minutes
  • Statistics API - Updates every 60 seconds

If Delayed:

  1. Check Pirsch status page: status.pirsch.io
  2. Verify system time is correct (affects timestamp processing)
  3. Wait 5 minutes and hard refresh dashboard
  4. Contact support if delay exceeds 10 minutes

Events Not Recording

Event Function Not Defined

Symptoms:

  • Custom events don't appear in dashboard
  • Console error: pirsch is not defined

Cause: Event tracking called before Pirsch script loads.

Solution:

Wait for script to load:

// Incorrect - may fire before Pirsch loads
pirsch('Custom Event');

// Correct - wait for script ready
window.addEventListener('load', function() {
  if (typeof pirsch === 'function') {
    pirsch('Custom Event');
  }
});

// Or use defer/async handling
function trackEvent(name) {
  if (typeof pirsch === 'function') {
    pirsch(name);
  } else {
    // Queue event for when script loads
    window.addEventListener('pirschLoaded', function() {
      pirsch(name);
    });
  }
}

Incorrect Event Syntax

Valid Event Formats:

// Simple event
pirsch('Button Click');

// Event with metadata
pirsch('Purchase', {
  meta: {
    product: 'Analytics Pro',
    price: 99,
    currency: 'USD'
  }
});

// Event with duration
pirsch('Video Watch', {
  duration: 180
});

Common Errors:

// Wrong - missing quotes
pirsch(Button Click);

// Wrong - using send instead of direct call
pirsch.send('Event Name');

// Wrong - incorrect parameter structure
pirsch('Event', 'metadata');

Events Filtered or Blocked

Check Event Filtering:

  1. Dashboard → Settings → Events
  2. Review event inclusion/exclusion rules
  3. Verify event name matches allowed patterns
  4. Check for case sensitivity in filters

Bot Filtering:

Pirsch automatically filters bot traffic. If testing:

  1. Use real browser (not headless)
  2. Enable JavaScript
  3. Don't use automation tools (Selenium, Puppeteer)
  4. Test from real IP (not data center)

Page Views Undercounted

Single Page Application (SPA) Issues

Symptoms:

  • Only first page loads tracked
  • Navigation within app not counted

Cause: SPAs don't trigger full page reloads.

Solution:

Manually trigger pageview on route change:

React Router:

import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

function usePageTracking() {
  const location = useLocation();

  useEffect(() => {
    if (typeof pirsch === 'function') {
      pirsch();
    }
  }, [location]);
}

// In your App component
function App() {
  usePageTracking();
  return <Router>...</Router>;
}

Vue Router:

router.afterEach((to, from) => {
  if (typeof pirsch === 'function') {
    pirsch();
  }
});

Next.js:

import { useRouter } from 'next/router';
import { useEffect } from 'react';

export default function App({ Component, pageProps }) {
  const router = useRouter();

  useEffect(() => {
    const handleRouteChange = () => {
      if (typeof pirsch === 'function') {
        pirsch();
      }
    };

    router.events.on('routeChangeComplete', handleRouteChange);
    return () => {
      router.events.off('routeChangeComplete', handleRouteChange);
    };
  }, [router.events]);

  return <Component {...pageProps} />;
}

Session Timeout Configuration

Symptoms:

  • Lower session counts than expected
  • Multiple sessions for single visit

Explanation:

Pirsch ends sessions after 30 minutes of inactivity by default.

Review Session Logic:

  • New session starts if >30 minutes since last pageview
  • Closing browser tab doesn't end session (resumed if return within 30min)
  • Different devices/browsers = different sessions

No configuration needed - this is standard behavior and cannot be modified in cloud version. Self-hosted instances can adjust session timeout in configuration.

API Integration Issues

Authentication Failures

Error: "Invalid client credentials"

Resolution:

  1. Verify Client ID and Secret are correct
  2. Check for extra spaces or newlines in credentials
  3. Ensure credentials haven't been regenerated (old ones invalidate)
  4. Confirm API access enabled for your plan

Generate New Credentials:

  1. Dashboard → Settings → Integrations → API
  2. Click "Create API Client"
  3. Update application with new credentials

Rate Limiting

Error: HTTP 429 "Too Many Requests"

Response Headers:

X-RateLimit-Limit: 10000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1640995200

Resolution:

  1. Check current usage against plan limits
  2. Implement request caching
  3. Reduce polling frequency
  4. Upgrade plan for higher limits

Implement Exponential Backoff:

async function callPirschAPI(url, options, retries = 3) {
  try {
    const response = await fetch(url, options);

    if (response.status === 429) {
      const resetTime = response.headers.get('X-RateLimit-Reset');
      const waitTime = (resetTime * 1000) - Date.now();

      if (retries > 0) {
        await new Promise(resolve => setTimeout(resolve, waitTime));
        return callPirschAPI(url, options, retries - 1);
      }
    }

    return response;
  } catch (error) {
    throw error;
  }
}

Data Export Failures

Error: "Export timeout"

Cause: Requesting too large a date range.

Solution:

  1. Break exports into smaller date ranges (1 week at a time)
  2. Use ndjson format for streaming large datasets
  3. Export during off-peak hours
  4. Consider using incremental exports

Example:

async function exportByWeek(startDate, endDate) {
  const exports = [];
  let current = new Date(startDate);

  while (current < endDate) {
    const weekEnd = new Date(current);
    weekEnd.setDate(weekEnd.getDate() + 7);

    const data = await pirsch.export({
      from: current.toISOString().split('T')[0],
      to: weekEnd.toISOString().split('T')[0],
      format: 'json'
    });

    exports.push(data);
    current = weekEnd;
  }

  return exports;
}

Self-Hosted Deployment Issues

Database Connection Problems

Error: "Unable to connect to database"

Diagnostic:

# Test PostgreSQL connection
psql -h localhost -U pirsch -d pirsch

# Check PostgreSQL logs
docker logs pirsch_db

Common Causes:

  1. Wrong connection string format

    Correct format:

    postgres://username:password@host:port/database?sslmode=disable
    
  2. PostgreSQL not ready

    Add health check to Docker Compose:

    db:
      image: postgres:14
      healthcheck:
        test: ["CMD-SHELL", "pg_isready -U pirsch"]
        interval: 10s
        timeout: 5s
        retries: 5
    
  3. Network isolation

    Ensure containers on same network:

    services:
      pirsch:
        networks:
          - pirsch_network
      db:
        networks:
          - pirsch_network
    
    networks:
      pirsch_network:
    

High Memory Usage

Symptoms:

  • Container OOM (Out of Memory) killed
  • Slow query performance

Optimization:

  1. Increase memory allocation:

    pirsch:
      deploy:
        resources:
          limits:
            memory: 2G
    
  2. Optimize PostgreSQL configuration:

    db:
      command:
        - "postgres"
        - "-c"
        - "shared_buffers=256MB"
        - "-c"
        - "work_mem=16MB"
        - "-c"
        - "maintenance_work_mem=128MB"
    
  3. Implement data retention:

    -- Delete events older than 2 years
    DELETE FROM events WHERE created_at < NOW() - INTERVAL '2 years';
    

GeoIP Database Issues

Error: "GeoIP database not found"

Resolution:

  1. Download MaxMind GeoLite2 database:

    wget https://git.io/GeoLite2-City.mmdb
    
  2. Mount in Docker container:

    pirsch:
      volumes:
        - ./GeoLite2-City.mmdb:/data/GeoLite2-City.mmdb
      environment:
        GEOIP_DATABASE: /data/GeoLite2-City.mmdb
    
  3. Or disable geolocation:

    environment:
      ENABLE_GEOLOCATION: "false"
    

Data Discrepancies

Different Count Than Google Analytics

Expected Differences:

  • Bot filtering - Pirsch filters aggressively; GA4 may count some bots
  • Ad blocker bypass - Pirsch less likely to be blocked
  • Session definition - 30min timeout vs GA4's 30min or campaign change
  • Privacy settings - Pirsch doesn't track if Do Not Track enabled

Validation:

Compare specific metric definitions:

  • Sessions vs Visitors
  • Pageviews vs Events
  • Attribution windows

Missing Referrer Data

Symptoms:

  • Most traffic shows as "Direct"
  • Referrer appears empty

Causes:

  1. HTTPS → HTTP transition - Referrer stripped for security
  2. Referrer-Policy header - Site sending traffic sets restrictive policy
  3. Browser privacy features - Some browsers limit referrer
  4. Redirects - Multi-step redirects lose referrer

Workaround:

Use UTM parameters for campaign tracking:

https://example.com/?utm_source=newsletter&utm_medium=email&utm_campaign=launch

Getting Help

Enable Debug Mode

Always enable debug mode when reporting issues:

<script defer src="https://api.pirsch.io/pirsch.js"
    id="pirschjs"
    data-code="YOUR_CODE"
    data-debug="true"></script>

Gather Diagnostic Information

When contacting support, include:

  1. Browser and version
  2. Operating system
  3. Website URL
  4. Console errors (with debug enabled)
  5. Network tab screenshot showing pirsch.js request
  6. Steps to reproduce issue

Support Channels

Escalation

For critical issues:

  1. Check status.pirsch.io for service incidents
  2. Email support with "URGENT" in subject line
  3. Include account email and domain affected
  4. Describe business impact

Preventative Monitoring

Set Up Alerts

Monitor Key Metrics:

  1. Zero pageviews - Alert if no data for 1 hour
  2. Traffic drops - Alert if traffic drops >50% vs previous day
  3. API errors - Monitor API response codes

Using OpsBlu:

Configure automated monitoring for Pirsch implementation:

  • Verify script presence on all pages
  • Validate domain configuration
  • Monitor data collection continuity
  • Alert on tracking failures

Regular Health Checks

Weekly:

  • Review pageview trends for anomalies
  • Check event tracking still functioning
  • Verify API integrations receiving data

Monthly:

  • Audit custom event definitions
  • Review and update excluded IPs/paths
  • Check for JavaScript errors in production
  • Validate data export processes

Version Updates (Self-Hosted)

Stay Current:

# Check current version
docker exec pirsch ./pirsch --version

# Pull latest image
docker pull pirsch/pirsch:latest

# Restart with new version
docker-compose down && docker-compose up -d

Review Changelog: