Product analytics — PostHog, Mixpanel, events, funnels, cohorts, retention, north star metric, OKRs, and product dashboards. Use for: event tracking setup, conversion funnel analysis, cohort retention, DAU/MAU, feature flags, A/B testing, north star metrics, OKRs, product dashboards.
Product analytics skill covering PostHog, Mixpanel, events, funnels, cohorts, retention, north star metric, OKRs, and product dashboards. Use for: event tracking setup, conversion funnel analysis, cohort retention, DAU/MAU, feature flags, A/B testing, north star metrics, OKRs, and product dashboards.
Note: Code examples throughout this skill use a sample SaaS product as reference — adapt event names, metrics, and targets to your own product.
[object]_[past_verb]
Correct: user_signed_up, conversation_started, upgrade_completed
Wrong: signup, click, conversion
"In God we trust. All others must bring data." — W. Edwards Deming
PRODUCT_EVENTS = {
# Acquisition
"user_signed_up": {"props": ["source", "medium", "campaign"]},
"onboarding_started": {"props": ["step_count"]},
"onboarding_completed": {"props": ["time_to_complete", "steps_skipped"]},
# Activation
"first_conversation": {"props": ["intent", "response_time"]},
"aha_moment_reached": {"props": ["trigger", "session_number"]},
"feature_discovered": {"props": ["feature_name", "discovery_method"]},
# Retention
"conversation_started": {"props": ["intent", "user_tier", "device"]},
"conversation_completed":{"props": ["messages_count", "duration", "rating"]},
"session_started": {"props": ["days_since_last", "platform"]},
# Revenue
"upgrade_viewed": {"props": ["trigger", "current_tier"]},
"upgrade_started": {"props": ["target_tier", "trigger"]},
"upgrade_completed": {"props": ["tier", "plan", "revenue"]},
"subscription_canceled": {"props": ["reason", "tier", "tenure_days"]},
"payment_failed": {"props": ["attempt_count", "error_code"]},
}
from posthog import Posthog
import os
posthog = Posthog(
project_api_key=os.environ["POSTHOG_API_KEY"],
host=os.environ.get("POSTHOG_HOST", "https://app.posthog.com")
)
def track(user_id: str, event: str, properties: dict = None):
posthog.capture(
distinct_id=user_id,
event=event,
properties=properties or {}
)
def identify(user_id: str, traits: dict):
posthog.identify(
distinct_id=user_id,
properties=traits
)
## Usage:
track("user_123", "conversation_started", {
"intent": "business_advice",
"device": "mobile",
"user_tier": "pro"
})
Visits landing page (100%)
| [target: 40%]
Clicks "Try it" (40%)
| [target: 70%]
Completes sign-up (28%)
| [target: 60%]
Has first conversation (17%) <- AHA MOMENT
| [target: 50%]
Returns next day (8.5%)
| [target: 40%]
Uses 3+ days per week (3.4%)
| [target: 20%]
Converts to Pro (0.7%)
For each drop-off above benchmark:
1. Identify: where exactly does the user leave?
2. Understand: why? (session recordings, surveys)
3. Hypothesise: what change could improve this?
4. Test: A/B test with a statistically significant sample
5. Measure: minimum 2 weeks, p-value < 0.05
6. Learn: even failures improve your understanding of the user
def calculate_cohort_retention(events_df):
"""
events_df: DataFrame with columns [user_id, event_date, event_name]
Returns: retention matrix [cohort_week x week_number]
"""
import pandas as pd
first_session = events_df[events_df.event_name == "session_started"] \
.groupby("user_id")["event_date"].min() \
.dt.to_period("W")
sessions = events_df[events_df.event_name == "session_started"].copy()
sessions["cohort"] = sessions["user_id"].map(first_session)
sessions["weeks_since"] = (
sessions["event_date"].dt.to_period("W") - sessions["cohort"]
).apply(lambda x: x.n)
cohort_data = sessions.groupby(["cohort", "weeks_since"])["user_id"].nunique()
cohort_sizes = cohort_data.unstack().iloc[:, 0]
retention = cohort_data.unstack().divide(cohort_sizes, axis=0) * 100
return retention
| Week | Poor | OK | Good | Excellent |
|---|---|---|---|---|
| W1 | <20% | 20-35% | 35-50% | >50% |
| W4 | <10% | 10-20% | 20-30% | >30% |
| W8 | <5% | 5-12% | 12-20% | >20% |
Framework:
1. What creates real value for the user? -> Conversations that generate insight/action
2. What predicts long-term growth? -> Users with 3+ conversations per week
3. How to measure it? -> "Weekly Active Conversationalists" (WAC)
North Star: WAC (Weekly Active Conversationalists)
Definition: Users with >= 3 conversations per week lasting >= 2 minutes
Year 1 Target: 10,000 WAC
Year 2 Target: 100,000 WAC
def calculate_north_star(db):
wac = db.query("""
SELECT COUNT(DISTINCT user_id) as wac
FROM conversations
WHERE
created_at >= NOW() - INTERVAL '7 days'
AND duration_seconds >= 120
GROUP BY user_id
HAVING COUNT(*) >= 3
""").scalar()
return {
"wac": wac,
"wow_growth": calculate_wow_growth(db, "wac"),
"target": 10000,
"progress": f"{wac/10000*100:.1f}%"
}
def is_feature_enabled(user_id: str, feature: str) -> bool:
return posthog.feature_enabled(feature, user_id)
if is_feature_enabled(user_id, "new-onboarding-v2"):
show_new_onboarding()