Skip to main content

Overview

The Analytics system tracks page views using aggregated daily counters and a session ring buffer. No personal data (IP addresses, user agents, visitor IDs) is persisted to the database.

Type Definition

Privacy by Design: The knownVisitors map uses FNV-1a hashes of (IP+UserAgent) for session deduplication. These hashes exist only in memory and are never written to the database.

Initialization

Initialize

Creates analytics system, sets up collections, and starts background workers.
core.App
required
PocketBase application instance
Returns:
  • *Analytics - Initialized analytics instance
  • error - Error if collection setup fails
Location: core/analytics/analytics.go:33 Process:
  1. Creates _analytics collection (daily aggregated counters)
  2. Creates _analytics_sessions collection (recent visit ring buffer)
  3. Starts session cleanup worker (runs every 30 minutes)
Example:

Route Registration

RegisterRoutes

Attaches request tracking middleware to the router.
*core.ServeEvent
required
ServeEvent to bind middleware
Location: core/analytics/collector.go:15 Example:

Tracking Behavior

What Gets Tracked

The system tracks:
string
Request URL path
string
Device category: "desktop", "mobile", "tablet"
string
Browser: "chrome", "firefox", "safari", "edge", "opera", "unknown"
string
Operating system: "windows", "macos", "linux", "ios", "ipados", "android", "unknown"
boolean
Whether this is a new session (first visit within 30-minute window)

What Does NOT Get Tracked

  • IP addresses (used only for session hashing, never stored)
  • Full user agents (used only for parsing, never stored)
  • Visitor IDs or cookies
  • Personal information
  • Query parameters
  • Request headers

Excluded Paths

These paths are automatically excluded from tracking: API and System Routes:
  • /api/*
  • /_/*
  • /_app/immutable/*
  • /.well-known/*
Common Files:
  • /favicon.ico
  • /service-worker.js
  • /manifest.json
  • /robots.txt
Static Files:
  • CSS: .css
  • JavaScript: .js, .json, .map
  • Images: .png, .jpg, .jpeg, .gif, .svg, .ico, .webp, .bmp, .tiff, .tif, .heic, .heif, .avif
  • Video: .mp4, .webm, .ogg, .ogv, .mov, .avi, .wmv, .flv, .mkv, .m4v, .3gp
  • Audio: .mp3, .wav, .flac, .aac, .m4a, .wma, .opus
  • Documents: .pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .txt, .rtf, .csv, .md
  • Archives: .zip, .rar, .7z, .tar, .gz, .bz2
  • Fonts: .woff, .woff2, .ttf, .eot, .otf
Location: core/analytics/collector.go:204

Bot Detection

Requests from these user agents are excluded:
  • bot, crawler, spider
  • lighthouse, pagespeed, prerender
  • headless, pingdom
  • googlebot, baiduspider, bingbot
  • yandex, facebookexternalhit
  • ahrefsbot, semrushbot
  • screaming frog
  • Empty user agent strings
Location: core/analytics/collector.go:255

Session Management

Session Window

Default session window: 30 minutes A visitor is considered “new” if they haven’t been seen within the last 30 minutes.

Session Hash

Sessions are tracked using FNV-1a hashes:
Properties:
  • Fast, non-cryptographic hash
  • 64-bit hash value (16-character hex string)
  • Deterministic (same IP+UA always produces same hash)
  • Collision-resistant for practical purposes
  • Never written to database
Location: core/analytics/collector.go:142

Session Cleanup

Background worker runs every 30 minutes to remove expired sessions from memory:
Location: core/analytics/analytics.go:47

Data Storage

Daily Counters (_analytics)

Aggregated view counts stored as:
Upsert Logic:
Location: core/analytics/collector.go:62

Session Ring Buffer (_analytics_sessions)

Recent visits stored as ring buffer (max 50 entries):
Pruning:
Location: core/analytics/collector.go:103

Complete Examples

Basic Setup

Custom Session Window

Conditional Tracking

Testing Analytics

User Agent Parsing

Device Type Detection:
  • Contains “mobile” or “android” → "mobile"
  • Contains “tablet” or “ipad” → "tablet"
  • Default → "desktop"
Browser Detection:
  • Contains “chrome” (not “edg”) → "chrome"
  • Contains “firefox” → "firefox"
  • Contains “safari” (not “chrome”) → "safari"
  • Contains “edg” → "edge"
  • Contains “opera” → "opera"
  • Default → "unknown"
OS Detection:
  • Contains “windows” → "windows"
  • Contains “macintosh” or “mac os” → "macos"
  • Contains “linux” (not “android”) → "linux"
  • Contains “iphone” → "ios"
  • Contains “ipad” → "ipados"
  • Contains “android” → "android"
  • Default → "unknown"
Location: core/analytics/collector.go:156

Constants

Location: core/analytics/types.go:6

Best Practices

  1. Privacy First: Never log or store IP addresses or personal data
  2. GDPR Compliance: System is designed for GDPR compliance (no cookies, no personal data)
  3. Performance: Tracking happens after response is sent (non-blocking)
  4. Data Retention: Clean up old analytics data (90-day retention recommended)
  5. Bot Filtering: Rely on built-in bot detection, don’t reinvent
  6. Session Window: 30 minutes is standard, adjust based on your use case
  7. Testing: Test with real user agents, not synthetic ones