Skip to main content
The C++ SDK sends events and structured logs from your services to Tell. It’s a server SDK — you create a client, pass a user ID on every call, and a background worker thread handles batching and delivery over TCP. Your thread does about 85 ns of work per call and never touches the network. The SDK has zero external dependencies beyond C++17 and pthreads.

Installation

Add the SDK as a CMake subdirectory:
Or build from source:
Requires a C++17 compiler (GCC 7+, Clang 5+, MSVC 2017+) and CMake 3.14+.

Quick start

The client connects to collect.tell.rs:50000, batches up to 100 events, and flushes every 10 seconds or when you call close().

Configuration

Use one of the two presets, or build a custom config.
For custom settings, use the builder:
The API key must be a 32-character hex string. The SDK validates it at build time and throws TellError if it’s invalid.

Tracking events

Every tracking method takes user_id as its first parameter. Calls never block or throw — errors go to the optional on_error callback.
Properties are always optional — you can omit them entirely:

Standard event names

The SDK provides typed constants for common events:
Constants cover user lifecycle, revenue, subscriptions, trials, shopping, engagement, and communication events. Custom string names are always accepted too.

Super properties

Register properties that get merged into every track, group, and revenue call:
Event-specific properties override super properties when keys conflict.

Structured logging

Send logs alongside events through the same pipeline. Each log has an RFC 5424 severity level.
The service parameter defaults to "app" if omitted. Convenience methods are available for all nine levels: log_emergency, log_alert, log_critical, log_error, log_warning, log_notice, log_info, log_debug, and log_trace. You can also use the generic log method with an explicit level:

Properties

The Props class builds key-value pairs with a chainable API. It writes JSON bytes directly to a buffer — no intermediate allocations.
Supported types: std::string, const char*, int, int64_t, double, and bool.

Lifecycle

Always call close() before your process exits to avoid losing buffered events. It blocks up to close_timeout (default 5 seconds).

Thread safety

The SDK is fully thread-safe. Internal state is protected by std::shared_mutex:

Error handling

Construction throws on invalid config:
Tracking and logging calls (track, identify, log_*, etc.) never throw. Invalid input (empty user ID, event name too long) is reported through the on_error callback:

Advanced

Configuration reference

Validation rules

Performance

Caller latency — serialize, encode, and enqueue (Apple M4 Pro):

Retry behavior

On TCP send failure, the SDK retries with exponential backoff up to max_retries attempts. After exhausting retries, the batch is dropped and the error reported via on_error.