A tracking plan is the foundation of your analytics implementation. Without one, you'll end up with inconsistent event names, missing properties, and reports that no one trusts. With a good tracking plan, you get clean data that actually answers business questions.

This guide covers everything you need to create a PostHog tracking plan that scales with your product.

What Is a Tracking Plan?

A tracking plan is a document that defines every event you track, what properties each event includes, and when that event should fire. It's the contract between your engineering team (who implements tracking) and your product/analytics team (who uses the data).

A good tracking plan answers three questions for every event:

  • What happened? The event name (e.g., user_signup)
  • What context? The properties (e.g., plan_type, signup_source)
  • When does it fire? The trigger condition (e.g., after successful registration)

Autocapture vs. Custom Events

PostHog offers two approaches to event tracking, and understanding when to use each is essential for a good tracking plan.

Autocapture

PostHog can automatically capture events without specific tracking code. This includes pageviews, pageleaves, clicks, input changes, and form submissions associated with a, button, form, input, select, textarea, and label tags.

When to use autocapture:

  • Getting started quickly with minimal setup
  • Exploratory analysis when you're not sure what to track
  • Capturing broad user interactions for heatmaps and session recordings
  • When partial data is acceptable (e.g., understanding user journeys)

Limitations of autocapture:

  • Lack of signal: Captures everything, making it difficult to find what matters
  • Frontend only: Cannot capture server-side events
  • Fragile naming: Event names change when UI text changes (e.g., "Clicked button with text 'Add to cart'" becomes "Clicked button with text 'Add'" if you update the button)
  • SPA limitations: Pageview captures rely on page loads, requiring configuration for single-page apps

Custom Events

Custom events give you precise control over what data you capture and when. They're essential for high-value actions.

When to use custom events:

  • Tracking critical business events (signups, purchases, feature usage)
  • When you need specific properties attached to events
  • Server-side tracking for reliability
  • When event names need to remain stable despite UI changes

Best practice: Use a combination of autocapture and custom events. Start with autocapture for broad coverage, then add custom events for your most important actions.

Event Naming Conventions

Consistency in event naming is crucial. PostHog recommends specific conventions that differ from some other analytics platforms.

The category:object_action Framework

PostHog recommends structuring events as category:object_action where:

  • Category: The context where the event occurred (e.g., signup_flow, account_settings, checkout)
  • Object: The component or element involved (e.g., signup_button, pricing_page)
  • Action: The verb describing what happened (e.g., click, submit, view)

Examples:

  • signup_flow:signup_button_click
  • checkout:payment_form_submit
  • dashboard:report_generate
  • onboarding:step_complete

For simpler implementations, the [object][verb] format also works well:

  • user_signup
  • order_complete
  • project_create
  • feature_flag_evaluate

Naming Rules

  1. Use lowercase letters only: user_signup not User_Signup or USER_SIGNUP
  2. Use snake_case: signup_button_click not signupButtonClick or signup-button-click
  3. Use present-tense verbs: submit, create, view (not submitted, created, viewed)
  4. Be specific: signup_button_click is better than button_click
  5. Avoid abbreviations: user not usr, configuration not config
  6. Use properties for context: Instead of web_user_signup and ios_user_signup, use user_signup with a platform property

Create a Standard Verb List

Limit your team to an approved list of verbs to prevent inconsistency. Common verbs include:

  • view, click, submit, create, update, delete
  • start, complete, cancel, fail
  • open, close, expand, collapse
  • search, filter, sort, select
  • share, invite, export, download

Property Standards

Properties provide context for events. Without proper property standards, you'll have inconsistent data types and missing information.

Property Naming

Use snake_case for all properties (same as event names):

  • plan_type (not planType or PlanType)
  • signup_source (not signupSource)
  • is_premium (not isPremium or premium)

Standard Property Types

Define standard properties that appear on multiple events:

User Properties (set once via $set or $set_once):

  • email – User's email address
  • name – User's display name
  • created_at – Account creation timestamp
  • plan – Current subscription plan
  • company_id – For B2B, the associated organization

Note: Properties set with $set_once cannot be changed by calling $set_once again—use this for immutable data like original signup source.

Event Properties (sent with each event):

  • platformweb, ios, android
  • page_path – Current URL path
  • session_id – For session-level analysis
  • experiment_variant – If user is in an A/B test
  • feature_name – When tracking feature usage

Data Types

Be consistent with data types—PostHog detects types automatically but inconsistency causes problems:

  • Booleans: is_premium: true (not "yes" or 1)
  • Numbers: price: 49.99 (not "$49.99")
  • Dates: ISO 8601 format: 2025-01-15T10:30:00Z
  • Arrays: features: ["analytics", "reports"]

Property Best Practices

  • Include more properties than you think you need. There's no limit to the number of properties an event can have, and your future self will thank you.
  • Avoid PII in event properties when possible. Use IDs instead of names/emails for GDPR compliance.
  • Don't duplicate user properties in event properties. PostHog automatically associates events with person profiles.

Event Categories

Organize events into categories based on the user journey. The AARRR (Pirate Metrics) framework works well:

1. Acquisition Events

Track how users discover and sign up:

  • page_view – Landing page visits (or use autocapture's $pageview)
  • demo_request – Form submissions
  • user_signup – Registration complete
  • email_verify – Confirmation link clicked

2. Activation Events

Track the "aha moment" and initial value delivery:

  • onboarding_start
  • onboarding_step_complete (with step_name property)
  • first_project_create
  • team_member_invite

3. Engagement Events

Track ongoing product usage:

  • feature_use (with feature_name property)
  • report_generate
  • dashboard_view
  • search_perform

4. Revenue Events

Track monetization and upgrade paths:

  • pricing_page_view
  • checkout_start
  • subscription_create
  • plan_upgrade

5. Referral Events

Track word-of-mouth growth:

  • invite_send
  • share_click (with share_destination property)
  • referral_complete

6. Retention Events

Track churn signals and return usage:

  • session_start – Return visits
  • subscription_cancel
  • downgrade_request
  • support_ticket_create

Frontend vs. Backend Tracking

A robust tracking plan uses both frontend and backend events. Understanding when to use each is critical.

Backend Analytics Are More Reliable

There are three main reasons to prefer backend tracking for critical events:

  1. Ad blockers: Many users have tracking disabled or blocked on their browsers
  2. JavaScript issues: Frontend analytics can be interrupted by network issues, CORS, or browser settings
  3. Data accuracy: Server-side events capture the actual state from your database

When to Use Each

Use frontend analytics when:

  • Getting partial data is acceptable
  • Understanding user journeys and page sequences
  • Tracking UI interactions like clicks, scrolls, or form submissions
  • Gathering client-side performance data (page load times)

Use backend analytics when:

  • You need accurate data (e.g., exact signup counts)
  • Tracking high-value events (signups, purchases, subscriptions)
  • CRUD events (API requests that create, update, or delete resources)
  • Backend jobs and workflows

Use Different Event Names

PostHog recommends using different event names for frontend and backend events to avoid duplicate counting:

  • Frontend: signup_form_submit
  • Backend: user_create

Event Versioning

As your app evolves, so do the events you track. Implementing a versioning system ensures you can distinguish between older and newer event definitions.

For example, if you initially tracked registration:signup_button_click and later revamped your registration flow, introduce a new version:

  • Old: registration:signup_button_click
  • New: registration_v2:signup_button_click

This preserves historical data while letting you compare the impact of changes.

Implementation Examples

JavaScript (Frontend)

// Custom event with properties
posthog.capture('plan_purchase', {
  price: 1599,
  plan_id: 'XYZ12345',
  frequency: 'monthly',
  features: {
    sso: true,
    custom_branding: true
  }
});

// Setting user properties
posthog.identify('user_123', {
  email: 'user@example.com',
  plan: 'enterprise',
  company_id: 'company_456'
});

Python (Backend)

from posthog import Posthog

posthog = Posthog('your-api-key', host='https://app.posthog.com')

# Capture event with properties
posthog.capture(
    distinct_id='user_123',
    event='order_complete',
    properties={
        'order_id': '#0054',
        'subtotal': 3599,
        'currency': 'USD'
    }
)

Adding Properties to Autocapture

You can add custom properties to autocaptured events using data attributes:

<button
  data-ph-capture-attribute-button-type="primary-cta"
  data-ph-capture-attribute-page-section="hero"
>
  Sign Up Now
</button>

Building Your Tracking Plan Document

Your tracking plan should be a living document. We recommend a spreadsheet with these columns:

  1. Event Name: Following category:object_action pattern
  2. Description: When this event fires
  3. Category: Acquisition, Activation, Engagement, Revenue, Referral, Retention
  4. Source: Frontend, Backend, or Both
  5. Properties: List of required and optional properties
  6. Property Types: String, Number, Boolean, Array, etc.
  7. Example Values: Sample data for testing
  8. Implementation Status: Planned, In Development, Live, Deprecated
  9. Owner: Who's responsible for this event
  10. Version: Track changes to event definitions

Privacy and Compliance

A tracking plan must account for privacy regulations like GDPR and CCPA.

GDPR Considerations

  • Personal data: GDPR applies to any data that can identify an individual, including emails, names, IP addresses, and even device IDs combined with other data
  • Consent: If collecting personal data, you must provide a mechanism for informed consent
  • Right to be forgotten: Use PostHog's data deletion features to comply with deletion requests
  • Data location: For robust GDPR compliance, use PostHog Cloud EU (hosted in Frankfurt)

Data Minimization Strategies

  • Use anonymous IDs instead of PII in event properties where possible
  • Use $set for user properties rather than including PII in every event
  • Configure PostHog's masking features for session recordings
  • Use PostHog's realtime transformations to anonymize data before storage

Cookieless Tracking

PostHog supports cookieless tracking via the cookieless_mode configuration. This prevents storing data in cookies or local storage while still counting users via privacy-preserving hashes.

Reverse Proxy Setup

Ad blockers can prevent events from reaching PostHog. Setting up a reverse proxy sends events through your own domain, improving data capture rates. This is especially important for accurate frontend analytics.

Filtering Internal Users

Apps with few users can inadvertently inflate metrics by including their own team's usage. Your tracking plan should address this:

  • Turn off tracking in development using localhost or environment checks
  • Use PostHog's internal user filtering features
  • Create cohorts to exclude team members from reports
  • Consider separate PostHog projects for development and production

Group Analytics

For B2B products, tracking at the company/organization level is essential. PostHog's group analytics lets you:

  • Associate events with groups (companies, teams, organizations)
  • Analyze metrics at the group level, not just individual users
  • Track group properties separately from user properties
// JavaScript example
posthog.group('company', 'company_id_123', {
  name: 'Acme Corp',
  plan: 'enterprise',
  employee_count: 500
});

Governance and Maintenance

A tracking plan only works if it's maintained. Here's how to keep it healthy:

Change Management

  • Require approval for new events from analytics owner
  • Document breaking changes before implementation
  • Version your tracking plan (v1.0, v1.1, etc.)
  • Keep a changelog of modifications
  • Consider using tools like Avo or Trackingplan for automated governance

Quality Assurance

  • Validate events in staging before production
  • Set up alerts for missing required properties
  • Monitor event volume for anomalies (sudden drops may indicate broken tracking)
  • Quarterly audits to remove unused events
  • Use PostHog's data management features to mark events as verified, hidden, or deprecated

Documentation

  • Keep tracking plan accessible to all stakeholders
  • Include implementation examples for engineers
  • Document the "why" behind each event
  • Link events to business questions they answer

Using Actions to Organize Events

PostHog Actions let you combine multiple events or autocapture elements into a single trackable unit. This is useful for:

  • Renaming events: Create an action with a clear name based on a confusingly-named event
  • Combining related events: Group insight_create, insight_analyze, and dashboard_create into a "Product Analytics Interactions" action
  • Handling autocapture drift: Combine "Clicked button with text 'Add to cart'" and "Clicked button with text 'Add'" into one action

Common Mistakes to Avoid

  1. Tracking everything: More events = more noise. Track what you'll actually analyze.
  2. Vague event names: button_click tells you nothing. Be specific.
  3. Inconsistent casing: Mixing User_Signup, user signed up, and user_sign_up creates duplicate events that are hard to combine.
  4. Missing properties: Events without context are useless for segmentation.
  5. No documentation: If only one person knows what an event means, you have a problem.
  6. Relying only on frontend tracking: You'll miss events from users with ad blockers.
  7. Not filtering internal users: Your team's usage will skew metrics.
  8. Ignoring privacy: GDPR fines can reach €20 million or 4% of global revenue.
  9. No versioning: When you change event definitions, you lose the ability to compare old and new data.
  10. Duplicating events across frontend and backend: Use different names to avoid double-counting.

Next Steps

Start with a small, focused tracking plan:

  1. Identify your top 5 business questions
  2. Map the events needed to answer them
  3. Define properties for each event
  4. Decide whether each event should be frontend, backend, or both
  5. Document in a shared tracking plan
  6. Implement, validate in staging, and iterate
  7. Set up monitoring for event volume anomalies

A well-designed tracking plan is the difference between analytics that gather dust and analytics that drive decisions. Invest the time upfront, and your future self will thank you.

Additional Resources