Skip to content

Design a Product Analytics System, stage 6 of 9: break it

Two visitors who were one person

Anonymous events carry a random device ID. At signup, the snippet sends an identify call linking that device ID to the new account. Person data is copied onto events at ingestion, as decided in the last stage.

System so far· 8 parts
12345678CLIENTCustomers' appsEDGECapture APILOG / STREAMEvent streamWORKERIngestionworkersDATABASEEvents(column store)DATABASEPostgresSERVICEQuery serviceCLIENTCustomers'dashboards

Select a component to see what it is responsible for and which state it owns.

  1. 1Customers' apps → Capture API: Batches of events
  2. 2Customers' dashboards → Query service: Chart request
  3. 3Query service → Postgres: Teams and saved charts
  4. 4Query service → Events (column store): Aggregate by column
  5. 5Capture API → Event stream: Append, then acknowledge
  6. 6Ingestion workers → Event stream: Read a partition
  7. 7Ingestion workers → Postgres: Who is this ID?
  8. 8Ingestion workers → Events (column store): Batch insert

What you need to know

0 of 2 checks done
  1. Before signup, a visitor's events carry a random device ID. At signup, an identify call links that device ID to the new account. But earlier events were already stored with the device ID, and in a column store nothing rewrites stored events cheaply.

    So after the link, the same human appears as two people in older data.

  2. Check

    What's a cheap way to make funnels count them as one person without rewriting events?