-
Notifications
You must be signed in to change notification settings - Fork 0
Configuration
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
)| 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.
-
log_levelaccepts the integerConvertSdk::LogLevelthresholds:TRACE(0) ·DEBUG(1) ·INFO(2) ·WARN(3) ·ERROR(4) ·SILENT(5). A message emits when its level is>=the configured threshold;SILENTsuppresses everything. The default isDEBUG. See Return Types & Sentinels. -
data_refresh_intervalandflush_intervalacceptnil(timer-off mode). When either isnil, 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 explicitflush. See Fork Safety & Runtime Recipes. -
tracking: falseis 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,negationare bucketing/rule-engine parity constants. Leave them at their defaults unless you are deliberately matching legacy account behavior — see Bucketing Algorithm and Rule Evaluation.
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 norequire "redis"happens. -
connection options (e.g.
url:) — forwarded toRedis.new; triggers a lazyrequire "redis". If theredisgem is not installed, instantiation raises an actionableLoadErrornaming the gem to add (a wiring-time programmer error, in the same class ascreate'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).
The SDK uses hand-written plain-hash readers (experiences, features, goal_by_key, …) that access the config response's string-keyed frozen snapshot directly. There is no OpenAPI code generation at runtime — all readers are hand-written and RBS-typed.
Build-time drift detection is provided by a generated compile-time-only RBS file (sig/convert_sdk/config/generated/types.rbs). When the backend serving spec changes, the backend workflow regenerates this file and opens a PR into ruby-sdk. The steep check CI job then type-checks the contract probe (steep/config_contract_probe.rb), which asserts every field the SDK depends on. If a field is removed from the generated RBS, steep check fails on the exact probe line — blocking the backend PR before merge.
This gate is CRuby-only (the rbs C-extension cannot build on JRuby) and fires only when the spec changes. For reality-drift-without-spec-change and JRuby runtime verification, the staging.yml suite (daily + dispatch) is the backstop. See Testing for details on both gates.
-
Initialization —
ConvertSdk.create, thesink:/store:/clock:seams -
Return Types & Sentinels —
LogLeveland the other enums -
Tracking Control — the
trackingswitch in depth - Testing — drift-control gates, direct-data mode, capturing sinks
Copyrights © 2026 All Rights Reserved by Convert Insights, Inc.
Getting Started
Ruby SDK
- Quickstart
- Installation
- Initialization
- Configuration
- Return Types & Sentinels
- Code Examples
- Fork Safety & Runtime Recipes
- Tracking Control
Core Concepts
- Experiences & Variations
- Feature Flags
- Bucketing Algorithm
- Rule Evaluation
- Segments
- Data Management
- Event System
- API Communication
How-To Guides
- Running Experiences
- Running Features
- Tracking Conversions
- Visitor Context
- Persistent DataStore
- Troubleshooting
Contributing