Dev guideAPI Reference
Dev guideAPI ReferenceUser GuideGitHubNuGetDev CommunitySubmit a ticketLog In
GitHubNuGetDev CommunitySubmit a ticket

Event batching for the Android SDK

The Optimizely Feature Experimentation Android SDK uses the event processor to batch decision and conversion events into a single payload before sending it to Optimizely.

The Android SDK lets you batch events and includes options to set an event batch size, event time interval and event flush interval. The benefit of event batching is less network traffic for the same number of impression and conversion events tracked.

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

  • Batch size – Defines the number of batched events before sending to Optimizely Feature Experimentation.
  • Flush interval – Defines the amount of time after which any batched events should be sent to passed to the Event Dispatcher to be sent to Optimizely Feature Experimentation.

An event consisting of the batched payload is sent as soon as the batch size reaches the specified limit or the flush interval reaches the specified time limit. BatchEventProcessor options are described in the following sections.

📘

Note

The default Event Dispatcher in the Optimizely Feature Experimentation Android SDK uses an Android Intent Service to dispatch batched requests. As a result you may observe additional delays to outbound requests beyond your specified flush interval as a result of system limits on those requests.

Optimizely Feature Experimentation's 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. You must still ensure that you are not sending any unnecessary PII to Optimizely.

Basic example

val optimizelyManager = OptimizelyManager.builder()
         .withSDKKey("<Your_SDK_Key>")
         .build(context)
val optimizely = optimizelyManager.initialize(context, R.raw.datafile)
OptimizelyManager optimizelyManager = OptimizelyManager.builder()
        .withSDKKey("<Your_SDK_Key>")
        .build(context);
OptimizelyClient optimizely = optimizelyManager.initialize(context, R.raw.datafile);

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

Advanced Example

val eventHandler: EventHandler = DefaultEventHandler.getInstance(context)

// Here we are using the builder options to set batch size
// to 5 events and flush interval to a minute.
val batchProcessor = BatchEventProcessor.builder()
         .withBatchSize(5)
         .withEventHandler(eventHandler)
         .withFlushInterval(TimeUnit.MINUTES.toMillis(1L))
         .build()
val optimizelyManager = OptimizelyManager.builder()
         .withSDKKey("<Your_SDK_Key>")
         .withEventHandler(eventHandler)
         .withDatafileDownloadInterval(15, TimeUnit.MINUTES)
         .withEventProcessor(batchProcessor)
         .build(context)
val optimizely = optimizelyManager.initialize(context, R.raw.datafile)
EventHandler eventHandler = DefaultEventHandler.getInstance(context);

// Here we are using the builder options to set batch size
// to 5 events and flush interval to a minute.
BatchEventProcessor batchProcessor = BatchEventProcessor.builder()
         .withBatchSize(5)
         .withEventHandler(eventHandler)
         .withFlushInterval(TimeUnit.MINUTES.toMillis(1L))
         .build();

OptimizelyManager optimizelyManager = OptimizelyManager.builder()
         .withSDKKey("<Your_SDK_Key>")
         .withEventHandler(eventHandler)
         .withDatafileDownloadInterval(15, TimeUnit.MINUTES)
         .withEventProcessor(batchProcessor)
         .build(context);

OptimizelyClient optimizely = optimizelyManager.initialize(context, R.raw.datafile);

❗️

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, 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 the BlockingCollection 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 using the Builder class.

Builder methods

Use the following methods to customize the BatchEventProcessor.

PropertyDefault valueDescription
withEventHandlernullRequired field. Specifies event handler to use to dispatch event payload to Optimizely Feature Experimentation.

By default, if you create an Optimizely instance, it passes in AsyncEventHandler to BatchEventProcessor.
withBatchSize10The maximum number of events to batch before dispatching. Once this number is reached, all queued events are flushed and sent to Optimizely Feature Experimentation.
withFlushInterval30000 (30 Seconds)Maximum time after which to batch and send event payload to Optimizely Feature Experimentation. In milliseconds.
withEventQueue1000BlockingCollection that queues individual events to be batched and dispatched by the executor.
withNotificationCenternullNotification center instance to be used to trigger any notifications to notify when event batches are flushed.
withExecutorSingle Thread ExecutorExecutor service that takes care of triggering event batching and subsequent dispatching to Optimizely Feature Experimentation.
withTimeout5000Maximum time to wait for event processor’s close to be executed. In milliseconds.

Advanced configuration

You can set the following properties can be set to override the default configuration for BatchEventProcessor.

PropertyDefault valueDescription
event.processor.batch.size10Maximum size of batch of events to send to Optimizely Feature Experimentation.
event.processor.batch.interval30000Maximum time after which to batch and send event payload to Optimizely Feature Experimentation. In milliseconds.
event.processor.close.timeout5000Maximum time to wait for event processor’s close to be executed. In milliseconds.

For more information, see Initialize the Android SDK.

Side effects

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

FunctionalityDescription
LogEventWhenever the event processor produces a batch of events, a LogEvent object will be created using the EventFactory.

It contains batch of conversion and decision events.

This object will be dispatched using the provided event dispatcher and also it will be sent to the notification subscribers
Notification ListenersFlush invokes the LOGEVENT notification listener if this listener is subscribed to.

Register LogEvent listener

To register a LogEvent notification listener:

optimizely.notificationCenter?.addNotificationHandler(LogEvent::class.java) { logEvent: LogEvent ->
    Log.d("Optimizely", "event dispatched: $logEvent")
}
optimizely.getNotificationCenter().addNotificationHandler(LogEvent.class, logEvent -> {
    Log.d("Optimizely", "event dispatched: " + logEvent);
});

LogEvent

LogEvent object gets created using EventFactory. It represents the batch of decision and conversion events we send to the Optimizely Feature Experimentation backend.

ObjectTypeDescription
requestMethod
Required (non null)
RequestMethod (Enum)The HTTP verb to use when dispatching the log event. It can be Get or POST.
endpointUrl
Required (non null)
StringURL to dispatch log event to.
requestParams
Required (non null)
Map<String, String>Parameters to be set in the log event.
eventBatch
Required
EventBatchIt contains all the information regarding every event which is batched. including list of visitors which contains UserEvent.

Close Optimizely Feature Experimentation 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 as soon as possible to avoid data loss.

Warning

Because the Optimizely client maintains a buffer of queued events, you must call close() on the Optimizely Feature Experimentation instance before shutting down your application or whenever dereferencing the instance.

MethodDescription
close()Stops all executor threads and flushes the event queue. This method will also stop any scheduledExecutorService running for the data-file manager.