Knowing how many distinct users are actually using your product is foundational. PostHog tracks this out of the box, but the setup matters — if users aren't identified consistently, your unique user count won't reflect reality. We'll cover the key patterns to get accurate counts.
Set Up User Identification
PostHog's unique user tracking starts with the identify() call. Without it, PostHog treats each session as a separate user.
Call identify() when a user logs in
Use the PostHog SDK to send a unique identifier (user ID, email, or internal identifier) as soon as you know who the user is. This ties all their events to a single user record.
posthog.identify(
'user_123', // Unique identifier
{
email: '[email protected]',
name: 'Alice Johnson',
plan: 'pro'
}
);Attach custom properties to track user context
Pass properties like plan tier, signup date, or region alongside the ID. These properties let you segment your unique user counts later.
posthog.identify('user_123', {
email: '[email protected]',
signup_date: '2025-01-15',
monthly_revenue: 2500,
account_status: 'active'
});Reset on logout
Call reset() when a user logs out to clear the identified user from the session. This prevents cross-user event attribution.
function handleLogout() {
posthog.reset();
// Then redirect to login
}Create a Unique Users Insight
Once users are identified, you can build an insight to see your active user counts.
Open Insights and create a new metric
Navigate to Insights > + New in the PostHog sidebar. You'll see the trend builder. For tracking unique users, select Unique users as your metric (not Events).
// Query unique users via API (optional, if you're building your own dashboard)
fetch('https://app.posthog.com/api/projects/YOUR_PROJECT_ID/insights/', {
method: 'POST',
headers: {
'Authorization': `Bearer YOUR_API_KEY`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
filters: {
insight: 'TRENDS',
display: 'ActionsLineGraph',
events: [{id: '$pageview', type: 'events'}],
properties: []
},
date_from: '-30d'
})
}).then(r => r.json()).then(data => console.log(data));Filter by date range and properties
Set a date range (last 7 days, last 30 days, etc.). Use Filters to segment by user properties — for example, show unique users by plan tier or account status.
// Track unique users from plan='pro' in the last 30 days
// In the UI: Unique users → Filter by plan = 'pro' → Date range: Last 30 days
// Or via SDK events, ensure plan is captured:
posthog.capture('user_action', {
plan: 'pro'
});Choose aggregation and save
Select how PostHog groups the data: by Day, by Week, or by Month. Save the insight with a clear name like "DAU (Daily Active Users)" or "Monthly Unique Users".
distinct_id in PostHog. If you want to count identified users only, filter out anonymous sessions.Monitor Trends and Returning Users
Beyond absolute counts, you want to see if the same users keep coming back.
Use Retention to track returning users
Go to Insights > Retention. This shows what percentage of your unique users from a start period (e.g., Week 1) return in later periods (Week 2, Week 3, etc.). It's a better signal than raw user count.
// Retention is calculated server-side in PostHog
// Ensure you're capturing events for returning users:
posthog.capture('feature_used', {
feature: 'dashboard_view',
duration_seconds: 45
});
// PostHog will track: User identified on day 1 → Captured event on day 8 → Counts as "returned"Set up a dashboard to monitor continuously
Pin your Unique Users insight and Retention insight to a dashboard. Check it regularly — daily is standard for early-stage products, weekly for mature ones.
// If you're building a custom dashboard, fetch insight data periodically:
setInterval(() => {
fetch(`https://app.posthog.com/api/projects/YOUR_PROJECT_ID/insights/?order=created_at&limit=10`)
.then(r => r.json())
.then(data => {
const uniqueUsersInsight = data.results.find(i => i.name.includes('Unique Users'));
console.log('Current unique users:', uniqueUsersInsight.result);
});
}, 3600000); // Check every hourCommon Pitfalls
- Calling identify() after capturing events — events before identify() won't be attributed to that user. Always identify early, ideally on page load.
- Using non-unique identifiers like IP address or session ID. PostHog needs a stable, user-level ID (user_id, email) to track the same person across sessions.
- Forgetting to call reset() on logout — if you don't, the next user on that device will be attributed to the previous user.
- Confusing unique users with event count. You can have 1,000 unique users and 50,000 events. The metric depends on your question.
Wrapping Up
You now have the foundation to track unique users accurately in PostHog: identify users with stable IDs, build insights to visualize counts, and monitor retention to understand stickiness. These metrics become the baseline for all downstream analytics. If you want to track this automatically across tools, Product Analyst can help.