Skip to main content

Event tracking

Eppo's Track API allow you to record any actions your users perform, like "Signed Up", "Made a Purchase" or "Clicked a Button", along with any properties that describe the action. Once you send these events, Eppo will ingest them, batch, process and load into your data warehouse. You can then use those events in your warehouse to run experiments, construct data pipelines, or power custom tools/dashboards.

Benefits of using the Track API

  • Deeper Insights: You can better understand how people use your product. That helps you figure out where users might get stuck, what features they love, and what drives them to come back.
  • Personalized Experiences: Once you know what actions users are taking, you can customize their experience—like sending personalized messages or recommending features they’d find useful.
  • Consistent Data Flow: By centralizing your event tracking with an API call, you keep everything neat and standard across all your different tools (analytics, CRM, marketing platforms, etc.).

When to Use It

Use the Track API any time you want to record a user’s action. This could be:

  • User signs up or completes onboarding;
  • User views specific screens or pages;
  • User interacts with certain in-app features (clicking a button, changing a setting, etc.);
  • Transactions, such as making a purchase or completing a subscription upgrade;

Example usage

Events are composed of a type string, and a payload. The payload can contain any properties you'd like to associate with the event. The maximum length of the stringified JSON payload is 4096.

Here's an example of how you might use the Track API in a Browser application:

import * as EppoSdk from "@eppo/js-client-sdk";

const eppoClient = EppoSdk.getInstance();
eppoClient.track("added_to_cart", {
productId: "abc-987",
userId: "123",
price: 24.99
});

Data Organization

When configuring Eppo for experimentation, you provide Eppo with a dataset/schema to use for writing intermediate tables for experiment analysis. We use this same dataset for writing events logged by our SDKs. This ensures maximum performance when using metrics based on these events in experiment analysis.

Events table

By default, each event type will be stored in a single table called eppo_events. This table contains the following fields:

Column NameTypeDescription
timestampTIMESTAMPWhen the event was created/tracked (populated automatically)
typeVARCHARType of the event
payloadVARCHARPayload of the event in JSON format
uuidVARCHARUUID of the event (populated automatically)
api_key_prefixVARCHARPrefix of the SDK key used to log the event (populated automatically)
client_ip_fingerprintVARCHARFingerprint of the IP address of the client that logged the event (populated automatically)
environmentVARCHAREnvironment of the event (populated automatically based on the SDK key used)

Custom tables

You can also configure a certain event type to be stored in its own table, with a specific schema. Rather than having a single column that contains the payload sent to the SDK, custom tables can have specific events which are extracted from events in the payload.

For example, consider the following event:

{
"type": "item_added_to_cart",
"payload": {
"user_id": "user_123",
"item_id": "item_456",
"item_name": "Some Widget",
"price": 10.00,
"currency": "USD"
}
}

This event can be configured to be stored in a custom table, with each field in the payload represented as a column in the table. The resulting table will have the following structure (with underlying types depending on your warehouse):

Column NameTypeDescription
user_idVARCHARID of the user who added the item to the cart
item_idVARCHARID of the item added to the cart
item_nameVARCHARName of the item added to the cart
priceDECIMALPrice of the item added to the cart
currencyVARCHARCurrency of the item added to the cart
timestampTIMESTAMPWhen the event was created/tracked (populated automatically)
uuidVARCHARUUID of the event (populated automatically)
api_key_prefixVARCHARPrefix of the SDK key used to log the event (populated automatically)
client_ip_fingerprintVARCHARFingerprint of the IP address of the client that logged the event (populated automatically)
environmentVARCHAREnvironment of the event (populated automatically based on the SDK key used)

Once a table is configured, the schema can only be modified in a backward-compatible manner. This means that you cannot remove or change columns, but you can add new columns.

System latency

Events tracked with our SDKs are buffered to local storage on the user's device (or server, depending on the SDK) before being sent in batches to Eppo's servers. We then do additional batching before writing the results into your warehouse.

The frequency of updates/latency depends on the load/availability of compute resources in your warehouse. You are able to configure how often, and optionally during what times of day events are loaded into your warehouse. The maximum frequency which you are able to configure events to be loaded into your warehouse is 10 minutes.

SDK Configuration

In order to use the Track API in the Eppo SDKs, you need to use an SDK key which was created after November 15, 2024. SDK keys created prior to this date can still be used for feature flag/experiments, but not event tracking.

Other than using a compatible SDK key, there is no additional configuration required. Simply initialize the SDK with your SDK key, and start tracking events.

In order to override the default behavior of certain aspects of event handling, you can modify the following properties (see language-specific pages for examples):

PropertyTypeDescriptionDefault
deliveryIntervalMsnumberTime to wait between each batch delivery, in milliseconds.10,000 (10 seconds)
retryIntervalMsnumberMinimum time to wait before retrying a failed delivery, in milliseconds.5,000 (5 seconds)
maxRetryDelayMsnumberMaximum time to wait before retrying a failed delivery, in milliseconds.30,000 (30 seconds)
maxRetriesnumberMaximum number of retry attempts before giving up on a batch delivery.3
batchSizenumberMaximum number of events to send per batch/network request.1,000
maxQueueSizenumberMaximum number of events to queue in memory before starting to drop events.10,000