ANA-001 recommended Server-Side Tracking

Server-side analytics and data ownership

Analytics events sent from server (not just client-side). Data accessible in a warehouse you control or self-hosted solution. Can query raw event data with SQL.

Question to ask

"If a third-party shuts down, do you lose your analytics history?"

What to check

  • Look for server-side analytics packages (PostHog, Segment, Mixpanel backend SDKs)
  • Check for analytics events in backend code (not just frontend)
  • Verify data goes to owned warehouse or self-hosted solution
  • Flag client-only analytics (GA4 without server-side) as fail

Verification guide

Severity: Recommended

Analytics should not be delegated entirely to client-side third-party tools. Server-side tracking ensures data completeness (ad blockers don't affect it) and data ownership means you can query raw events.

Check automatically:

  1. Look for server-side analytics implementation:
# Check for analytics packages that support server-side
grep -riE "posthog|segment|mixpanel|amplitude|@analytics|rudderstack" package.json 2>/dev/null

# Look for analytics in backend code (not just frontend)
grep -riE "analytics\.(track|identify|page)|trackEvent|logEvent" --include="*.ts" --include="*.js" --include="*.py" src/ lib/ app/ api/ server/ 2>/dev/null | grep -v node_modules | head -15

# Check for analytics middleware or event handlers
grep -riE "analytics.*middleware|event.*tracking|track.*event" --include="*.ts" --include="*.js" src/ lib/ app/ 2>/dev/null | grep -v node_modules | head -10
  1. Check for self-hosted or data-owning solutions:
# Self-hosted analytics (PostHog, Plausible, Matomo)
grep -riE "POSTHOG_HOST|PLAUSIBLE|MATOMO|self.hosted" .env.example .env* docker-compose*.yml 2>/dev/null

# Check for warehouse destination config
grep -riE "warehouse|bigquery|snowflake|redshift|destination" --include="*.ts" --include="*.js" --include="*.json" config/ 2>/dev/null | head -10
  1. Red flags for client-only analytics:
# Google Analytics without server-side component = data not owned
grep -riE "gtag|google.analytics|ga\('|GA_MEASUREMENT_ID" --include="*.ts" --include="*.js" --include="*.html" . 2>/dev/null | grep -v node_modules | head -5

If not found in code, ask user:

  • "What analytics tool do you use and is it server-side or client-side?"
  • "Where does your analytics data ultimately live? Can you query raw events?"
  • "Do you own your analytics data or is it locked in a third-party dashboard?"

Cross-reference with:

  • ANA-002 (data ownership requires warehouse access)

Pass criteria:

  • Analytics events sent from server (not just client-side JavaScript)
  • Data accessible in a warehouse you control, OR self-hosted solution (PostHog, Plausible)
  • Can query raw event data with SQL or equivalent

Fail criteria:

  • Client-only analytics (GA4, Mixpanel frontend-only)
  • No ability to query raw event data
  • Data locked in third-party dashboard without export

Partial (acceptable):

  • Server-side tracking exists but some events are client-only (document which)
  • Data exported to warehouse on schedule (not real-time) - note the delay

Evidence to capture:

  • Analytics tool name and deployment (self-hosted vs managed)
  • Where raw event data lives (warehouse, self-hosted DB, etc.)
  • Evidence of server-side tracking code

Section

18. Analytics

Performance & Analytics