---
title: Initialize the Ruby SDK
slug: feature-experimentation/docs/initialize-sdk-ruby
docTags: 
createdAt: 2026-08-05T20:40:02.000Z
---

Use the `new` method to initialize the Ruby SDK and instantiate an instance of the Optimizely client class that exposes API methods like [Decide methods](docId\:W-MCwQUNp-EC5yaDomerg). Each client corresponds to the datafile representing the state of a project for a certain environment.

## Version

5.0.0

## Description

The SDK provides a default implementation, but you may want to override the optional parameters for your production environments. For example, you can configure an [error handler](docId\:a3H2eQ1ULHbpIH79KGxTJ) and [logger](docId\:J84rwNjns7IHbnoGuD9mq) to catch issues, an [event dispatcher](docId:-nFoSDdaX9ONAi8uG40OY) to manage network calls, and a [User Profile Service](https://docs.developers.optimizely.com/feature-experimentation/docs/v) to ensure sticky bucketing.

## Parameters

The following are the required and optional parameters for the `new` method:

| Parameter                                  | Type                      | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| ------------------------------------------ | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| \`datafile\` \_optional\_                  | string                    | The JSON string representing the project.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| \`event\_dispatcher\` \_optional\_         | EventDispatcher           | An event handler to manage network calls.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| \`logger\` \_optional\_                    | Logger                    | A logger implementation to log issues.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| \`error\_handler\` \_optional\_            | ErrorHandler              | An error handler object to handle errors.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| \`user\_profile\_service\` \_optional\_    | UserProfileService        | A user profile service.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| \`skip\_json\_validation\` \_optional\_    | boolean                   | Specifies whether the JSON should be validated. Set to \`true\` to skip JSON validation on the schema, or \`false\` to perform validation.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| \`datafile\_access\_token\` \_optional\_   | string                    | Use an access token (with an \`sdkKey\`) to fetch the datafile from an authenticated endpoint. Find your datafile access token in the Optimizely app at **Settings > Environments**. Select your secure environment, and copy the **Datafile access token**. See the \[Use authenticated datafile in a secure environment]\(#use-authenticated-datafile-in-a-secure-environment) section.                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| \`default\_decide\_options\` \_optional\_  | Array                     | Arrary of \`OptimizelyDecideOption\` enums. Constructing the Optimizely client with this parameter sets default decide options that apply to all Decide calls made during the lifetime of the Optimizely client. Passing options to individual Decide methods overrides these defaults. For details on decide options, see \[OptimizelyDecideOption]\(https\://docs.developers.optimizely.com/feature-experimentation/docs/decide-methods-ruby#optimizelydecideoption).                                                                                                                                                                                                                                                                                                                                                                                   |
| \`event\_processor\_options\` \_optional\_ | Hash                      | Hash of event processor options passed to the default event processor. See \[BatchEventProcessor]\(https\://docs.developers.optimizely.com/feature-experimentation/docs/event-batching-ruby) for more details.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| \`settings\`                               | \`OptimizelySdkSettings\` | Instance of \`OptimizelySdkSettings\` for configuring \[Real-Time Audiences for Feature Experimentation]\(https\://docs.developers.optimizely.com/feature-experimentation/docs/real-time-audiences-for-feature-experimentation). You must configure this parameter to use Real-Time Audiences for Feature Experimentation. The Ruby SDK enables the Real-Time Audiences for Feature Experimentation methods by default. But, the methods do nothing unless you have configured \[Real-Time Audiences for Feature Experimentation]\(https\://docs.developers.optimizely.com/feature-experimentation/docs/real-time-audiences-for-feature-experimentation). To optionally disable Real-Time Audiences for Feature Experimentation, see \[OdpManager]\(https\://docs.developers.optimizely.com/feature-experimentation/docs/initialize-sdk-ruby#odpmanager). |

## Returns

Instantiates an instance of the Optimizely client class.

## Examples

Optimizely Feature Experimentation provides default functionality to dynamically manage datafiles (configuration files) on either the client or the server. The Ruby SDK provides default implementations of an `ProjectConfigManager`. The package also includes a factory class, [OptimizelyFactory](docId\:GZzK3CQxBF2g4uWupfu70), which you can use to instantiate the Optimizely SDK with the default configuration of [HttpProjectConfigManager](docId\:GZzK3CQxBF2g4uWupfu70).

Whenever the experiment configuration changes, the SDK uses automatic datafile management (ADM) to handle the change for you. You can provide either `sdk_key`,`datafile`, or both.

- Initializing with the SDK key only polls for datafile changes in the background at regular intervals.
- Initializing with the datafile only does not poll for datafile changes in the background.
- Initializing with the SDK key and datafile uses the given datafile to poll for changes in the background.

### Instantiate with an SDK Key (recommended)

In the Ruby SDK, you only need to pass the SDK key value to instantiate a client. Whenever the experiment configuration changes, the SDK handles the change for you.

Include `sdk_key` as a string property in the options object you pass to the `default_instance` method.

When you provide the `sdk_key`, the SDK instance downloads the datafile associated with that `sdk_key`. When the download completes, the SDK instance updates itself to use the downloaded datafile.

### Basic example

The following code example shows basic Ruby ADM usage:

```ruby
require 'optimizely'
require 'optimizely/optimizely_factory'

# Initialize an Optimizely client
optimizely_instance = Optimizely::Project.new(sdk_key: 'put_your_sdk_key_here')
```

### Advanced examples

The following is a code example showing advanced configuration for Ruby ADM. See the following sections for advanced configuration properties.

This advanced example shows how to construct the individual components directly to override various configurations. This gives you full control over using implementations.

```ruby
require 'optimizely'
require 'optimizely/optimizely_factory'
require 'optimizely/config_manager/http_project_config_manager'

sdk_key = 'YOUR_SDK_KEY'
http_project_config_manager = Optimizely::HTTPProjectConfigManager.new(
  sdk_key: sdk_key,
  polling_interval: 10
)

optimizely_instance = Optimizely::OptimizelyFactory.default_instance_with_config_manager(http_project_config_manager)
```

```ruby
# Starting in 5.0+ the client constructor uses keyword arguments
sdk_key = 'YOUR_SDK_KEY'
optimizely_client = Optimizely::Project.new(sdk_key: sdk_key, logger: logger)

# Starting in 3.2+ there are convienence factory methods for instantiating clients
require 'optimizely/optimizely_factory'

# Instantiate with just the SDK key. The SDK will pull the datafile remotely.
optimizely_client = Optimizely::OptimizelyFactory.default_instance(sdk_key)

# You can optionally instantiate with a hard-coded datafile as well 
datafile = '{ revision: "42" }'
optimizely_client = Optimizely::OptimizelyFactory.default_instance(sdk_key, datafile)
```

### Required SDK key with other optional arguments

```ruby
require 'optimizely'

optimizely_instance = Optimizely::Project.new(
  sdk_key: 'YOUR_SDK_KEY',
  datafile: datafile,
  event_dispatcher: event_dispatcher,
  logger: logger,
  error_handler: error_handler,
  skip_json_validation: skip_json_validation,
  user_profile_service: user_profile_service,
  config_manager: config_manager,
  notification_center: notification_center,
  event_processor: event_processor,
  default_decide_options: default_decide_options,
  event_processor_options: event_processor_options,
  settings: settings
)

# Prior to 5.0
optimizely_instance = Optimizely::OptimizelyFactory.custom_instance(
  'YOUR_SDK_KEY',
  datafile,
  event_dispatcher,
  logger,
  error_handler,
  skip_json_validation,
  user_profile_service,
  config_manager,
  notification_center,
  settings
)
```

### Instantiate using datafile

You can also instantiate with a hard-coded datafile. If you do not pass in an SDK key, the Optimizely Client does not automatically sync newer versions of the datafile. Any time you retrieve an updated datafile, just re-instantiate the same client.

To instantiate a client for simple applications, provide a datafile specifying the project configuration for a given environment. For most advanced implementations, you should [customize the logger](docId\:J84rwNjns7IHbnoGuD9mq) or [error handler](docId\:a3H2eQ1ULHbpIH79KGxTJ) for your specific requirements.

```ruby
# Instantiate with both SDK key and datafile. The SDK will use the hard-coded datafile and will start polling for new datafiles remotely.
datafile = '{ revision: "42" }'
optimizely_client = Optimizely::Project.new(
  sdk_key: sdk_key, 
  datafile: datafile
  error_handler: error_handler,
  logger: logger
)

# Prior to 5.0 you can use the OptimizelyFactory for a similar experience
optimizely_client = Optimizely::OptimizelyFactory.default_instance(sdk_key, datafile)

# You can also customize the various components of the SDK (that is, logger, error handler)
optimizely_client = Optimizely::OptimizelyFactory.custom_instance(
  sdk_key, 
  datafile
  # event_dispatcher
  # logger
)

# Prior to 3.2 you can instantiate with just a JSON datafile string
optimizely_client = Optimizely::Project.new(datafile)
```

## Initialize in a Rails application

To use the SDK in a Rails application, you can configure the SDK using The following snippet:

```ruby
# initialize a client
Rails.configuration.optimizely_client = Optimizely::OptimizelyFactory.default_instance('YOUR_SDK_KEY')

# you can access the client in your Rails controllers from the application config
Rails.application.config.optimizely_client
```

The SDK spawns multiple threads when initialized. These threads have infinite loops for fetching the datafile, and batching and dispatching events in the background. When using in a web server that spawn multiple child processes, you need to initialize the SDK after those child processes or workers have been spawned:

### Unicorn

```ruby
after_fork do |server, worker|
   Rails.configuration.optimizely_client = Optimizely::OptimizelyFactory.default_instance('YOUR_SDK_KEY')
end
```

### Puma

```ruby
on_worker_boot do
   Rails.configuration.optimizely_client = Optimizely::OptimizelyFactory.default_instance('YOUR_SDK_KEY')
end
```

### Passenger

```ruby
PhusionPassenger.on_event(:starting_worker_process) do |forked|
 if forked
   Rails.configuration.optimizely_client = Optimizely::OptimizelyFactory.default_instance('YOUR_SDK_KEY')
 end
end
```

## `HttpProjectConfigManager`

[HttpProjectConfigManager](https://github.com/optimizely/ruby-sdk/blob/master/lib/optimizely/config_manager/http_project_config_manager.rb) is an implementation of `ProjectConfigManager` interface which polls for the datafile and updates `DatafileProjectConfig` based on an update interval. To maintain the asynchronous nature of requests, it uses an `AsyncScheduler` which makes an HTTP `GET` request to the configured URL to asynchronously download the project datafile and initialize an instance of the `DatafileProjectConfig`.

By default, `HttpProjectConfigManager` blocks until the first successful datafile retrieval, up to a configurable blocking timeout. Set the frequency of the polling method and the blocking timeout when initializing the config manager.

```ruby
http_project_config_manager = Optimizely::HTTPProjectConfigManager.new(
  datafile: datafile
  sdk_key: YOUR_SDK_KEY,
  polling_interval: 10,
  blocking_timeout: 15
)
```

### SDK key

The SDK key composes the outbound HTTP request to the default datafile location on the Optimizely CDN.

### Poll interval

The polling interval specifies a fixed delay between consecutive HTTP requests for the datafile.

### Initial datafile

You can provide an initial datafile while initializing the Config Manager to bootstrap the `ProjectConfigManager` so that it can be used immediately without blocking execution. The initial datafile is also a fallback datafile if HTTP connection cannot be established. This is useful in mobile environments, where internet connectivity is not guaranteed.

The SDK discards the initial datafile after the first successful datafile poll.

### Advanced configurations

You can use the following properties to customize the `HttpProjectConfigManager` configuration.

| Property           | Default value | Description                                                                                                                                                                                      |
| ------------------ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `datafile`         | null          | Initial datafile, typically sourced from a local cached source.                                                                                                                                  |
| `url`              | null          | URL override location used to specify custom HTTP source for the datafile.                                                                                                                       |
| `url_template`     | null          | Parameterized datafile URL by SDK key.                                                                                                                                                           |
| `polling_interval` | 5 minutes     | Fixed delay between fetches for the datafile. Valid duration is between 1 and 2592000 seconds. Otherwise, the default is used.                                                                   |
| `blocking_timeout` | 15 seconds    | The blocking timeout period is used to specify a maximum time to wait for initial bootstrapping. Valid blocking timeout period is between 1 and 2592000 seconds. Otherwise, the default is used. |
| `sdk_key`          | null          | Your Optimizely project SDK key. Required unless source URL is overridden.                                                                                                                       |
| `auto_update`      | true          | Boolean flag to specify if callback for datafile polling needs to execute infinitely or only once.                                                                                               |
| `start_by_default` | true          | Boolean flag to specify if datafile polling should start right away, when the `HTTPConfigManager` is initialized.                                                                                |

### Update config notifications

The SDK triggers a notification signal when fetching a new datafile or updating a corresponding project. To subscribe to these notifications, use the  `notification_center.add_notification_listener()` method.

```ruby
notification_center.add_notification_listener(Optimizely::NotificationCenter::NOTIFICATION_TYPES[:OPTIMIZELY_CONFIG_UPDATE], @callback
)
```

## `OptimizelyFactory`

[OptimizelyFactory](https://github.com/optimizely/ruby-sdk/blob/master/lib/optimizely/optimizely_factory.rb) provides basic utility to instantiate the Optimizely Ruby SDK with a minimal number of configuration options.

`OptimizelyFactory` does not capture all configuration and initialization options. For more use cases, build the resources with their constructors.

You must provide the SDK key at runtime, directly using the factory method:

```ruby
optimizely_instance = Optimizely::OptimizelyFactory.default_instance(
  'YOUR_SDK_KEY'
)
```

## Enable JSON schema validation

Skipping JSON schema validation enhances performance during instantiation. In the Ruby SDK, you can control whether to validate the JSON schema of the datafile when instantiating the client. This example shows how to skip JSON schema validation:

```ruby
# Skip JSON schema validation (SDK versions 0.1.1 and above)
optimizely_client = Optimizely::Project.new(datafile: datafile, skip_json_validation: true)
```

## Dispose of the client

For effective resource management with the Optimizely Ruby SDK, you must properly close the Optimizely client instance when it is no longer needed. This is done by calling `optimizely.close()`.

The `.close()` method ensures that the processes and queues associated with the instance are properly released. This is essential for preventing memory leaks and ensuring that the application runs efficiently, especially in environments where resources are limited or in applications that create and dispose of many instances over their lifecycle.

See [Close Optimizely Ruby SDK on application exit](docId\:c5e7PD_QEJzGOZInIgCEr).

## Use authenticated datafiles in secure environments

You can fetch the Optimizely datafile from an authenticated endpoint using a server-side (only) SDK, like the Ruby SDK.

To use an [authenticated datafile](docId\:YpSOMYlWkUccLCL-uB-ZE), download your environment's access token from the app at **Settings > Environment**. Select your secure environment, and copy the **Datafile access token** The following example shows how to initialize the Optimizely client using an access token and `sdk_key`, enabling the client to fetch the authenticated datafile and complete initialization.

```ruby
# fetch the datafile from an authenticated endpoint
require 'optimizely'

sdk_key = '<YOUR_SDK_KEY>'
datafile_access_token = '<YOUR_DATAFILE_ACCESS_TOKEN>'

config_manager = Optimizely::HTTPProjectConfigManager.new(
  sdk_key: sdk_key,
  datafile_access_token: datafile_access_token
)

Optimizely::Project.new(config_manager:, config_manager)
```

## `OdpManager`

The `OdpManager` contains the logic supporting the Real-Time Audiences for Feature Experimentation-related features, including audience segments. You must configure this parameter to use Real-Time Audiences for Feature Experimentation.

The Ruby SDK enables the Real-Time Audiences for Feature Experimentation methods by default. But, the methods do nothing unless you have enabled and configured [Real-Time Audiences for Feature Experimentation](docId:6UBBxxRv331nBIVZ2lun8).

:::hint{type="info"}
If necessary, to disable Real-Time Audiences for Feature Experimentation altogether, set `disable_odp: true`. See the following sample code for information.
:::

The following settings are optionally configurable when the Ruby SDK is initialized:

- **ODP SegmentsCache size** – `segments_cache_size`
  - **Default** – 10,000
  - Set to 0 to disable caching.
- **ODP SegmentsCache timeout** (in seconds) – `segments_cache_timeout_in_secs`
  - **Default** – 600 secs (10 minutes)
  - Set to 0 to disable timeout (never expires).
- **ODP enable** – `disable_odp`
  - **Default** – false (enabled)
  - The Ruby SDK returns or logs an `odpNotEnabled` error when ODP is disabled and its features are requested.

See [Customize ODPSegmentManager](docId\:GZzK3CQxBF2g4uWupfu70).

`OdpSegmentManager`

This module provides an interface to the remote ODP server for audience segment mappings.

It fetches all qualified audience segments for the given user context and returns them as a string array in the completion handler.

It also manages a segments cache shared for all user contexts. Because the cache is in memory (not persistent), rebooting the device or terminating the app resets it.

`OdpEventManager`

This module provides an interface to the remote ODP server for events.

It queues all pending events (persistent) and sends them (in batches of up to 10) to the ODP server when all resources are available, including network connection and ODP public key (in the SDK's datafile).

:::hint{type="info"}
The Ruby SDK tries to dispatch all events (stored in a persistent queue and retried on recoverable errors) but does not guarantee completion.
:::

```ruby
require 'optimizely'
require 'optimizely/optimizely_factory'

event_manager = Optimizely::OdpEventManager.new()

segments_cache = YourCustomCache.new()
segments_manager = Optimizely::OdpSegmentManager.new(segments_cache)

sdk_settings = Optimizely::Helpers::OptimizelySdkSettings.new(
  disable_odp: false, #set to true to disable Real-Time Segments for Feature Experimentation
  segments_cache_size: 10_000,
  segments_cache_timeout_in_secs: 600,
  odp_segments_cache: segments_cache,
  odp_segment_manager: segments_manager,
  odp_event_manager: event_manager,
  odp_segment_request_timeout: 10,
  odp_event_request_timeout: 10,
  odp_event_flush_interval: 1
)
optimizely = Optimizely::Project.new(
  sdk_key: 'YOUR_SDK_KEY',
  settings: sdk_settings
)
```

### Customize `OdpEventApiManager`

`OdpEventApiManager` is an interface, and its implementation requires the user to provide the functionality of the following methods:

```ruby
require 'optimizely'
require 'optimizely/optimizely_factory'

event_api_manager = Optimizely::OdpEventApiManager.new(timeout: 10)
odp_event_manager = Optimizely::OdpEventManager.new(api_manager: event_api_manager, flush_interval: 1)
sdk_settings = Optimizely::Helpers::OptimizelySdkSettings.new(odp_event_manager: odp_event_manager)

optimizely = Optimizely::Project.new(
  sdk_key: 'YOUR_SDK_KEY',
  settings: sdk_settings
)
```

### Customize `OdpEventManager`

You can provide custom `queue_size` and `flush_interval` in the constructor. If set to zero, `batch_size`  is 1. Otherwise, `batch_size` is the default of 10.

```ruby
require 'optimizely'
require 'optimizely/optimizely_factory'

event_api_manager = Optimizely::OdpEventApiManager.new(timeout: 10)
odp_event_manager = Optimizely::OdpEventManager.new(api_manager: event_api_manager, flush_interval: 1)
sdk_settings = Optimizely::Helpers::OptimizelySdkSettings.new(odp_event_manager: odp_event_manager)

optimizely = Optimizely::Project.new(
  sdk_key: 'YOUR_SDK_KEY',
  settings: sdk_settings
)
```

### Customize `OdpSegmentManager`

By default, `OdpSegmentManager` uses the `LRUCache`.

```ruby
require 'optimizely'
require 'optimizely/optimizely_factory'

cache = Optimizely::LRUCache.new(10_000, 600)

odp_segment_manager = Optimizely::OdpSegmentManager.new(cache, 10)
sdk_settings = Optimizely::Helpers::OptimizelySdkSettings.new(odp_segment_manager: odp_segment_manager)

optimizely = Optimizely::Project.new(
  sdk_key: 'YOUR_SDK_KEY',
  settings: sdk_settings
)
```

### Custom cache

You can provide a custom cache to store the [\`fetch\_qualified\_segments\`](docId:0XHlYTIKhKO-FHN6fCDL7) results by implementing the following interface:

```ruby
class OptimizelySegmentsCache
  def save(key, value); end
  def lookup(key); end
  def reset; end
end
```

The following is an example of custom cache implementation:

```ruby
class CustomCache
  def initialize
    @mutex = Mutex.new
    @map = {}
  end

  def save(key, value)
    @mutex.synchronize { @map[key] = value }
    nil
  end

  def lookup(key)
    @mutex.synchronize { @map[key] }
  end

  def reset
    @mutex.synchronize { @map.clear }
    nil
  end
end
```

Pass this `CustomCache` within `OptimizelySdkSettings` when instantiating the Optimizely client:

```ruby
require 'optimizely/optimizely_factory'

segments_cache = CustomCache.new
sdk_settings = Optimizely::Helpers::OptimizelySdkSettings.new(odp_segments_cache: segments_cache)
Optimizely::Project.new(
  sdk_key: 'YOUR_SDK_KEY',
  settings: sdk_settings
)
```

```ruby
# fetch the datafile from an authenticated endpoint
require 'optimizely'

sdk_key = 'YOUR_SDK_KEY'
datafile_access_token = 'YOUR_DATAFILE_ACCESS_TOKEN'

config_manager = Optimizely::HTTPProjectConfigManager.new(
  sdk_key: sdk_key,
  datafile_access_token: datafile_access_token
)

Optimizely::Project.new(config_manager:, config_manager)
```

## CMAB configuration

Configure caching behavior for Contextual Multi-Armed Bandit (CMAB) decisions at initialization time.

Use `OptimizelyFactory` class methods to configure CMAB caching *before* initializing your client.

### Parameters

| Parameter    | Method              | Type    | Default                   | Description                                                                                |
| ------------ | ------------------- | ------- | ------------------------- | ------------------------------------------------------------------------------------------ |
| Cache Size   | `cmab_cache_size`   | Integer | 10000                     | Maximum number of cached decisions                                                         |
| Cache TTL    | `cmab_cache_ttl`    | Numeric | 1800 seconds (30 minutes) | Time-to-live for cache entries                                                             |
| Custom Cache | `cmab_custom_cache` | Cache   | nil                       | Optional custom cache implementation. If not provided, uses built-in thread-safe LRU cache |

For configuration examples, cache behavior details, and runtime control options, see [Configure CMAB caching](docId\:HSqSPkFDNZmKJGGtExsoK).

## Source files

The language and platform source files containing the implementation for Ruby are available on [GitHub](https://github.com/optimizely/ruby-sdk/blob/master/lib/optimizely.rb).
