Skip to content

Configuration

Ahmed Abbas edited this page Jun 8, 2026 · 2 revisions

Configuration Options

Every option is passed as a keyword argument to ConvertSdk.create and merged over the SDK's defaults. The defaults are JS-parity constants (verified against the JavaScript and PHP reference SDKs) — they are not tuning knobs and should not be changed without reason.

An unknown option key raises ArgumentError at construction — a typo fails fast rather than being silently ignored. (store:, clock:, and sink: are wiring seams handled separately by create, not config options — see Initialization.)

CONVERT_SDK = ConvertSdk.create(
  sdk_key:        ENV.fetch("CONVERT_SDK_KEY"),
  sdk_key_secret: ENV["CONVERT_SDK_KEY_SECRET"],
  environment:    "staging",
  log_level:      ConvertSdk::LogLevel::INFO
)

All options

Option Default Purpose
sdk_key nil Account/project SDK key (fetch mode). At least one of sdk_key / data is required.
sdk_key_secret nil Bearer secret for the config fetch. Redacted from all logs.
data nil Pre-fetched config object (direct-data mode); skips the network fetch.
environment nil Platform environment selector (e.g. "staging"). Appended as a query param to the config fetch when set.
config_endpoint "https://cdn-4.convertexperiments.com/api/v1" Config-fetch base URL.
track_endpoint "https://[project_id].metrics.convertexperiments.com/v1" Event-tracking base URL.
data_refresh_interval 300 Config-refresh cadence in seconds. nil = timer-off (Lambda/CLI).
flush_interval 1 Event-flush cadence in seconds. nil = timer-off (Lambda/CLI).
event_batch_size 10 Events per delivery batch.
max_traffic 10000 Bucketing max traffic (JS-parity constant — do not tune).
hash_seed 9999 Bucketing hash seed (JS-parity constant — do not tune).
keys_case_sensitive true Rule-key case sensitivity.
negation "!" Rule negation token.
log_level ConvertSdk::LogLevel::DEBUG Logging threshold (TRACE=0 … SILENT=5).
tracking true Master switch for outbound event tracking.
open_timeout 5 HTTP connect timeout in seconds.
read_timeout 10 HTTP read timeout in seconds.

The fixed bucketing hash space (2³² = 4_294_967_296) is a JS-parity constant exposed to the bucketing engine; it is not a configurable option.

Notes on key options

  • log_level accepts the integer ConvertSdk::LogLevel thresholds: TRACE(0) · DEBUG(1) · INFO(2) · WARN(3) · ERROR(4) · SILENT(5). A message emits when its level is >= the configured threshold; SILENT suppresses everything. The default is DEBUG. See Return Types & Sentinels.

  • data_refresh_interval and flush_interval accept nil (timer-off mode). When either is nil, the corresponding background thread is never started. This is the AWS Lambda and plain-CLI recipe: zero background threads, config freshness checked on-demand at decision time, delivery only on an explicit flush. See Fork Safety & Runtime Recipes.

  • tracking: false is the global consent switch. It suppresses outbound event enqueue — decisioning and sticky store writes still happen, only delivery is silenced. See Tracking Control.

  • max_traffic, hash_seed, keys_case_sensitive, negation are bucketing/rule-engine parity constants. Leave them at their defaults unless you are deliberately matching legacy account behavior — see Bucketing Algorithm and Rule Evaluation.

Data stores (RedisStore wiring)

Sticky bucketing (variation assignment) and goal deduplication persist through a store port. The default is an in-process MemoryStore, which keeps state in a single process — fine for a single long-running server, but inconsistent across a Puma cluster, a Sidekiq worker fleet, or Lambda invocations.

For those multi-process fleets, pass a ConvertSdk::Stores::RedisStore via the store: seam so every process shares one view:

require "convert_sdk"

store = ConvertSdk::Stores::RedisStore.new(url: ENV.fetch("REDIS_URL"))
CONVERT_SDK = ConvertSdk.create(sdk_key: ENV.fetch("CONVERT_SDK_KEY"), store: store)

RedisStore accepts:

  • redis: — an existing redis-rb-compatible client (#get/#set). Preferred — enables connection reuse/pooling, and no require "redis" happens.
  • connection options (e.g. url:) — forwarded to Redis.new; triggers a lazy require "redis". If the redis gem is not installed, instantiation raises an actionable LoadError naming the gem to add (a wiring-time programmer error, in the same class as create's argument validation).
  • key_prefix: — namespaces every key (default "convert:") so the SDK's keys do not collide with other tenants of the same Redis database.

The redis gem is your dependency — it is never a runtime dependency of convert_sdk. Any object that duck-types get/set is accepted as a custom store. See Persistent DataStore.

Cross-process merge caveat: visitor-data merges are a read-modify-write. In-process that sequence is atomic under the store manager's mutex; across processes sharing one Redis there is no such lock — concurrent writers race and the last write wins (this matches the JS SDK contract; the SDK does not use Lua scripts or WATCH/MULTI).

Next steps

Clone this wiki locally