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:
- Open browser DevTools (F12 or Cmd+Option+I)
- Navigate to Network tab
- Filter by "pirsch"
- Reload page
- Verify
pirsch.jsloads 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:
Real-Time Dashboard
Monitor Live Traffic:
- Log into Pirsch dashboard
- Navigate to Real-Time view
- Open your site in another tab
- Verify pageview appears within 5-10 seconds
- 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:
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>Check for typos - Ensure URL and attributes are correct
Validate identification code - Copy from Pirsch dashboard Settings
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:
- Navigate to Pirsch dashboard → Settings → Domains
- Verify domain exactly matches your site (exclude protocol)
- Correct:
example.comorwww.example.com - Incorrect:
https://example.com
- Correct:
- Check subdomain configuration
blog.example.comandexample.comare different domains- Add each subdomain separately or use wildcard
- 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:
- Check Pirsch status page:
status.pirsch.io - Verify system time is correct (affects timestamp processing)
- Wait 5 minutes and hard refresh dashboard
- 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:
- Dashboard → Settings → Events
- Review event inclusion/exclusion rules
- Verify event name matches allowed patterns
- Check for case sensitivity in filters
Bot Filtering:
Pirsch automatically filters bot traffic. If testing:
- Use real browser (not headless)
- Enable JavaScript
- Don't use automation tools (Selenium, Puppeteer)
- 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();
}
});
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:
- Verify Client ID and Secret are correct
- Check for extra spaces or newlines in credentials
- Ensure credentials haven't been regenerated (old ones invalidate)
- Confirm API access enabled for your plan
Generate New Credentials:
- Dashboard → Settings → Integrations → API
- Click "Create API Client"
- 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:
- Check current usage against plan limits
- Implement request caching
- Reduce polling frequency
- 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:
- Break exports into smaller date ranges (1 week at a time)
- Use
ndjsonformat for streaming large datasets - Export during off-peak hours
- 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:
Wrong connection string format
Correct format:
postgres://username:password@host:port/database?sslmode=disablePostgreSQL 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: 5Network 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:
Increase memory allocation:
pirsch: deploy: resources: limits: memory: 2GOptimize PostgreSQL configuration:
db: command: - "postgres" - "-c" - "shared_buffers=256MB" - "-c" - "work_mem=16MB" - "-c" - "maintenance_work_mem=128MB"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:
Download MaxMind GeoLite2 database:
wget https://git.io/GeoLite2-City.mmdbMount in Docker container:
pirsch: volumes: - ./GeoLite2-City.mmdb:/data/GeoLite2-City.mmdb environment: GEOIP_DATABASE: /data/GeoLite2-City.mmdbOr 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:
- HTTPS → HTTP transition - Referrer stripped for security
- Referrer-Policy header - Site sending traffic sets restrictive policy
- Browser privacy features - Some browsers limit referrer
- 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:
- Browser and version
- Operating system
- Website URL
- Console errors (with debug enabled)
- Network tab screenshot showing pirsch.js request
- Steps to reproduce issue
Support Channels
- Documentation - docs.pirsch.io
- Community Forum - forum.pirsch.io
- Email Support - support@pirsch.io
- GitHub Issues - github.com/pirsch-analytics/pirsch (self-hosted)
Escalation
For critical issues:
- Check status.pirsch.io for service incidents
- Email support with "URGENT" in subject line
- Include account email and domain affected
- Describe business impact
Preventative Monitoring
Set Up Alerts
Monitor Key Metrics:
- Zero pageviews - Alert if no data for 1 hour
- Traffic drops - Alert if traffic drops >50% vs previous day
- 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:
- github.com/pirsch-analytics/pirsch/releases
- Check for breaking changes before upgrading
- Test in staging environment first