Identify: the most common issue with PostHog and how to see if you’re affected

December 30, 2025

If you work with product analytics long enough, certain patterns start repeating themselves. After auditing and fixing dozens of PostHog implementations across startups, scale-ups, and enterprise teams, one issue shows up more than any other:

The misuse of the $identify event.

Short explanation on what it is: this helps identify a user and tie them to a PostHog person for all analytics across PostHog.

This article explains why this is the most common PostHog problem we see across all of our clients, how it quietly breaks your data, and exactly how to tell if your project is affected.

Everything below is grounded in PostHog’s official documentation and real production cases.

Why $identify matters more than you think

At a high level, $identify exists for one job only: linking an anonymous user to a known user.

In PostHog, users usually start anonymous. They browse pages, trigger events, and generate sessions with a randomly assigned distinct_id. When you later learn who that user is (most commonly after login or signup), you call $identify with a stable identifier like a user ID or email. PostHog then merges the anonymous history with the known user profile.

$identify is meant to be called once per identity transition, not repeatedly. Repeated calls are unnecessary and harmful.

Yet in practice, many teams end up calling $identify:

  • On every page load
  • On every event
  • On every session start
  • Inside shared layout components
  • Inside analytics wrappers that fire more often than expected

The result is subtle at first. Funnels look a bit odd. Session counts feel inflated. Feature flag targeting behaves strangely. Over time, the data becomes harder to trust.

This is why we say this is the most common issue we see across all of our clients. Not because teams are careless, but because it is surprisingly easy to get wrong.

What actually goes wrong when $identify is misused

To understand the impact, it helps to know what happens internally when $identify fires.

Each $identify call tells PostHog: "this anonymous ID and this known ID belong to the same person." If you do this once, that's perfect and how it’s supposed to be. If you do it dozens or hundreds of times for the same user, PostHog still processes every call.

Here are the most common downstream effects we see in real client data:

  • First, inflated event volume and costs. $identify is still an event. Calling it excessively increases ingestion volume and billing without adding any analytical value. We've seen clients where 70% of their event volume is identify/set events.
  • Second, confusing person profiles. You may see a single person with dozens or hundreds of associated distinct IDs. This makes debugging individual user journeys extremely difficult and can make your data feel unreliable.
  • Third, mid-session experience changes. If you call identify multiple times during a session (especially with different properties), feature flags may re-evaluate based on the new identity information, potentially changing the user experience mid-session.
  • Fourth, analytics noise. In our client work, we've observed that excessive identity operations can introduce attribution noise that makes funnels harder to interpret and can affect person-based metrics.

The fastest way to tell if you have a problem

On the very first call with a new client, before we look at dashboards, funnels, or feature flags, we always run the same query together. It almost always tells us whether there is an identity problem.

Here is the query:

SELECT
    properties.$host AS host,
    count(DISTINCT $session_id) AS sessions,
    sum(if(event = '$identify', 1, 0)) AS identify_calls,
    round(
        sum(if(event = '$identify', 1, 0)) 
        / toFloat(count(DISTINCT $session_id)),
        2
    ) AS identify_per_session_ratio
FROM events
GROUP BY properties.$host
ORDER BY sessions DESC

This query looks at ALL data and answers one simple question:

How many $identify calls are happening per session?

We group by properties.$host because many teams track multiple domains or environments in the same PostHog project. This helps isolate where the problem lives.

How to interpret the results

The most important column in this query is identify_per_session_ratio. It tells you how often $identify is being called relative to real user sessions.

In a healthy PostHog implementation, this ratio should be below 1.

Why? Because $identify is not a “trigger on every session” event. It should only fire when a user transitions from anonymous to known, which is a relatively rare moment in a user’s lifecycle. Once a user is identified, PostHog already knows who they are. Re-identifying them on every session adds no value and often causes harm.

In most products:

  • Anonymous sessions never trigger $identify
  • Returning logged-in users should not trigger $identify again
  • A user should typically be identified once, not repeatedly

As a result, it’s very normal to see ratios like 0.05, 0.1, or 0.2 in well-implemented projects. These numbers usually indicate a healthy identity setup, not missing tracking.

The warning signs appear when the ratio starts approaching 1. At that point, $identify is likely being fired once per session, which is rarely necessary and often a sign of mis-implementation.

When the ratio exceeds 1, the issue is usually severe. This means $identify is being fired multiple times within a single session. We’ve seen ratios of 5, 10, and even 20 in real client projects. At that point, session counts, funnels, feature flags, and person profiles are all likely being distorted, and analytics built on top of that data become unreliable.

Common implementation patterns that cause this

After fixing this issue across many teams, we’ve noticed the root causes are mostly the same.

  • One very common pattern is calling $identify inside a global layout or app shell. In single-page applications, this code may run on every route change, not just on login.
  • Another common issue is calling $identify immediately after reading user data from local storage or cookies. This happens on every page load, even though the user is already identified.
  • We also frequently see $identify wrapped inside generic “track user” helpers that are called by multiple components. Each component thinks it is being safe, but together they create a storm of identity calls.
  • Some teams also call $identify on both the backend and frontend for the same action, doubling the problem.

None of these teams intend to misuse $identify. The issue comes from misunderstanding when it is actually needed.

What PostHog officially recommends

PostHog’s documentation is very clear on this point.

$identify should be called once per user, when you first know who they are. After that, you should rely on PostHog’s internal identity handling. You do not need to keep reminding PostHog who the user is.

Based on PostHog's guidance and real implementation issues we see, excessive identify calls commonly lead to:

  • Unexpected session behavior
  • Hard-to-debug person profiles
  • Data quality issues

This is not a gray area. The docs are explicit, and the product behavior confirms it.

How to fix it safely

The fix is almost always simpler than teams expect.

First, decide what your stable user identifier is. This should be something that does not change, like a database user ID. Emails can work, but IDs are safer.

Second, call $identify once, at the moment you first know that identifier. This is usually:

  • After signup
  • After login
  • or any kind of account creation

Third, remove $identify from:

  • Page load handlers
  • Layout components
  • Shared tracking utilities
  • Repeated lifecycle hooks

Finally, test again using the same query. A healthy project will usually show a ratio well below 1, often closer to 0.1 or lower depending on traffic mix.

Final thoughts

If you are using PostHog and you have never checked how often $identify fires, there is a good chance your project is affected.

This single check has uncovered more broken analytics implementations than any other technique we use. Fixing it often unlocks clearer insights, better decisions, and far more confidence in your data.

Recent Blogs

calendar icon

Nov 28, 2025

calendar icon

November 06, 2025

calendar icon

October 31, 2025

calendar icon
hubspot logo

PostHog Identify, Explained: How User Identity Really Works in Product Analytics

Have a look at how you can setup your PostHog instance for identifying user actions and save time in the long run!

calendar icon
hubspot logo

How to Setup PostHog with Clay and Cloud Functions

See how you can create a full loop with PostHog, Clay and Cloud functions for your Product.

calendar icon
hubspot logo

How to Sync Customer.io Data into PostHog

Check out how you can use Customer.io campaigns data in PostHog for analytics.

calendar icon
hubspot logo

How to Bring Your Database Data into PostHog

See how you can use rich data sitting in your product or marketing database in PostHog for Analytics.

calendar icon
hubspot logo

Google Ads to BigQuery Setup for PostHog Integration

Check out how you can set up Google Ads data to be synced with BigQuery for PostHog analytics.