Environment Variables Reference

Temps environment variables fall into two groups: server settings that configure the temps binary itself (TEMPS_*, read when temps serve starts), and application variables that Temps passes to your deployed containers. This page lists both, plus the CLI and SDK variables.

To add, scope and preview-gate your app's variables, see Manage Environment Variables.


Server Configuration

These environment variables configure the Temps server itself:

VariableCLI FlagDefaultDescription
TEMPS_ADDRESS--address127.0.0.1:3000HTTP server address and port
TEMPS_TLS_ADDRESS--tls-address(optional)HTTPS server address and port
TEMPS_DATA_DIR--data-dir~/.tempsData directory for keys and configuration
TEMPS_LOG_LEVEL--log-levelinfoLog level: trace, debug, info, warn, error
TEMPS_CONSOLE_ADDRESS--console-address(optional)Console listener (public ingest + admin if no split)

Admin Listener (optional)

When the admin listener is configured, admin/management routes bind to a separate address while TEMPS_CONSOLE_ADDRESS only serves public ingest endpoints (analytics events, error tracking ingest, AI gateway, worker route sync, email tracking pixels). See the admin listener guide for the full route classification and deployment patterns.

VariableCLI FlagDefaultDescription
TEMPS_CONSOLE_ADMIN_ADDRESS--console-admin-address(optional)Dedicated bind for admin/management routes. Unset = single listener mode (backwards-compat)
TEMPS_ADMIN_ALLOWED_IPS—(optional)Comma-separated IPs/CIDRs allowed to reach the admin listener (e.g. 10.0.0.0/8,127.0.0.1)
TEMPS_ADMIN_ALLOWED_HOSTS—(optional)Comma-separated Host header values allowed on the admin listener
TEMPS_ADMIN_TRUST_FORWARDED_FOR—falseHonor X-Forwarded-For for the IP gate — only from loopback peers (anti-spoof)

Example

# Single listener (backwards-compatible default)
export TEMPS_ADDRESS=0.0.0.0:8080
export TEMPS_TLS_ADDRESS=0.0.0.0:8443
export TEMPS_LOG_LEVEL=debug
export TEMPS_DATA_DIR=/var/lib/temps

# Two listeners with admin on loopback + IP allowlist
export TEMPS_CONSOLE_ADDRESS=0.0.0.0:8080
export TEMPS_CONSOLE_ADMIN_ADDRESS=127.0.0.1:8081
export TEMPS_ADMIN_ALLOWED_IPS=127.0.0.1/32,10.0.0.0/8
export TEMPS_ADMIN_ALLOWED_HOSTS=admin.temps.example.com

Database Configuration

VariableCLI FlagDefaultDescription
TEMPS_DATABASE_URL--database-url(required)PostgreSQL connection string

Database URL Format

postgresql://[user[:password]@][host][:port][/database][?param1=value1&...]

Example

# Preferred: set as environment variable (never visible in process listings)
export TEMPS_DATABASE_URL=postgresql://temps:password@localhost:5432/temps
temps serve

# Avoid: flag form exposes the password in ps/pgrep output
# temps serve --database-url=postgresql://temps:password@localhost:5432/temps

Connection Pool Tuning

Control the PostgreSQL connection pool size and timeouts:

VariableDefaultDescription
TEMPS_DB_MAX_CONNECTIONS100Maximum connections in the pool
TEMPS_DB_MIN_CONNECTIONS5Minimum idle connections kept open
TEMPS_DB_ACQUIRE_TIMEOUT30Seconds to wait for a connection
TEMPS_DB_IDLE_TIMEOUT600Seconds before idle connections are closed

For small servers (2GB RAM), reduce TEMPS_DB_MAX_CONNECTIONS to 20-30. If you see slow_acquire_threshold warnings in logs, it means the pool is saturated — either increase the max or investigate long-running queries.

# Example: tuning for a small VPS
export TEMPS_DB_MAX_CONNECTIONS=30
export TEMPS_DB_MIN_CONNECTIONS=2
export TEMPS_DB_IDLE_TIMEOUT=300

Data Directory

Temps stores sensitive data in the data directory (~/.temps by default):

~/.temps/
├── encryption_key    # Master key for AES-256-GCM encryption at rest (auto-generated)
└── auth_secret       # Session authentication secret (auto-generated)

Application environment variable values and managed-service credentials are encrypted at rest with AES-256-GCM under this one master key. Back up ~/.temps/encryption_key and ~/.temps/auth_secret. Losing these files means you cannot decrypt your existing data.


ClickHouse Analytics Backend

By default Temps stores analytics events, traces, metrics and proxy logs in PostgreSQL/TimescaleDB, with no extra configuration. For large workloads you can move those four domains to ClickHouse by setting the TEMPS_CLICKHOUSE_* variables and restarting temps serve, which reads them at startup. There is no rebuild and no cargo feature flag: the ClickHouse backends are compiled in and stay dormant until configured. The step-by-step procedure, including backfill, is in Migrate to ClickHouse.

VariableRequiredDefaultDescription
TEMPS_CLICKHOUSE_URLYes—ClickHouse HTTP endpoint URL
TEMPS_CLICKHOUSE_USERYes—ClickHouse username
TEMPS_CLICKHOUSE_PASSWORDYes—ClickHouse password
TEMPS_CLICKHOUSE_DATABASENotemps (when the URL is set)ClickHouse database name

Fail-closed activation

ClickHouse turns on only when the URL, user and password are all set and non-empty (the database name defaults to temps once the URL is set). Partial or empty configuration is treated as off, and Temps stays on PostgreSQL/TimescaleDB. A variable that is set but empty counts as unset, so a half-configured server never silently loses data.

# Enable the ClickHouse backends, then restart temps serve
export TEMPS_CLICKHOUSE_URL=http://clickhouse:8123
export TEMPS_CLICKHOUSE_USER=temps
export TEMPS_CLICKHOUSE_PASSWORD=your-clickhouse-password
# Optional; defaults to "temps"
export TEMPS_CLICKHOUSE_DATABASE=temps

The same variables enable all four domains in one database: analytics events, traces, resource metrics and proxy logs. Traces, metrics and proxy logs switch backend (new writes go to ClickHouse). Analytics events work differently, as described below.

Analytics events: dual write

When ClickHouse is enabled, the analytics-events plugin:

  1. Applies the embedded ClickHouse schema migrations — events, events_5m_mv, and sessions, tracked in a _temps_ch_migrations table.
  2. Spawns the ChFanoutWorker on the tokio runtime.
  3. Swaps the read-side analytics events service to ClickHouseEventsBackend.

Migrations and the worker run on background tasks so plugin init does not block on remote calls. If migrations fail, queries surface the error per-call rather than crashing startup.

PostgreSQL stays the system of record for events

PostgreSQL/TimescaleDB remains the source of truth. record_event writes the event to PostgreSQL synchronously, then enqueues the event id into an events_ch_outbox table (INSERT ... ON CONFLICT (event_id) DO NOTHING). The worker drains that outbox asynchronously, claiming batches with FOR UPDATE SKIP LOCKED and inserting into ClickHouse.

This makes ingestion resilient:

  • The outbox enqueue is best-effort. If it fails, the event is still recorded in PostgreSQL (the failure is logged at debug); that single event simply won't replicate to ClickHouse.
  • A ClickHouse outage never blocks ingestion. The write path never waits on ClickHouse — rows queue in the outbox and are retried on later poll cycles.
  • Retries are safe. The ClickHouse events table uses ReplacingMergeTree(_version) and dedupes over its sort key (with event_id as the most granular component), so re-delivering the same event collapses to one row.

The worker also runs an hourly retention sweep that deletes delivered outbox rows older than 7 days, and a 5-minute dead-letter scan that warn-logs the count of rows that hit the retry ceiling (attempts >= max_attempts, default 10) without deleting them.

Analytics behavior differences from the PostgreSQL backend

A few analytics behaviors differ by design when events are read from ClickHouse:

  • Unique counts are approximate. The ClickHouse backend uses uniq() (HyperLogLog), accurate to within ~1% at scale, instead of the exact COUNT(DISTINCT) used by PostgreSQL.
  • The self-referral filter is PostgreSQL-only. The referrer-hostname self-referral filter checks the project_custom_domains table, which is not replicated to ClickHouse.

Geolocation (country/region/city) is denormalized onto each ClickHouse event row at fan-out time, so breakdowns and timelines group on plain ClickHouse columns without a cross-database join.

PostgreSQL remains the system of record for analytics events and for all platform data (deployments, domains, users, configuration). To disable ClickHouse, unset the TEMPS_CLICKHOUSE_* variables and restart temps serve. See Migrate to ClickHouse for the enable, verify and rollback flow.


Application Environment Variables

These are environment variables you configure for your deployed applications:

Setting Environment Variables

Set an application environment variable

  1. 1

    Navigate to Project then Environment then Settings.

  2. 2

    Go to the Environment Variables section.

  3. 3

    Add or edit the variable, entering the key (e.g. DATABASE_URL) and its value.

    Checkpoint: Confirm the new variable appears in the Environment Variables list for the chosen environment.

Environment variables are set per project and scoped to environments. Values are encrypted at rest and applied on the next deployment.

Via Dashboard:

  1. Navigate to Project → Environment → Settings
  2. Go to Environment Variables section
  3. Add or edit variables

Via CLI:

# Set for several environments at once
bunx @temps-sdk/cli environments vars set \
  --environments production,staging \
  DATABASE_URL "postgresql://user:pass@host/db"

# Set for one environment
bunx @temps-sdk/cli environments vars set \
  --environments production \
  DATABASE_URL "postgresql://user:pass@host/db"

Without --environments, the CLI asks which environments to use. The commands act on the project linked to the current directory or your default project; pass --project <slug> to environments vars to pick another.

Via API:

await fetch(`https://your-temps-instance.com/api/projects/${projectId}/env-vars`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    key: "DATABASE_URL",
    value: "postgresql://user:pass@host/db",
    environment_ids: [1],
  }),
});

The full API (list, update, delete, secrets, preview control) is in Manage Environment Variables.

Variables Temps injects

Temps also sets variables in every container it deploys: HOST, PORT (in v0.1.0-beta.56, not on rollbacks or promotions), TEMPS_API_URL, TEMPS_API_TOKEN, CRON_SECRET, TEMPS_NODE_NAME, TEMPS_NODE_ID and TEMPS_REPLICA, plus credentials for linked services and error-tracking and OpenTelemetry settings. The full table, with values and version notes, is in Manage Environment Variables.

Framework-Specific Variables

Common environment variables for popular frameworks:

Next.js:

NODE_ENV=production
NEXT_PUBLIC_API_URL=https://api.example.com

React/Vite:

VITE_API_URL=https://api.example.com

Node.js:

NODE_ENV=production

Don't set PORT yourself: Temps sets it to the port it routes traffic to and replaces your value. Change the port in the project or environment settings instead.

Python:

PYTHONUNBUFFERED=1
FLASK_ENV=production

CLI Configuration

These environment variables configure the Temps CLI:

VariableDescription
TEMPS_API_URLAPI endpoint URL (e.g., https://your-temps-instance.com)
TEMPS_API_TOKENAPI authentication token
TEMPS_API_KEYAPI key (alternative to token)
NO_COLORDisable colored output (set to 1 or true)

Example

export TEMPS_API_URL=https://your-temps-instance.com
export TEMPS_API_TOKEN=your-token-here

Configuration Files

CLI configuration is stored in:

  • Config file: ~/.temps/config.json
  • Credentials: stored securely under ~/.temps/ with mode 0600, managed by login and logout

Use bunx @temps-sdk/cli configure show to view current configuration.


SDK Configuration

Node.js SDK

VariableDescription
TEMPS_API_URLYour Temps API URL
TEMPS_TOKENYour API key or deployment token
TEMPS_PROJECT_IDProject ID (optional, can be set in code)

React Analytics SDK

VariableDescription
NEXT_PUBLIC_TEMPS_API_URLTemps API URL (for Next.js)
NEXT_PUBLIC_TEMPS_PROJECT_IDProject ID (for Next.js)

Example

# Node.js SDK
export TEMPS_API_URL=https://your-temps-instance.com
export TEMPS_TOKEN=your-token-here

# Next.js with React Analytics
export NEXT_PUBLIC_TEMPS_API_URL=https://your-temps-instance.com
export NEXT_PUBLIC_TEMPS_PROJECT_ID=123

Precedence Rules

A variable belongs to the project and is assigned to one or more environments. There are no separate project-level and environment-level copies to merge: a key has one value per environment, and creating a key that already exists in one of the selected environments is rejected.

At deploy time, Temps builds the container's variables in this order. A later step replaces an earlier value with the same name:

  1. HOST=0.0.0.0, a default you can override
  2. Your variables assigned to the target environment
  3. Variables from linked managed services (POSTGRES_URL, REDIS_URL and so on)
  4. Variables Temps owns: SENTRY_DSN, TEMPS_API_URL, TEMPS_API_TOKEN, CRON_SECRET and the OTEL_* settings, then PORT, TEMPS_NODE_NAME, TEMPS_NODE_ID and TEMPS_REPLICA

In v0.1.0-beta.56, a variable you define with the same name as a linked-service variable is replaced by the service's value. Nightly builds since 2026-08-30 reverse steps 2 and 3, so your own value wins. Variables on the host running temps serve are never passed to app containers.

Give one environment its own value

Give one environment its own value

  1. 1

    Open the project and go to Environment Variables.

  2. 2

    If API_URL is already assigned to production, edit it and remove production from its environments.

  3. 3

    Add API_URL again with the production value, assigned to production only.

    Checkpoint: Confirm the list shows one API_URL per environment, each with its own value.

To use different values per environment, create one variable per value and assign each to different environments:

# Staging value
bunx @temps-sdk/cli environments vars set \
  --environments staging \
  API_URL "https://api-staging.example.com"

# Production value
bunx @temps-sdk/cli environments vars set \
  --environments production \
  API_URL "https://api-prod.example.com"

To change the value of an existing variable, run the same command with --update and without --environments; the variable keeps its current environments.

Project variables

In this section, a Project is a group of Services; elsewhere on this page, "project" still means a single deployable app, which the experimental feature calls a Service.

This layer is experimental and in nightly builds only; it does not exist in a beta or stable release yet. See Projects and Services.

When a Service belongs to a Project, the Project's shared variables become one more layer. For a deployment of the Service, from highest to lowest priority:

  1. Values Temps sets for the platform, such as SENTRY_DSN, TEMPS_API_URL, TEMPS_API_TOKEN and CRON_SECRET. A Project variable cannot replace them. HOST is the exception: a Service or Project variable can set it.
  2. The Service's own variables (the environment-level and project-level values above). Where a Service variable and a Project variable with the same name both apply to the environment, the Service's value wins.
  3. The Project's shared variables. Within the Project, a variable scoped to the environment's slug (for example production) wins over the Project's all-environments variable with the same name.
  4. Defaults from linked databases and storage, such as DATABASE_URL from a linked PostgreSQL. A Project variable overrides them.

All-environments Project variables reach preview environments only when marked to include previews (off by default). Secret Project variables are write-only, and changes apply on each Service's next deployment.


Best Practices

Security

  • Never commit secrets: Use environment variables for sensitive data
  • Use different values per environment: Production should have different credentials than staging
  • Rotate secrets regularly: Update API keys and tokens periodically
  • Use secure storage: Values are encrypted at rest, but anyone with dashboard access to the project can read them. External secret stores (Vault, AWS Secrets Manager, Infisical) are a Premium feature; see Premium

Organization

  • Use descriptive names: DATABASE_URL is better than DB
  • Document variables: Keep a list of required variables in your README
  • Group related variables: Use prefixes like DATABASE_, API_, REDIS_
  • Set defaults when possible: Provide sensible defaults in your application code

Debugging

  • Check variable precedence: Verify which value is actually being used
  • Use logging: Log variable names (not values) to verify they're set
  • Test locally: Use .env files for local development
  • Verify in dashboard: Check environment variables in the Temps dashboard

Additional Resources

Last updated

Was this page helpful?