---
title: Event batching for the Python SDK
slug: feature-experimentation/docs/event-batching-python
docTags: 
createdAt: 2026-08-05T20:39:59.000Z
---

The Optimizely Feature Experimentation Python SDK lets you batch events and includes options to set a maximum batch size and flush interval timeout. The benefit of event batching means less network traffic for the same number of decision and conversion events tracked.

:::hint{type="info"}
**Note**
By default, event batching is disabled in Python SDK 3.3.0.

Event batching works with both out-of-the-box and custom event dispatchers.

Ensure you are not sending personally identifiable information (PII) to Optimizely. The event batching process does not remove PII from events.
:::

## Configure event batching

Event batching can be enabled through the usage of `BatchEventProcessor`. Optimizely provides two main options to configure event batching: `batch_size` and `flush_interval`. You can pass in both these options when creating instance of `BatchEventProcessor` and pass the created instance during Optimizely client creation. When using `BatchEventProcessor`, events are held in a queue until either:

- The number of events reaches the defined `batch_size`.
- The oldest event has been in the queue for longer than the defined `flush_interval`, which is specified in seconds. The queue is then flushed and all queued events are sent to Optimizely in a single network request.
- A new datafile revision is received. This occurs only when live datafile updates are enabled.

```python
from optimizely import optimizely
from optimizely import event_dispatcher as optimizely_event_dispatcher
from optimizely.event import event_processor

# Set event dispatcher that the 
# You can reference your own implementation of event dispatcher here
event_dispatcher = optimizely_event_dispatcher.EventDispatcher

# Create instance of BatchEventProcessor.
#
# In this example here we set batch size to 15 events
# and flush interval to 50 seconds. 
# Setting start_on_init starts the consumer
# thread to start receiving events.
#
# See table below for explanation of these
# and other configuration options.  
batch_processor = event_processor.BatchEventProcessor(
    event_dispatcher,
    batch_size=15,
    flush_interval=50,
    start_on_init=True,
)

# Create Optimizely client and pass in instance 
# of BatchEventProcessor to enable batching.
optimizely_client = optimizely.Optimizely(
    sdk_key='<Your SDK Key here>', 
    datafile='<Your datafile here>',
    event_processor=batch_processor
)
```

The following table defines these and other options that you can use to configure the `BatchEventProcessor`.

| Name                                     | Default value                         | Description                                                                                                                                                                                                                                                                                                                    |
| ---------------------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **event\\\_dispatcher**                  | No default value. Required parameter. | An event handler to manage network calls. Provides a \`dispatch\_event\` method that takes in URL and parameters and dispatches request.                                                                                                                                                                                       |
| **logger**\ \*optional\*                 | NoOpLogger                            | A logger implementation to log issues.                                                                                                                                                                                                                                                                                         |
| **flush\\\_interval**\ \*optional\*      | 30                                    | The maximum duration in seconds that an event can exist in the queue before being flushed.                                                                                                                                                                                                                                     |
| **batch\\\_size**\ \*optional\*          | 10                                    | The maximum number of events to hold in the queue. Once this number is reached, all queued events are flushed and sent to Optimizely.                                                                                                                                                                                          |
| **start\\\_on\\\_init**\ \*optional\*    | False                                 | Boolean, which, if set to true starts the thread consuming and queuing events on initializing the \`BatchEventProcessor\`. By default, the value is False, so the consumer thread is not ready to receive any events. One can always start the consumer thread by calling \`start\` on the instance of \`BatchEventProcessor\` |
| **timeout\\\_interval**\ \*optional\*    | 5                                     | The number representing time interval in seconds before joining the consumer thread.                                                                                                                                                                                                                                           |
| **event\\\_queue**\ \*optional\*         | six.moves.queue.Queue                 | Component that lets you accumulate events until they are dispatched.                                                                                                                                                                                                                                                           |
| **notification\\\_center**\ \*optional\* | NotificationCenter                    | Instance of \`optimizely.notification\_center.NotificationCenter\`. By default an instance of \`notification\_center.NotificationCenter\` is created.                                                                                                                                                                          |

For information, see [Initialize the Python SDK](docId:3RNo0adSzdB2ndnj5I_WC).

:::hint{type="danger"}
**Warning**
The maximum payload size is 3.5 MB. Optimizely rejects requests with a 400 response code, `Bad Request Error`, if the batch payload exceeds this limit.

The size limitation is because of the [Optimizely Events API](docId:822ZQOB6Zk2-kWJKavBvA), which Feature Experimentation uses to send data to Optimizely.

The most common cause of a large payload size is a high batch size. If your payloads exceed the size limit, try configuring a smaller batch size.
:::

## Side effects

The table lists other functionality that may be triggered by using this class.

| Functionality          | Description                                                                                                                                                                                                                                                                                   |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| \`LogEvent\`           | Whenever the event processor produces a batch of events, a \`LogEvent\` object is created using the \`EventFactory\`. It contains batch of conversion and decision events. This object is dispatched using the provided event dispatcher and also it is sent to the notification subscribers. |
| Notification Listeners | Flush invokes the LOG\\\_EVENT \[notification listener]\(https\://docs.developers.optimizely.com/feature-experimentation/docs/set-up-notification-listener-python) if this listener is subscribed to.                                                                                         |

### Register `LogEvent` listener

To register a `LogEvent` notification listener:

```python
def on_log_event():
  pass

optimizely_client.notification_center.add_notification_listener(enums.NotificationTypes.LOG_EVENT, on_log_event)
```

### `LogEvent`

`LogEvent` object gets created using [`EventFactory`](https://github.com/optimizely/python-sdk/blob/master/optimizely/event/event_factory.py). It represents the batch of decision and conversion events Optimizely sends to the Optimizely backend.

| Object                                   | Type   | Description                                                                                                                                   |
| ---------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| **http\\\_verb** \*Required (non null)\* | String | The HTTP verb to use when dispatching the log event. It can be \`GET\` or \`POST\`.                                                           |
| **url**\ \*Required (non null)\*         | String | URL to dispatch log event to.                                                                                                                 |
| **params**\ \*Required (non null)\*      | Dict   | Event Batch. It contains all the information regarding every event which is batched. including list of visitors which contains \`UserEvent\`. |
| **headers**                              | Dict   | Request Headers                                                                                                                               |

## Stop BatchEventProcessor on application exit

If you enable event batching, you **must** call the 'stop' method, `batch_processor.stop()`, before exiting. This ensures that queued events are flushed when possible to avoid data loss.

:::hint{type="info"}
**Warning**
Because the BatchEventProcessor maintains a buffer of queued events, you must call `stop()` on the BatchEventProcessor instance before shutting down your application.
:::

| Method     | Description                                                                                                           |
| ---------- | --------------------------------------------------------------------------------------------------------------------- |
| **stop()** | Stops and flushes the event queue. **Note**: You should connect this method to a kill signal for the running process. |
