Docs / Contact / sdks/go/configuration

Go SDK: Configuration

The API key comes from the constructor argument first, then the TENDRL_KEY environment variable. Everything else comes from a JSON config file.

The config file is not optional in practice

LoadConfigFile searches ~/.tendrl/config.json, then /etc/tendrl/config.json, and returns an empty config when it finds neither. An empty config means managed is false, and a false managed zeroes the whole managed feature set — so with no config file, offline storage, offline retry, connectivity monitoring and automatic heartbeats are all off, even when you pass true to NewClient. Write the file below to turn them on.

Configuration File#

Create ~/.tendrl/config.json or /etc/tendrl/config.json:

json

{
    "managed": true,
    "timeout_seconds": 10,
    "max_retries": 3,
    "debug": false,
    "min_batch_size": 10,
    "max_batch_size": 500,
    "max_queue_size": 1000,
    "target_cpu_percent": 70.0,
    "target_mem_percent": 80.0,
    "min_batch_interval_ms": 100,
    "max_batch_interval_ms": 1000,
    "offline_storage": true,
    "storage_path": "tendrl_storage.db",
    "offline_retry_enabled": true,
    "offline_retry_interval_seconds": 30,
    "offline_retry_limit": 5,
    "connectivity_check_enabled": true,
    "connectivity_check_interval_seconds": 30,
    "send_heartbeat": true,
    "heartbeat_interval_seconds": 30
}

"managed": true must be present in the file itself. Without that key the other booleans are ignored, whatever they say.

You can also generate that file from code. GenerateExampleConfig takes no arguments and returns a *ConfigFile with every option at its default; pair it with SaveConfigFile:

go

cfg := tendrl.GenerateExampleConfig()
if err := tendrl.SaveConfigFile(cfg, tendrl.GetDefaultConfigPath()); err != nil {
    log.Fatal(err)
}

All Configuration Options#

Core#

JSON Key Type Default Description
managed bool false unless set here Managed mode (background processing) or headless (direct calls). NewClient(true, …) forces managed mode on afterwards, but NewClientWithConfig does not — there, an absent "managed": true gives you a headless client.
timeout_seconds int 10 HTTP request timeout in seconds
max_retries int 3 Maximum retry attempts for failed requests
debug bool false Enable detailed debug logging

Batching & Performance#

JSON Key Type Default Description
min_batch_size int 10 Minimum messages per batch
max_batch_size int 500 Maximum messages per batch
max_queue_size int 1000 Maximum queued messages
min_batch_interval_ms int 100 Minimum ms between batch sends
max_batch_interval_ms int 1000 Maximum ms before forced send
target_cpu_percent float 70.0 Target CPU % for dynamic batch sizing
target_mem_percent float 80.0 Target memory % for dynamic batch sizing

The SDK calculates batch size dynamically: batchSize = MaxBatchSize × (cpuFactor×0.4 + memFactor×0.4 + queueFactor×0.2), clamped between min and max.

Offline Storage#

JSON Key Type Default Description
offline_storage bool false unless set here Enable BoltDB message persistence
storage_path string "tendrl_storage.db" Path to BoltDB file
offline_retry_enabled bool false unless set here Automatically retry stored messages
offline_retry_interval_seconds int 30 Seconds between retry checks
offline_retry_limit int 5 Maximum retry attempts per message

Messages are stored with a 1-hour TTL. Expired messages are automatically cleaned up.

Both keys need "managed": true alongside them to take effect. With no config file at all they are false, and a message that cannot be sent is dropped rather than stored.

Connectivity#

JSON Key Type Default Description
connectivity_check_enabled bool false unless set here Enable network monitoring
connectivity_check_interval_seconds int 30 Seconds between connectivity checks

Heartbeat#

JSON Key Type Default Description
send_heartbeat bool true when the file sets "managed": true, otherwise false Send periodic heartbeats
heartbeat_interval_seconds int 30 Seconds between heartbeats

Heartbeats report memory (free/total) and disk (free/total) metrics. This is the one managed feature that is on by default once the file sets "managed": true — set "send_heartbeat": false to turn it off. With no config file it is off like the rest.

client.PublishHeartbeat sends one on demand regardless of this setting.

Environment Variables#

Variable Purpose
TENDRL_KEY API key (used when no key is passed to the constructor)
TENDRL_APP_URL API base URL. Defaults to https://app.tendrl.com/api. Accepts a bare origin (http://localhost:8000) or a base URL already ending in /api. See Testing against a local or staging stack.

There is no config-file key for the server URL; TENDRL_APP_URL is the only way to change it.

Constructor Variants#

go

// Managed mode with explicit API key
client, err := tendrl.NewClient(true, "your_key")

// Managed mode with TENDRL_KEY env var
client, err = tendrl.NewClientWithMode(true)

// Custom config file path
client, err = tendrl.NewClientWithConfig("/etc/myapp/tendrl.json")

// Config file + explicit API key
client, err = tendrl.NewClientWithConfigAndAPIKey("/etc/myapp/tendrl.json", "your_key")

The first two take the mode from their managed argument. The two WithConfig variants take it from the file and error if the file is missing, so that file must contain "managed": true or you get a headless client with no background processing at all.

Example Configurations#

Edge Gateway (High Throughput)#

json

{
    "managed": true,
    "max_batch_size": 1000,
    "max_queue_size": 5000,
    "target_cpu_percent": 85.0,
    "offline_storage": true,
    "offline_retry_enabled": true,
    "connectivity_check_enabled": true,
    "storage_path": "/var/lib/myapp/tendrl.db",
    "heartbeat_interval_seconds": 60
}

Lightweight Sensor Device#

json

{
    "managed": true,
    "max_batch_size": 50,
    "max_queue_size": 200,
    "target_cpu_percent": 50.0,
    "target_mem_percent": 60.0,
    "offline_storage": true,
    "offline_retry_enabled": true,
    "connectivity_check_enabled": true,
    "heartbeat_interval_seconds": 120
}