PostHog enables you to analyze data in real-time, as events come in. Make full use of this power by ingesting live data with our analytics integrations: client libraries, server libraries, as well as third-party platforms.
The purpose of this guide is to help you understand some key concepts with a goal of ingesting live data into PostHog. For simplicity, we'll focus on client libraries as a means of data ingestion.
The guide covers the following:
- Installing and initializing a PostHog library
- How autocapture works with the JavaScript library
- How to capture user events with PostHog
- How to identify and associate users with events
If you prefer to learn by doing, you can get started on the web with the JavaScript snippet.
Note that some events with a never-before-seen distinct ID are deliberately delayed by around a minute. More on that in the "Event ingestion nuances" section.
Install a library
Install the library for the platform you are building your application for.
You can either load the snippet as a script in your HTML:
Place the snippet in the <head> tags of your website, ideally just above the closing </head> tag. You will need to do this for all pages that you wish to track.
Or you can include it using npm, by doing either:
or:
And then include it in your files:
If you don't want to send a bunch of test data while you're developing, you could do the following:
The best way to install the PostHog Android library is with a build system like Gradle. This ensures you can easily upgrade to the latest versions.
All you need to do is add the posthog module to your build.gradle:
The best place to initialize the client is in your Application subclass.
PostHog is available through CocoaPods and Carthage or you can add it as a Swift Package Manager based dependency.
CocoaPods
Carthage
Swift Package Manager
Add PostHog as a dependency in your Xcode project "Package Dependencies" and select the project target for your app, as appropriate.
For a Swift Package Manager based project, add PostHog as a dependency in your "Package.swift" file's Package dependencies section:
and then as a dependency for the Package target utilizing PostHog:
With Objective-C
With Swift
PostHog is available for install via Pub.
Setup your Android, iOS, and/or web sources as described at PostHog.com and generate your API keys.
Set your PostHog API key and change the automatic event tracking (only for Android and iOS) on if you wish the library to take care of it for you.
Remember that the application lifecycle events won't have any special context set for you by the time it is initialized. If you are using a self-hosted instance of PostHog you will need to have the public hostname or IP for your instance as well.
Android
iOS
Web
For more information please check: https://posthog.com/docs/integrate/client/js
In your React Native or Expo project add the posthog-react-native package to your project as well as the required peer dependencies.
The recommended flow for setting up PostHog React Native is to use the PostHogProvider which utilises the Context API to pass posthog around as well as enabling autocapture and ensuring that the queue is flushed at the right time:
Alternatively you can simply create a global instance of PostHog with your API Key and any options. This allows you to use PostHog outside of the PostHogProvider but limits the functionality of PostHog (such as autocapture).
For most people, the default configuration options will work great but if you need to you can further customise how PostHog will work.
Use autocapture
Autocapture is presently only available in the web browser using the JavaScript library. For non-browser platforms and for situations where you wish to manually capture events, see the capture user events section.
When you call posthog.init the PostHog JS library begins automatically capturing user events:
- pageviews, including the URL
- autocaptured events, such as any click, change of input, or submission associated with a,button,form,input,select,textarea, andlabeltags
PostHog puts a great amount of effort into making sure it doesn't capture any sensitive data from your website. If there are other elements you don't want to be captured, you can add the ph-no-capture class name.
Capture user events
This allows you to send more context than the default event info that PostHog captures whenever a user does something. In that case, you can send an event with any metadata you may wish to add.
A capture call requires:
- eventto specify the event name- We recommend naming events with "[noun][verb]", such as movie playedormovie updated, in order to easily identify what your events mean later on (we know this from experience).
 
- We recommend naming events with "[noun][verb]", such as 
Optionally you can submit:
- properties, which is an object with any information you'd like to add
Identify users
To make sure you understand which user is performing actions within your app, you can identify users at any point. From the moment you make this call, all events will be identified with that distinct id.
The ID can by anything, but is usually the unique ID that you identify users by in the database.
Normally, you would put this below posthog.init if you have the information there.
If a user was previously anonymous (because they hadn't signed up or logged in yet), we'll automatically alias their anonymous ID with their new unique ID. That means all their events from before and after they signed up will be shown under the same user.
You can also pass two more arguments to posthog.identify. Both take objects consisting of as many properties as you want to be set on that user's profile. The difference is that the second argument will use the $set mechanism, whereas the third argument will use $set_once. 
You can read more about the difference between this in the setting properties section.
Warning! You can't call identify straight after an `.init` (as `.init` sends a pageview event, probably with the user's anonymous ID).
To address the issue described above, you can call .init passing a loaded callback function, inside which you can then call identify, like so:
When you start tracking events with PostHog, each user gets an anonymous ID that is used to identify them in the system.
In order to link this anonymous user with someone from your database, use the identify call. 
Identify lets you add metadata to your users so you can easily identify who they are in PostHog, as well as do things like segment users by these properties.
An identify call requires:
- distinctIdwhich uniquely identifies your user in your database
- userPropertieswith a dictionary of key:value pairs
The most obvious place to make this call is whenever a user signs up, or when they update their information.
When you call identify, all previously tracked anonymous events will be linked to the user.
When you start tracking events with PostHog, each user gets an anonymous ID that is used to identify them in the system.
In order to link this anonymous user with someone from your database, use the identify call. 
Identify lets you add metadata to your users so you can easily identify who they are in PostHog, as well as do things like segment users by these properties.
An identify call requires:
- distinct_idwhich uniquely identifies your user in your database
- propertieswith a dictionary of key:value pairs
For example:
The most obvious place to make this call is whenever a user signs up, or when they update their information.
When you call identify, all previously tracked anonymous events will be linked to the user.
See the Flutter library docs for more information.
When you start tracking events with PostHog, each user gets an anonymous ID that is used to identify them in the system.
In order to link this anonymous user with someone from your database, use the identify call. 
Identify lets you add metadata on your users so you can more easily identify who they are in PostHog, and even do things like segment users by these properties.
An identify call requires:
- distinctIdwhich uniquely identifies your user in your database
- userPropertieswith a dictionary with key: value pairs
The most obvious place to make this call is whenever a user signs up, or when they update their information.
When you call identify, all previously tracked anonymous events will be linked to the user.
Event ingestion nuances
It's a priority for us that events are fully processed and saved as soon as possible. However, there is a class of events which we deliberately process with a slight delay. Specifically, an event is delayed by around a minute if it fits all of the following three conditions:
- isn't from an anonymous user (anonymous users are recognized by having the distinct_idthe same as the$device_idproperty)
- isn't an $identifyevent (e.g. fromposthog.identify())
- its distinct_idcannot be matched to an existing person
This delay mechanism is called the event buffer, and it materially improves handling of an edge case which could otherwise inflate unique user counts.
How does the event buffer help?
Starting with version 1.38.0, PostHog stores the person associated with an event inline with the event record. This greatly improves query performance, but because events are immutable, it also means that persons can't be merged retroactively. See this scenario where that's problematic:
- User visits signup page, in turn frontend captures anonymous $pageviewfor distinct IDXYZ(anonymous distinct ID = device ID).
 This event gets person IDA.
- User click signup button, initiating in a backend request, in turn frontend captures anonymous $autocapture(click) for distinct IDXYZ.
 This event gets person IDA.
- Signup request is processed in the backend, in turn backend captures identified signup for distinct ID alice@example.com.
 OOPS! We haven't seenalice@example.combefore, so this event gets person IDB.
- Signup request finishes successfully, in turn frontend captures identified $identify aliasing distinct ID XYZtoalice@example.com.
 This event gets person IDA.
Here, the event from step 3 got a new person ID B, impacting unique users counts. If it were delayed just a bit and processed after the event from step 4, all events would get the expected person ID A. This is exactly what the event buffer achieves.