---
title: Event batching for the Go SDK
slug: feature-experimentation/docs/event-batching-go
docTags: 
createdAt: 2026-08-05T20:39:56.000Z
---

The [Optimizely Feature Experimentation Go SDK](https://github.com/optimizely/go-sdk) batches decision and conversion events into a single payload before sending it to Optimizely. This is achieved through an SDK component called the event processor.

Event batching has the advantage of reducing the number of outbound requests to Optimizely depending on how you define, configure, and use the event processor. It means less network traffic for the same number of Impression and conversion events tracked.

In the Go SDK, `QueueingEventProcessor` provides implementation of the `EventProcessor` interface and batches events. You can control batching based on two parameters:

- **Batch size** – Defines the number of events that are batched together before sending to Optimizely.
- **Flush interval** – Defines the amount of time after which any batched events should be sent to Optimizely.

An event consisting of the batched payload is sent when the batch size reaches the specified limit or flush interval reaches the specified time limit. `BatchEventProcessor` options are described in more detail in the following section.

:::hint{type="info"}
**Note**
Event batching works with both out-of-the-box and custom event dispatchers.

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

## Basic example

```go
import optly "github.com/optimizely/go-sdk" // for v2: "github.com/optimizely/go-sdk/v2"

// the default client will have a BatchEventProcessor with the default options
optlyClient, err := optly.Client("SDK_KEY_HERE")
```

By default, batch size is 10 and flush interval is 30 seconds.

## Advanced Example

To customize the event processor, you can use the client factory methods.

```go
import (
  "time"
  
  "github.com/optimizely/go-sdk/pkg/client" // for v2: "github.com/optimizely/go-sdk/v2/pkg/client"
  "github.com/optimizely/go-sdk/pkg/event"  // for v2: "github.com/optimizely/go-sdk/v2/pkg/event"
  "github.com/optimizely/go-sdk/pkg/utils"  // for v2: "github.com/optimizely/go-sdk/v2/pkg/utils"
)

optimizelyFactory := &client.OptimizelyFactory{
		SDKKey: "SDK_KEY",	
}

// You can configure the batch size and flush interval
eventProcessor := event.NewBatchEventProcessor(
  event.WithBatchSize(10), 
  event.WithFlushInterval(30 * time.Second),
)
optlyClient, err := optimizelyFactory.Client(
  client.WithEventProcessor(eventProcessor),
)
```

:::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.
:::

## BatchEventProcessor

`BatchEventProcessor ` is an implementation of `EventProcessor` where events are batched. The class maintains a single consumer thread that pulls events off of an in-memory queue and buffers them for either a configured batch size or a maximum duration before the resulting `LogEvent` is sent to the `EventDispatcher` and `NotificationCenter`.

The following properties can be used to customize the `BatchEventProcessor` configuration.

| Property                  | Default value           | Description                                                                                                                                  |
| ------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **event.EventDispatcher** | NewQueueEventDispatcher | Used to dispatch event payload to Optimizely.                                                                                                |
| **event.BatchSize**       | 10                      | The maximum number of events to batch before dispatching. Once this number is reached, all queued events are flushed and sent to Optimizely. |
| **event.FlushInterval**   | 30000 (30 Seconds)      | Milliseconds to wait before batching and dispatching events.                                                                                 |
| **event.Q**               | NewInMemoryQueue        | BlockingCollection that queues individual events to be batched and dispatched by the executor.                                               |
| **event.MaxQueueSize**    | 1000                    | The maximum number of events that can be queued.                                                                                             |

For information, see [Initialize the Go SDK](docId\:lA6eDbcuVC3C-SQUsCcXV).

## Side Effects

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

| Functionality          | Description                                                                                                                                                                                                                                                                               |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| \`LogEvent\`           | Whenever the event processor produces a batch of events, a \`LogEvent\` object is created using the event factory. 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 LOGEVENT \[notification listener]\(https\://docs.developers.optimizely.com/feature-experimentation/docs/set-up-notification-listener-go) if this listener is subscribed to.                                                                                             |

### Register and Unregister a `LogEvent` listener

The following example code shows how to add and remove a `LogEvent` notification listener.

```go
import (
	"fmt"

  "github.com/optimizely/go-sdk/pkg/client" // for v2: "github.com/optimizely/go-sdk/v2/pkg/client"
  "github.com/optimizely/go-sdk/pkg/event"  // for v2: "github.com/optimizely/go-sdk/v2/pkg/event"
)

// Callback for log event notification
callback := func(notification event.LogEvent) {

  // URL to dispatch log event to
  fmt.Print(notification.EndPoint)
  // Batched event
  fmt.Print(notification.Event)
}

optimizelyFactory := &client.OptimizelyFactory{
  SDKKey: "SDK_KEY",
}
optimizelyClient, err := optimizelyFactory.Client()
if err != nil {
	// handle error
}

// Add callback for logEvent notification
id, err := optimizelyClient.EventProcessor.(*event.BatchEventProcessor).OnEventDispatch(callback)
if err != nil {
	// handle error
}
// Remove callback for logEvent notification
err = optimizelyClient.EventProcessor.(*event.BatchEventProcessor).RemoveOnEventDispatch(id)
```

### `LogEvent`

`LogEvent` object gets created using [`factory`](https://github.com/optimizely/go-sdk/blob/8a8fb7e959f2597d26d2a0dc3a6a072dcbc15f0f/pkg/event/factory.go#L46). It represents the batch of decision and conversion events Optimizely sends to the Optimizely backend.

| Object                                                                                                                                       | Type        | Description                                                                                                                   |
| -------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **EndPoint** \*Required (non null)\*                                                                                                         | String      | URL to dispatch log event to.                                                                                                 |
| \*\*\[Event]\(https\://github.com/optimizely/go-sdk/blob/8a8fb7e959f2597d26d2a0dc3a6a072dcbc15f0f/pkg/event/events.go#L70)\*\*\ \*Required\* | event.Batch | Contains all the information regarding every event which is batched. Including list of visitors which contains \`UserEvent\`. |

## Close Optimizely on application exit

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

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

| Method      | Description                                                                                                                                                  |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Close()** | Stops all executor threads and flushes the event queue. This method will also stop any `scheduledExecutorService` that is running for the data-file manager. |
