Chapter 02

Identity and sessions

Twig records each filter selection as a stay_filter_selected event. Its destination_type property shows which destination was chosen. This tells the team what happened, but not who was behind the interaction.

PostHog adds two identifiers that help connect the event to the visitor and visit that produced it:

  • distinct_id groups events under the same identity.
  • $session_id groups events from the same session.

Group events into one visit

Put yourself in the shoes of an anonymous Twig visitor. Select Forest, then Coast, and notice how the distinct_id and $session_id remain the same:

Twig
Filter by destination type
Dark A-frame cabin among autumn trees, with a gravel path leading to the entrance at dusk

Adiron-shack

Adirondacks, New York

4 guests · 2 bedrooms · 2 baths

$355 / night USD

Inspector
Identityanon_7f3
anonymous browser
distinct_id: "anon_7f3"
$session_id: "session_a1"
Select Forest, then Coast to capture both events.

The matching IDs tell the Twig team that both selections happened during one session and both events came from the same anonymous identity.

For this visit, PostHog counts two events associated with the same anonymous identity and session. The identity and session help the team determine which visitor and visit the events belong to, while the event count records how many distinct actions occurred.

There's a problem with anonymous IDs, though: anon_7f3 identifies activity from this browser, but it doesn't show who was using it. If two people share the browser, they share an anonymous ID, so the Twig team has no idea which one generated the activity.

Same browser, new session

The next day, an anonymous browser can return and select a new filter: City.

By default, PostHog starts a new session after 30 minutes without activity. The anonymous ID stored in the browser remains, but the session ID changes.

Twig has now recorded three selections from one anonymous identity across two sessions:

  • distinct_id: anon_7f3 connects the events to the same browser identity.
  • $session_id: session_b2 places the City selection in a different visit.

The anonymous ID does not automatically follow someone to another browser, phone, or computer. Clearing browser storage also removes that connection.

This presents a problem for the Twig engineers: they still can't claim that anon_7f3 represents a person or understand their session history.

Identify visitors

Twig offers accounts so visitors can edit their profiles, save and view their booked stays, and update account settings. Select the bookmark on Adiron-shack, then sign in to Twig's demo account for Edgar Hogg:

Twig
Dark A-frame cabin among autumn trees, with a gravel path leading to the entrance at dusk

Adiron-shack

Adirondacks, New York

4 guests · 2 bedrooms · 2 baths

$355 / night USD

Inspector
Identityanon_7f3
anonymous browser
distinct_id: "anon_7f3"
$session_id: "session_b2"
Select the bookmark to start Twig's sign-in flow.

When Edgar signs in, Twig calls posthog.identify() with user_812, his account ID from Twig's database – not an ID created by PostHog.

PostHog links his anonymous activity to his person profile. Earlier events keep their original distinct_id: anon_7f3, but activity before and after sign-in appears together. Separate visits remain separate sessions.

On his phone, Edgar starts with a different anonymous ID. Signing in with the same account ID connects that device's activity to his profile too. Without signing in, it stays anonymous.

Connect browser and server activity

Suppose Edgar clicks Book stay in his browser and Twig's server completes the booking. The engineers want to connect both actions to Edgar.

In the browser, identify() tells PostHog which account to use for subsequent events. On the server, the engineers pass that account ID with each event.

Here, user_812 represents the ID from Edgar's signed-in account – not a value to hard-code. Both events arrive with the same distinct_id, connecting them to the same person.

Reset the identity at sign-out

Now suppose Edgar signs out and a second person uses Twig in the same browser. Open the profile menu and select Log out:

Twig
Inspector
IdentityEdgar Hogg
signed-in browser
distinct_id: "user_812"
$session_id: "session_b2"
Open the profile menu and select Log out.

When Edgar signs out, Twig tells the PostHog tracking code in the browser to forget his identity. reset() replaces Edgar's identified distinct_id with a new anonymous ID and starts a new session. Edgar's person profile and earlier events stay unchanged.

Without reset(), the second person's browsing could be attached to Edgar's account. If the second person later signs in, Twig may also attempt to connect two different accounts incorrectly.

The safe sequence is:

  1. Identify the account after sign-in.
  2. Capture that account's activity.
  3. Reset PostHog at sign-out.
  4. Keep later events anonymous until another account signs in.

See the visit behind an event

To see context around a click, like what led to the event or what the user did next, Twig opens the event's Session Replay – a playback of what happened in the browser during that visit.

PostHog uses the same $session_id already attached to the event to find the matching replay. For the City click, session_b2 connects the click to its recorded visit. Because the event’s distinct_id: anon_7f3 is now linked to user_812, PostHog can also connect that visit to Edgar.

Session replay
0.0s / 19.1s
Inspector
Events
2 clicks4 pages
  1. Browse staysPageview
    event
    $pageview
    pathname
    /
    distinct_id
    anon_7f3
    $session_id
    session_b2
  2. City filterClick
  3. Le Nid ChicPageview
  4. Log inPageview
  5. Identify EdgarIdentity
  6. Le Nid ChicPageview
  7. Save stayClick

This creates one connected trail:

Event → visit → person

Now Twig's engineers can connect an event to a person. Next, they use those events to see how many people use a feature and how many finish a booking.