Memtrace splits configuration in two:
- Global server settings (HTTP port, log format, timeouts, dedup) live in
memtrace.tomlorMEMTRACE_*environment variables. - Per-org Arc connection details (URL, API key, database, measurement) live in the metadata SQLite database and are managed via the
memtrace orgCLI. Memtrace is multi-tenant — each org points at its own Arc instance.
A required MEMTRACE_MASTER_KEY environment variable is used to encrypt per-org Arc API keys at rest.
Memtrace uses AES-256-GCM envelope encryption for the per-org Arc API keys it stores. The master key must be set on every host that runs memtrace serve or any memtrace admin subcommand.
# Generate once
export MEMTRACE_MASTER_KEY=$(memtrace keygen master)The value is a base64-encoded 32-byte key. Losing it makes encrypted secrets unrecoverable — store it in your secret manager (AWS Secrets Manager, GCP Secret Manager, Vault, 1Password, etc.) and inject it at runtime. Don't commit it to source control.
The server fails to start if MEMTRACE_MASTER_KEY is missing, malformed, or the wrong length.
Memtrace looks for memtrace.toml in these locations (in order):
- Current directory (
./memtrace.toml) /etc/memtrace/memtrace.toml$HOME/.memtrace/memtrace.toml
All TOML keys can be overridden with environment variables using the MEMTRACE_ prefix and _ between sections:
MEMTRACE_SERVER_PORT=9100
MEMTRACE_AUTH_ENABLED=true
MEMTRACE_LOG_LEVEL=debug
MEMTRACE_MASTER_KEY=... # required; not from TOML| Key | Env | Default | Description |
|---|---|---|---|
host |
MEMTRACE_SERVER_HOST |
0.0.0.0 |
Bind address |
port |
MEMTRACE_SERVER_PORT |
9100 |
Listen port |
read_timeout |
MEMTRACE_SERVER_READ_TIMEOUT |
30 |
Read timeout (seconds) |
write_timeout |
MEMTRACE_SERVER_WRITE_TIMEOUT |
30 |
Write timeout (seconds) |
shutdown_timeout |
MEMTRACE_SERVER_SHUTDOWN_TIMEOUT |
30 |
Graceful shutdown timeout (seconds) |
| Key | Env | Default | Description |
|---|---|---|---|
level |
MEMTRACE_LOG_LEVEL |
info |
Log level (debug, info, warn, error) |
format |
MEMTRACE_LOG_FORMAT |
console |
Log format (console or json) |
These are the global Arc client knobs shared by every per-org instance. Per-org url, api_key, database, and measurement are stored in the metadata DB — see "Managing organizations and Arc instances" below.
| Key | Env | Default | Description |
|---|---|---|---|
connect_timeout |
MEMTRACE_ARC_CONNECT_TIMEOUT |
5 |
Connection timeout (seconds) |
query_timeout |
MEMTRACE_ARC_QUERY_TIMEOUT |
30 |
Query timeout (seconds) |
write_batch_size |
MEMTRACE_ARC_WRITE_BATCH_SIZE |
100 |
Records per write batch |
write_flush_interval_ms |
MEMTRACE_ARC_WRITE_FLUSH_INTERVAL_MS |
1000 |
Flush interval (milliseconds) |
| Key | Env | Default | Description |
|---|---|---|---|
enabled |
MEMTRACE_AUTH_ENABLED |
true |
Enable API key authentication |
db_path |
MEMTRACE_AUTH_DB_PATH |
./data/memtrace.db |
SQLite database path (also stores org/Arc-instance metadata) |
| Key | Env | Default | Description |
|---|---|---|---|
enabled |
MEMTRACE_DEDUP_ENABLED |
true |
Enable deduplication |
window_hours |
MEMTRACE_DEDUP_WINDOW_HOURS |
24 |
Dedup time window (hours) |
| Env | Required | Description |
|---|---|---|
MEMTRACE_MASTER_KEY |
yes | Base64-encoded 32-byte key for envelope encryption of per-org Arc API keys. Generate with memtrace keygen master. |
[server]
host = "0.0.0.0"
port = 9100
[log]
level = "info"
format = "json" # use "json" in production
[arc]
connect_timeout = 5
query_timeout = 30
write_batch_size = 100
write_flush_interval_ms = 1000
[auth]
enabled = true
db_path = "./data/memtrace.db"
[dedup]
enabled = true
window_hours = 24Per-org Arc connection details are managed with the bundled CLI. Every admin command needs the metadata DB path (read from memtrace.toml) and MEMTRACE_MASTER_KEY set.
memtrace org create acme
# Organization created
# id: org_a1b2c3d4...
# name: acmememtrace org add-arc org_a1b2c3d4... \
--url https://arc.acme.example.com \
--api-key <arc-api-key> \
--database acme_memory \
--measurement events # default: eventsThe Arc API key is encrypted with MEMTRACE_MASTER_KEY before being stored.
memtrace org list
memtrace org show-arc <org_id> # API key is masked
memtrace org remove-arc <org_id>
memtrace org delete <org_id> # also cascades to its arc instance, agents, sessions, keysmemtrace key create --org <org_id> --name acme-prod
# API key created (shown only once — save it now):
# mtk_...
memtrace key list --org <org_id>
memtrace key revoke <key_id>A request authenticated with that key automatically routes reads and writes to the org's Arc instance. If the org has no Arc instance configured, the API returns 503 with a hint to run memtrace org add-arc.
Older Memtrace deployments declared the Arc URL/API key/database/measurement directly in memtrace.toml. On first startup, if the legacy [arc] block has a url set and the new arc_instances table is empty, Memtrace automatically:
- Ensures
org_defaultexists in theorganizationstable. - Encrypts the legacy
api_key. - Inserts an
arc_instancesrow (id=arc_default,org_id=org_default). - Logs:
WRN legacy [arc] config detected — migrating to DB url=...
INF migration complete; remove [arc] url/api_key/database/measurement from memtrace.toml on next deploy
The migration is idempotent — once arc_instances is populated, the legacy fields are ignored and the migration code does nothing on subsequent boots. Remove the deprecated fields from your TOML when convenient.
docker build -t memtrace .
# Generate a master key once and store it in your secret manager
MASTER=$(docker run --rm memtrace memtrace keygen master)
# Run the server
docker run -p 9100:9100 \
-e MEMTRACE_MASTER_KEY="$MASTER" \
-v ./data:/app/data \
memtraceAfter the server is up, provision orgs and Arc instances by running the admin CLI inside the container or against the same data volume:
docker exec -e MEMTRACE_MASTER_KEY="$MASTER" -it memtrace \
memtrace org create acme