Retention rate is the canary in the coal mine for product-market fit — but you can't act on it if you're checking PostHog manually every week. PostHog lets you create retention insights and alert on thresholds, so you catch drops before they compound into a churn problem.
Track Returning User Actions
Before you can alert on retention, PostHog needs to see both the initial action (user signs up) and the returning action (user comes back). Start by instrumenting your events.
Initialize PostHog and capture signup events
Load the PostHog SDK in your app and log the initial user action. PostHog identifies users automatically via their distinct_id. For retention, we care about the first event (cohort entry) and then recurring events (returns).
import posthog from 'posthog-js';
// Initialize PostHog
posthog.init('phc_your_api_key', {
api_host: 'https://app.posthog.com',
loaded: (ph) => {
// Called when PostHog is ready
},
});
// Capture signup as the initial cohort action
posthog.capture('user_signed_up', {
plan: 'pro',
source: 'landing',
});
// Capture return activity (e.g., logged in, viewed dashboard)
posthog.capture('dashboard_viewed');
posthog.capture('query_executed');Define cohort criteria on the returning user
For retention to work, PostHog needs to know which users count as "returning." Usually this is any user who does the initial action (signed up) and later does the returning action (logged in, viewed dashboard, made a payment). You can segment by user properties: only premium users, only users from a certain region, etc.
// Add properties to segment retention by user type
posthog.capture('user_signed_up', {
plan: 'pro',
team_size: 'enterprise',
region: 'us-east',
});
// Later, capture the return action
posthog.capture('made_purchase', {
amount: 199,
currency: 'usd',
});
// Link anonymous and identified users
posthog.identify('user_123', {
email: '[email protected]',
company: 'acme',
});distinct_id. If user IDs change between signup and return (anonymous → identified), retention will break. Use posthog.identify() to link IDs before capturing the return event.Create a Retention Insight and Set Alert Threshold
Once events are flowing, go to PostHog and create a retention insight. This shows the percentage of users from each cohort who return. Then configure an alert to notify you when retention dips below your threshold.
Build a retention insight in the PostHog UI
In PostHog, go to Insights > New insight > Retention. Choose your cohort action (e.g., user_signed_up), the returning action (e.g., dashboard_viewed), and the time interval (day, week, month). PostHog displays a cohort table: rows are signup dates, columns are days/weeks/months after signup, cells show the percentage retained.
// Create a retention insight via PostHog's Insights API
const response = await fetch('https://app.posthog.com/api/insights/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${YOUR_PERSONAL_API_TOKEN}`,
},
body: JSON.stringify({
name: 'Weekly Retention - Premium Users',
description: 'Track premium user retention by week',
filters: {
insight: 'RETENTION',
retention_type: 'retention_first_time',
target_entity: {
id: 'dashboard_viewed',
type: 'events',
},
returning_entity: {
id: 'user_signed_up',
type: 'events',
},
period: 'week',
},
}),
});
const insight = await response.json();
console.log('Insight created:', insight.id);Configure the alert trigger and destination
Click Alert on your retention insight. Set the condition: e.g., "if day 7 retention < 40%, alert me." Choose your destination: Slack, webhook, or email. PostHog checks this condition daily and sends a notification if triggered.
// Set up alert via API
const alertResponse = await fetch(
`https://app.posthog.com/api/insights/${insightId}/`,
{
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${YOUR_PERSONAL_API_TOKEN}`,
},
body: JSON.stringify({
derived_name: 'Weekly Retention Alert',
alert_config: {
metric_condition: {
day_index: 7,
threshold_type: 'below',
threshold_value: 40,
},
notification_channels: [
{
type: 'webhook',
url: 'https://your-domain.com/webhooks/retention',
headers: { 'X-API-Key': 'your_secret' },
},
],
},
}),
}
);
const alert = await alertResponse.json();Test Your Alert and Troubleshoot
Before relying on retention alerts, test that they actually fire. PostHog provides a dry-run feature to verify the integration works.
Trigger a test alert from the PostHog UI
On your retention insight, click Alert > Send test notification. PostHog sends a dummy alert to your Slack/webhook/email to confirm the integration is working. Check that the message arrives with the right format and destination.
// If using a webhook, PostHog sends a test payload:
{
"alert_id": "alert_abc123",
"insight_id": "insight_xyz789",
"insight_name": "Weekly Retention - Premium Users",
"condition": "day_7_retention < 40",
"current_value": 38.5,
"threshold": 40,
"is_test": true,
"triggered_at": "2026-03-26T14:22:00Z"
}
// Log it to confirm receipt
app.post('/webhooks/retention', (req, res) => {
console.log(`Retention alert: ${req.body.insight_name}`);
if (req.body.is_test) {
console.log('✓ Test alert received');
}
res.status(200).send('OK');
});Check alert history and tune the threshold
Visit your insight's Alert history tab. You'll see past alerts that fired, their values, and timestamps. If you're getting alert fatigue, raise the threshold or add filters. If alerts are too rare, lower the threshold or check the cohort action definition.
// Fetch alert history via API
const response = await fetch(
`https://app.posthog.com/api/insights/${insightId}/alerts/`,
{
headers: { 'Authorization': `Bearer ${YOUR_PERSONAL_API_TOKEN}` },
}
);
const alerts = await response.json();
alerts.results.forEach((alert) => {
console.log(
`${alert.triggered_at}: ${alert.insight_name} = ${alert.current_value}%`
);
});Common Pitfalls
- Cohort entry and return actions must come from the same
distinct_id. If you identify users after signup without linking IDs, retention will miss the returning event. - Day 1 retention percentages are unreliable because many users churn immediately. Set thresholds on day 7 or day 30 instead.
- Filtering by user properties can hide real drops in a subgroup. Create separate retention insights for each segment (e.g., free vs. pro) to catch regressions early.
- PostHog checks alert conditions once per day. Use webhooks and forward to an on-call tool if you need sub-day notifications.
Wrapping Up
You now have a retention alert system that catches drops before they cascade into churn. Monitor it weekly and adjust your threshold based on business goals — retention is a leading indicator of product health. If you want to track this automatically across tools, Product Analyst can help.