Elixir
Contents
This library provides an Elixir HTTP client for PostHog. See the repository for more information.
Installation
This library was built by the community but it's being maintained by the PostHog core team since v1.0.0. Thank you to Nick Kezhaya for building it originally. Thank you to Alex Martsinovich for contributing v2.0.0.
The package can be installed by adding posthog to your list of dependencies in mix.exs:
Configuration
You can see all the available configuration options in the PostHog.Config module.
Optionally, you might want to enable the Plug integration to automatically capture events from your Plug-based applications including Phoenix.
Development/Test mode
For a test environment, you can pass in test_mode: true value to the config. This causes events to be dropped instead of sent to PostHog.
Identifying users
Identifying users is required. Backend events need a
distinct_idthat matches the ID your frontend uses when callingposthog.identify(). Without this, backend events are orphaned — they can't be linked to frontend event captures, session replays, LLM traces, or error tracking.See our guide on identifying users for how to set this up.
Capturing events
To capture an event, use PostHog.capture/2:
Tip: We recommend using a
[object] [verb]format for your event names, where[object]is the entity that the behavior relates to, and[verb]is the behavior itself. For example,project created,user signed up, orinvite sent.
Setting event properties
Optionally, you can include additional information with the event by including a properties object:
Context
Carrying distinct_id around all the time might not be the most convenient approach, so PostHog lets you store it and other properties in a context.
The context is stored in the Logger metadata and PostHog automatically attaches these properties to any events you capture with PostHog.capture/2, as long as they happen in the same process.
You can also scope the context to a specific event name:
Batching events
Events are automatically batched and sent to PostHog via a background job.
Special events
PostHog.capture/2 is very powerful and enables you to send events that have special meaning.
In other libraries you'll usually find helpers for these special events, but they must be explicitly sent in Elixir.
For example:
Create alias
Group analytics
Feature flags
PostHog's feature flags enable you to safely deploy and roll back new features as well as target specific users and groups with them.
There are two steps to implement feature flags in Elixir:
Step 1: Evaluate flags once
Call PostHog.FeatureFlags.evaluate_flags/1 once for the user, then read values from the returned snapshot.
Boolean feature flags
Multivariate feature flags
PostHog.FeatureFlags.Evaluations.get_flag/2 returns the variant string for multivariate flags, true for enabled boolean flags, false for disabled flags, and nil when the flag wasn't returned by the evaluation.
Note:
PostHog.FeatureFlags.check/2,PostHog.FeatureFlags.check!/2,PostHog.FeatureFlags.get_feature_flag_result/2, andPostHog.FeatureFlags.get_feature_flag_result!/2still work during the migration period, but they're deprecated. Preferevaluate_flags/1for new code.
Step 2: Include feature flag information when capturing events
If you want use your feature flag to breakdown or filter events in your insights, you'll need to include feature flag information in those events. This ensures that the feature flag value is attributed correctly to the event.
Note: This step is only required for events captured using our server-side SDKs or API.
There are two methods you can use to include feature flag information in your events:
Method 1: Put the evaluated flags snapshot in context
Put the same snapshot object that you used for branching into context. Subsequent captures from the same process attach the exact flag values from that evaluation and don't make another /flags request.
By default, this attaches every flag in the snapshot using $feature/<flag-key> properties and $active_feature_flags.
To reduce event property bloat, put a filtered snapshot in context:
only_accessed/1 is order-dependent. If you call it before accessing any flags with enabled?/2, get_flag/2, or get_flag_payload/2, no feature flag properties are attached.
Method 2: Include the $feature/feature_flag_name property manually
In the event properties, include $feature/feature_flag_name: variant_key:
Evaluating only specific flags
By default, evaluate_flags/1 evaluates every flag for the user. If you only need a few flags, pass flag_keys to request only those flags:
Sending $feature_flag_called events
Capturing $feature_flag_called events enables PostHog to know when a flag was accessed by a user and provide analytics and insights on the flag. With evaluate_flags/1, the SDK sends this event when you call PostHog.FeatureFlags.Evaluations.enabled?/2 or PostHog.FeatureFlags.Evaluations.get_flag/2 for a flag.
PostHog.FeatureFlags.Evaluations.get_flag_payload/2 doesn't send $feature_flag_called events.
Error tracking
Error tracking is enabled by default. It will automatically captures exceptions thrown by the application.
As a matter of fact, since this is built on top of Elixir's Logger module, it automatically captures any Logger.error calls.
You can always disable it by setting enable_error_tracking to false:
Advanced configuration
By default, PostHog starts its own supervision tree and attaches a logger handler.
In certain cases, you might want to run this supervision tree yourself. You can do this by disabling the default supervisor and adding PostHog.Supervisor to your application tree with its own configuration:
Multiple instances
In even more advanced cases, you might want to interact with more than one PostHog project. In this case, you can run multiple PostHog supervision trees, one of which can be the default one:
Then, each function in the PostHog module accepts an optional first argument with the name of the PostHog supervisor tree that will process the capture:
Thanks
The library is maintained by the PostHog team since February 2025. Thanks to nkezhaya for contributing v0.1.0. Thanks to martosaur for contributing v2.0.0.