What Is PostHog?
PostHog is currently the most popular open-source product analytics and AI observability platform on GitHub (⭐ over 19K stars). Unlike closed-source tools like Google Analytics, PostHog combines product analytics, user behavior tracking, A/B experiments, feature flags, and error monitoring into a single unified open-source platform — with full data ownership and control.
Why Do Developers Choose PostHog?
| Dimension | Google Analytics | Mixpanel | PostHog |
|---|---|---|---|
| Open-source / Self-hosted | ❌ | ❌ | ✅ MIT License |
| Data ownership | Mixpanel | Yours | |
| Session Replay | ❌ | ✅ Paid | ✅ Built-in |
| Feature Flags | ❌ | ❌ | ✅ Built-in |
| A/B Experiments | ❌ | ✅ Paid | ✅ Built-in |
| AI Observability | ❌ | ❌ | ✅ Tracks LLM calls |
| Free tier | Unlimited (but sampled) | 1M events/mo | 1M events/mo |
| Pricing | Enterprise is expensive | Usage-based | Pay-as-you-go after free tier |
PostHog's core mission is helping product teams and developers understand user behavior and drive product decisions. Its unique selling points include:
- All-in-One platform: one tool covering product analytics, web analytics, session replay, feature flags, experiments, error tracking, logs, and surveys
- AI Observability: track LLM call latency, cost, and generated content — a real differentiator in 2026
- MCP integration: connect to AI coding tools like Claude Code and Cursor via the MCP protocol, letting you query data directly in your editor
- Self-driving mode: automatically detects rage clicks, errors, and failed queries, then generates analysis reports and pull requests
Architecture: PostHog vs. Other Solutions
┌─────────────────────────────────────────────────┐
│ PostHog │
├──────────┬──────────┬──────────┬────────────────┤
│ Product │ Session │ Feature │ AI │
│ Analytics │ Replay │ Flags │ Observability │
│ (Events) │ (Replay) │ (Flags) │ (LLM Traces) │
├──────────┴──────────┴──────────┴────────────────┤
│ Unified ClickHouse data engine │
├─────────────────────────────────────────────────┤
│ Frontend SDK | Backend SDK | API | MCP │
└─────────────────────────────────────────────────┘
Self-Hosting PostHog
Option 1: PostHog Cloud (Recommended)
The fastest way to get started — zero ops required:
- PostHog Cloud US — for users outside Europe
- PostHog Cloud EU — for European users with data compliance needs
The free tier includes per month: 1M events, 5,000 recordings, 1M flag requests, and 10 exceptions.
Option 2: One-Click Docker Deployment (Self-Hosted)
If you want full data control, PostHog provides a dead-simple Hobby deployment option.
Prerequisites: - Linux server - At least 4 GB RAM - Docker + Docker Compose
One-command deployment:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/posthog/posthog/HEAD/bin/deploy-hobby)"
Once deployed, open http://localhost:8000 in your browser to access the PostHog admin interface.
Option 3: Manual Docker Compose Deployment
If you need finer control:
# docker-compose.yml
version: '3.8'
services:
posthog:
image: posthog/posthog:latest
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgres://posthog:posthog@db:5432/posthog
- REDIS_URL=redis://redis:6379/
depends_on:
- db
- redis
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: posthog
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7
volumes:
pgdata:
# Start services
docker-compose up -d
# View logs
docker-compose logs -f posthog
⚠️ Note: The open-source self-hosted version is recommended for ≤ 100K events/month. Above that, consider migrating to PostHog Cloud.
Quick Start: Connect Your First App
Frontend JavaScript SDK
Install the SDK:
npm install posthog-js
Initialize it in your app entry point:
import posthog from 'posthog-js';
posthog.init('YOUR_POSTHOG_API_KEY', {
api_host: 'https://us.posthog.com', // For self-hosted: http://your-server:8000
autocapture: true, // Automatically captures all clicks, pageviews, etc.
});
// Manually send a custom event
posthog.capture('user_signed_up', {
method: 'email',
plan: 'free',
});
// Identify the user (call this on login)
posthog.identify('user-unique-id-123', {
email: 'developer@example.com',
name: 'John Doe',
});
With autocapture: true, you don't need to write any tracking code at all — every button click, link click, and form submission is automatically recorded.
Backend Python SDK
For backend events like successful payments or order creation:
pip install posthog
from posthog import Posthog
# Initialize (store API key in environment variables)
posthog = Posthog(
project_api_key='YOUR_PROJECT_API_KEY',
host='https://us.posthog.com'
)
# Capture an event
posthog.capture(
distinct_id='user-unique-id-123',
event='payment_completed',
properties={
'amount': 99.00,
'currency': 'USD',
'payment_method': 'stripe',
}
)
# Set user properties
posthog.identify(
distinct_id='user-unique-id-123',
properties={
'email': 'developer@example.com',
'plan': 'pro',
'company': 'TechCorp',
}
)
# Shut down the client (on app exit)
posthog.shutdown()
Next.js Full-Stack Integration
npm install posthog-js posthog-node
// components/PostHogProvider.tsx
import { PostHogProvider as PHProvider } from 'posthog-js/react';
import { useEffect, useState } from 'react';
import posthog from 'posthog-js';
export function PostHogProvider({ children }: { children: React.ReactNode }) {
const [clientReady, setClientReady] = useState(false);
useEffect(() => {
posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST || 'https://us.posthog.com',
person_profiles: 'identified_only',
});
setClientReady(true);
}, []);
if (!clientReady) return null;
return <PHProvider client={posthog}>{children}</PHProvider>;
}
// app/layout.tsx
import { PostHogProvider } from '@/components/PostHogProvider';
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<PostHogProvider>{children}</PostHogProvider>
</body>
</html>
);
}
// app/page.tsx
'use client';
import { usePostHog } from 'posthog-js/react';
export default function HomePage() {
const posthog = usePostHog();
return (
<button onClick={() => {
posthog.capture('cta_clicked', {
cta_text: 'Start Free Trial',
page: 'homepage',
});
}}>
Start Your Free Trial
</button>
);
}
Core Features in Practice
1. Product Analytics: Understand User Behavior
Once data is flowing in, PostHog automatically generates trend charts, funnel analysis, and retention curves.
Funnel example: Sign up → Activate → Pay
-- PostHog supports direct SQL queries (ClickHouse)
SELECT
event,
COUNT(DISTINCT distinct_id) as users
FROM events
WHERE event IN ('user_signed_up', 'feature_activated', 'payment_completed')
AND timestamp > now() - INTERVAL 30 DAY
GROUP BY event
ORDER BY timestamp
In the PostHog UI:
1. Go to Product Analytics → Funnels
2. Add steps: user_signed_up → feature_activated → payment_completed
3. Check the conversion rate at each step
Retention analysis:
1. Go to Product Analytics → Retention
2. Pick a first event (e.g. user_signed_up) and a returning event (e.g. pageview)
3. View D1/D7/D30 retention curves
2. Session Replay: Watch Real User Sessions
Session Replay lets you see actual recordings of user sessions — mouse movements, scrolling, clicks, the whole thing.
Configuration:
posthog.init('YOUR_API_KEY', {
api_host: 'https://us.posthog.com',
session_recording: {
maskAllInputs: false, // Don't mask input fields (set true for privacy-sensitive cases)
recordCrossOriginIframes: true,
},
});
Debugging Rage Clicks:
// When a user rapidly clicks the same element 5+ times, a rage click event fires
posthog.onFeatureFlags(() => {
posthog.capture('rageclick', {
element: document.activeElement.tagName,
page: window.location.pathname,
});
});
In the PostHog Dashboard: 1. Filter for all sessions containing rage clicks 2. Watch the recordings directly to spot the UI issue causing frustration 3. Create an issue and assign it to your dev team with one click
3. Feature Flags: Safe Gradual Rollouts
Feature flags let you control feature availability without deploying new code:
// Check if a feature is enabled for the current user
posthog.onFeatureFlags(() => {
const newDashboard = posthog.getFeatureFlag('new-dashboard');
if (newDashboard) {
// Show the new dashboard
renderNewDashboard();
} else {
// Keep the old version
renderOldDashboard();
}
});
Setting up a phased rollout:
// Target by user attributes
posthog.capture('feature_viewed', {
$feature_flag: 'beta-search',
$feature_flag_response: true,
});
In the PostHog admin panel:
1. Go to Feature Flags → Create Flag
2. Name it beta-search
3. Choose a rollout strategy:
- Full rollout (100% of users)
- Percentage rollout (e.g. 10% of users)
- Targeted rollout (by email domain, user group)
4. Save — the SDK picks it up automatically, no redeploy needed
4. A/B Experiments: Data-Driven Decisions
A/B experiments let you validate the impact of feature changes using statistics.
// Experiment code
posthog.onFeatureFlags(() => {
const experiment = posthog.getFeatureFlag('landing-page-test');
if (experiment === 'variant-a') {
showVariantA();
} else if (experiment === 'variant-b') {
showVariantB();
}
// Record experiment exposure
posthog.capture('experiment_exposure', {
$feature_flag: 'landing-page-test',
variant: experiment,
});
});
To create an experiment in PostHog:
1. Go to Experiments → Create Experiment
2. Select the relevant Feature Flag
3. Set the target metric (e.g. payment_completed event)
4. Choose a significance level (usually 95%)
5. Run the experiment and wait for statistically significant results
PostHog automatically calculates p-values, confidence intervals, and winning probability.
5. Error Tracking: Automatic Frontend Exception Capture
import posthog from 'posthog-js';
posthog.init('YOUR_API_KEY', {
api_host: 'https://us.posthog.com',
capture_performance: true,
});
// Automatically capture uncaught errors
window.addEventListener('error', (event) => {
posthog.capture('frontend_error', {
error_message: event.message,
error_url: event.filename,
error_line: event.lineno,
error_col: event.colno,
stack: event.error?.stack,
});
});
// Capture unhandled promise rejections
window.addEventListener('unhandledrejection', (event) => {
posthog.capture('promise_rejection', {
error_message: event.reason?.message || String(event.reason),
});
});
On the PostHog Error Tracking page, you can: - View error frequency trends - Link errors to affected session recordings - Set up alert rules (e.g. notify Slack when daily errors exceed 100)
6. AI Observability: Track LLM Calls
This is one of PostHog's standout features in 2026, built specifically for AI app developers.
Track OpenAI calls with the Python SDK:
pip install posthog openai
from posthog import Posthog
import openai
posthog = Posthog('YOUR_API_KEY', host='https://us.posthog.com')
def generate_with_tracking(user_id: str, prompt: str):
import time
start = time.time()
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}]
)
latency = time.time() - start
tokens_used = response.usage.total_tokens
# Track the LLM call
posthog.capture(
distinct_id=user_id,
event='llm_call_completed',
properties={
'model': 'gpt-4',
'prompt_length': len(prompt),
'response_length': len(response.choices[0].message.content),
'tokens_used': tokens_used,
'latency_ms': latency * 1000,
'success': True,
}
)
return response
Track with LangChain:
from langchain.callbacks import PostHogCallbackHandler
handler = PostHogCallbackHandler(
api_key='YOUR_API_KEY',
host='https://us.posthog.com',
distinct_id='user-123',
)
# Use in a chain
chain = LLMChain(llm=llm, prompt=prompt, callbacks=[handler])
result = chain.run("Hi, please introduce PostHog")
In the PostHog Dashboard you'll see: - Latency distribution for each LLM call - Token consumption and cost breakdowns - Error reasons for failed requests - Call patterns grouped by user
MCP Integration: Query Data from Your Editor
PostHog supports the MCP protocol, so you can query product data directly inside Claude Code, Cursor, and similar tools.
MCP Configuration (Claude Code):
// .mcp.json
{
"mcpServers": {
"posthog": {
"command": "npx",
"args": ["-y", "@posthog/mcp"],
"env": {
"POSTHOG_API_KEY": "phc_your_api_key",
"POSTHOG_PERSONAL_API_KEY": "phx_your_personal_key",
"POSTHOG_PROJECT_ID": "12345",
"POSTHOG_API_HOST": "https://us.posthog.com"
}
}
}
}
Once configured, you can just chat with Claude Code:
> How many users signed up in the last 7 days?
> Show me the conversion funnel for /dashboard
> Which page had the most rage clicks yesterday?
FAQ
Is the PostHog Free Tier Enough?
For most indie developers and small teams: the monthly 1M events + 5,000 recordings is plenty. On a typical SaaS site, 1M events ≈ 50K–100K MAU.
What's the Difference Between Self-Hosted and Cloud?
| Cloud | Self-Hosted | |
|---|---|---|
| Ops overhead | None | Docker + DB management needed |
| Data location | PostHog servers | Your own servers |
| Feature completeness | All features | Some enterprise features unavailable |
| Scale | Any size | ≤ 100K events/mo |
| Cost | Free tier + usage | Server costs |
Does PostHog Have a Big Performance Overhead?
The JavaScript SDK loads asynchronously — it won't block page rendering. The backend SDK uses batched sending via a queue, so there's zero impact on your business logic.
Does It Support Privacy Compliance (GDPR / PIPL)?
Yes. PostHog's EU instance meets GDPR requirements. For the China market, you can adapt to PIPL using maskAllInputs and custom data filtering rules.
Summary
PostHog is the most comprehensive open-source product analytics platform available today — a single tool that replaces Google Analytics + Hotjar + LaunchDarkly + Optimizely + Sentry combined. For developers and product teams, full data ownership + the all-in-one experience is where the real value lies.
Key Resources: - PostHog Website - GitHub Repository ⭐ 19,000+ - Documentation - Self-Hosting Guide - Company Handbook (Open Source)
If you found this article helpful, feel free to share it with more developers!