MakinForU Panel

Environment Variables

Complete reference for all MakinForU environment variables

This page documents all environment variables used by MakinForU. Variables are organized by category. Most variables are optional and have sensible defaults.

For deployment-specific configuration, see the deployment guides.

Database & Storage

DATABASE_URL

Type: string Required: Yes Default: None

PostgreSQL connection string for the main database.

Example:

DATABASE_URL=postgres://user:password@localhost:5432/makinforu?schema=public

DATABASE_URL_DIRECT

Type: string Required: No Default: Same as DATABASE_URL

Direct PostgreSQL connection string (bypasses connection pooling). Used for migrations and administrative operations.

Example:

DATABASE_URL_DIRECT=postgres://user:password@localhost:5432/makinforu?schema=public

DATABASE_URL_REPLICA

Type: string Required: No Default: Same as DATABASE_URL

Read replica connection string for read-heavy operations. If not set, uses the main database.

Example:

DATABASE_URL_REPLICA=postgres://user:password@replica-host:5432/makinforu?schema=public

REDIS_URL

Type: string Required: Yes Default: redis://localhost:6379

Redis connection string for caching and queue management.

Example:

REDIS_URL=redis://localhost:6379
# With password
REDIS_URL=redis://:password@localhost:6379

CLICKHOUSE_URL

Type: string Required: Yes Default: http://localhost:8123/makinforu

ClickHouse HTTP connection URL for analytics data storage.

Example:

CLICKHOUSE_URL=http://localhost:8123/makinforu

CLICKHOUSE_CLUSTER

Type: boolean Required: No Default: false

Enable ClickHouse cluster mode. Set to true or 1 if using a ClickHouse cluster.

Example:

CLICKHOUSE_CLUSTER=true

CLICKHOUSE_SETTINGS

Type: string (JSON) Required: No Default: {}

Additional ClickHouse settings as a JSON object.

Example:

CLICKHOUSE_SETTINGS='{"max_execution_time": 300}'

CLICKHOUSE_SETTINGS_REMOVE_CONVERT_ANY_JOIN

Type: boolean Required: No Default: false

Remove convert_any_join from ClickHouse settings. Used for compatibility with certain ClickHouse versions. This needs to be set if you use any clickhouse version below 25!

Application URLs

API_URL

Type: string Required: Yes Default: None

Public API URL exposed to the browser. Used by the dashboard frontend and API service.

Example:

API_URL=https://analytics.example.com/api

API_URL_SSR

Type: string Required: No Default: Same as API_URL

Internal API URL used only for the dashboard's server-side rendering (SSR) requests. Set this when the dashboard server can't resolve or reach the public API_URL and needs an internal address instead — for example a Docker Compose service name or a Kubernetes cluster-internal address.

The browser always keeps using the public API_URL; only requests made from the dashboard server during SSR use API_URL_SSR. If unset, SSR falls back to API_URL.

Example:

# Docker Compose: reach the API service directly over the internal network
API_URL_SSR=http://api:3000

# Kubernetes: cluster-internal service DNS
API_URL_SSR=http://makinforu-api.default.svc.cluster.local:3000

This only affects the dashboard's server-side requests. It does not change the API service itself, CORS, or any browser-facing URLs — those still use API_URL.

DASHBOARD_URL

Type: string Required: Yes Default: None

Public dashboard URL exposed to the browser. Used by the dashboard frontend and API service.

Example:

DASHBOARD_URL=https://analytics.example.com

API_CORS_ORIGINS

Type: string (comma-separated) Required: No Default: None

Additional CORS origins allowed for API requests. Comma-separated list of origins.

Example:

API_CORS_ORIGINS=https://app.example.com,https://another-app.com

Authentication & Security

Type: string Required: Yes Default: None

Secret key for encrypting session cookies. Generate a secure random string (32+ characters).

Example:

# Generate with: openssl rand -base64 32
COOKIE_SECRET=your-random-secret-here

Never use the default value in production! Always generate a unique secret.

ENCRYPTION_KEY

Type: string (64 hexadecimal characters) Required: For Google Search Console, two-factor authentication (TOTP) and object-store exports Default: None

AES-256 key used for everything MakinForU encrypts at rest: Google Search Console tokens, users' 2FA secrets and S3/GCS export credentials. Must be exactly 32 bytes encoded as 64 hex characters, and must be identical on the API and worker services. The Docker Compose setup script generates one for you.

Example:

# Generate with: openssl rand -hex 32
ENCRYPTION_KEY=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef

Rotating this key makes every existing ciphertext unreadable. Search Console connections must be re-authorised, 2FA must be re-enrolled and export credentials re-entered. Back it up together with your database.

Type: string (comma-separated) Required: No Default: None

Custom multi-part TLDs for cookie domain handling. Use this when deploying on domains with public suffixes that aren't recognized by default (e.g., .my.id, .web.id, .co.id).

Example:

# For domains like abc.my.id
COOKIE_TLDS=my.id

# Multiple TLDs
COOKIE_TLDS=my.id,web.id,co.id

This is required when using domain suffixes that are public suffixes (like .co.uk). Without this, the browser will reject authentication cookies. Common examples include Indonesian domains (.my.id, .web.id, .co.id).

Type: string Required: No Default: None

Override the automatic cookie domain detection and set a specific domain for authentication cookies. Useful when proxying the API through your main domain or when you need precise control over cookie scope.

Example:

# Set cookies only on the main domain
CUSTOM_COOKIE_DOMAIN=.example.com

# Set cookies on a specific subdomain
CUSTOM_COOKIE_DOMAIN=.app.example.com

When set, this completely bypasses the automatic domain parsing logic. The cookie will always be set as secure. Include a leading dot (.) to allow the cookie to be shared across subdomains.

DEMO_USER_ID

Type: string Required: No Default: None

User ID for demo mode. When set, creates a demo session for testing.

Example:

DEMO_USER_ID=user_1234567890

ALLOW_REGISTRATION

Type: boolean Required: No Default: false (after first user is created)

Allow new user registrations. Set to true to enable public registration.

Example:

ALLOW_REGISTRATION=true

Registration is automatically disabled after the first user is created. Set this to true to re-enable it.

ALLOW_INVITATION

Type: boolean Required: No Default: true

Allow user invitations. Set to false to disable invitation functionality.

Example:

ALLOW_INVITATION=false

AI Features

The in-app AI chat supports OpenAI and Anthropic models. Set one or both provider keys on the API service — the model picker in the chat UI automatically shows only the models whose provider has a key configured. If neither is set, the chat drawer still opens but shows setup instructions instead of suggestions.

Available models:

  • OpenAIGPT-4.1, GPT-4.1 mini, GPT-5.4 mini
  • AnthropicClaude Haiku 4.5, Claude Sonnet 4.6, Claude Opus 4.6

The AI assistant is optional. Without OPENAI_API_KEY or ANTHROPIC_API_KEY set, every other MakinForU feature continues to work normally.

OPENAI_API_KEY

Type: string Required: No Default: None

OpenAI API key. When set, the OpenAI models appear in the chat model picker.

Example:

OPENAI_API_KEY=sk-your-openai-api-key-here

OPENAI_BASE_URL

Type: string Required: No Default: OpenAI default API base URL

Override the OpenAI API base URL. Useful for proxies, gateways, Azure-compatible endpoints, or self-hosted OpenAI-compatible providers.

Example:

OPENAI_BASE_URL=https://your-openai-compatible-endpoint.example.com/v1

OPENAI_PROJECT

Type: string Required: No Default: None

Optional OpenAI project identifier to send with requests.

Example:

OPENAI_PROJECT=proj_1234567890

OPENAI_ORGANIZATION

Type: string Required: No Default: None

Optional OpenAI organization identifier to send with requests.

Example:

OPENAI_ORGANIZATION=org_1234567890

ANTHROPIC_API_KEY

Type: string Required: No Default: None

Anthropic API key. When set, the Claude models appear in the chat model picker.

Example:

ANTHROPIC_API_KEY=sk-ant-your-anthropic-api-key-here

ANTHROPIC_BASE_URL

Type: string Required: No Default: Anthropic default API base URL

Override the Anthropic API base URL. Useful for proxies, gateways, or Anthropic-compatible endpoints.

Example:

ANTHROPIC_BASE_URL=https://your-anthropic-endpoint.example.com

ANTHROPIC_TOKEN

Type: string Required: No Default: None

Optional auth token sent to the Anthropic provider in addition to the API key. Use this only if your Anthropic-compatible gateway requires it.

Example:

ANTHROPIC_TOKEN=your-auth-token

ANTHROPIC_VERSION

Type: string Required: No Default: Provider default

Override the Anthropic API version header sent with requests.

Example:

ANTHROPIC_VERSION=2023-06-01

Email

RESEND_API_KEY

Type: string Required: No Default: None

Resend API key for sending transactional emails (password resets, invitations, etc.).

Example:

RESEND_API_KEY=re_xxxxxxxxxxxxx

Get your API key from resend.com. Make sure to verify your sender email domain.

EMAIL_SENDER

Type: string Required: No Default: hello@makinforu.com

Email address used as the sender for transactional emails. Applies to both Resend and SMTP transports.

Example:

EMAIL_SENDER=noreply@yourdomain.com

SMTP_HOST

Type: string Required: No Default: None

SMTP server hostname. When set, MakinForU uses SMTP to send emails instead of Resend. Takes priority over RESEND_API_KEY if both are configured.

Example:

SMTP_HOST=smtp.example.com

SMTP_PORT

Type: number Required: No Default: 587

SMTP server port.

Example:

SMTP_PORT=587

SMTP_SECURE

Type: boolean Required: No Default: false

Use TLS for the SMTP connection. Set to true when using port 465.

Example:

SMTP_SECURE=true

SMTP_USER

Type: string Required: No Default: None

SMTP authentication username. Leave unset if your server does not require authentication.

Example:

SMTP_USER=smtp-user@example.com

SMTP_PASS

Type: string Required: No Default: None

SMTP authentication password.

Example:

SMTP_PASS=your-smtp-password

Set SMTP_HOST to enable SMTP. If both SMTP_HOST and RESEND_API_KEY are present, SMTP takes priority. If neither is set, emails are logged to the console (useful for development). In case of using Resend, the sender email must be verified in your Resend account.

If SMTP_HOST is set and an SMTP send attempt fails, the system will not automatically fall back to RESEND_API_KEY — the email will be silently dropped. To use Resend instead, unset SMTP_HOST.

OAuth & Integrations

GOOGLE_CLIENT_ID

Type: string Required: No Default: None

OAuth client ID from Google Cloud Console. Enables Sign in with Google and is also used by the Google Search Console integration. Set it on the API, and on the worker if you use Search Console.

Example:

GOOGLE_CLIENT_ID=123456789012-abcdefghijklmnop.apps.googleusercontent.com

GOOGLE_CLIENT_SECRET

Type: string Required: No (required together with GOOGLE_CLIENT_ID) Default: None

OAuth client secret matching GOOGLE_CLIENT_ID. Only the API and worker need it.

Example:

GOOGLE_CLIENT_SECRET=GOCSPX-xxxxxxxxxxxxxxxxxxxxxxxx

GOOGLE_REDIRECT_URI

Type: string Required: For Google sign-in Default: None

Full callback URL for Google sign-in: ${API_URL}/oauth/google/callback. Must exactly match an authorized redirect URI on the Google OAuth client. It is not derived from API_URL, so set it explicitly. See Social login.

Example:

GOOGLE_REDIRECT_URI=https://analytics.example.com/api/oauth/google/callback

GSC_GOOGLE_REDIRECT_URI

Type: string Required: For the Google Search Console integration Default: None

Full callback URL for connecting Google Search Console: ${API_URL}/gsc/callback. Must be registered as an authorized redirect URI on the same Google OAuth client as GOOGLE_REDIRECT_URI. Only the API needs it. See Google Search Console.

Example:

GSC_GOOGLE_REDIRECT_URI=https://analytics.example.com/api/gsc/callback

GITHUB_CLIENT_ID

Type: string Required: No Default: None

Client ID of a GitHub OAuth App. Enables Sign in with GitHub. Only the API needs it.

Example:

GITHUB_CLIENT_ID=Iv1.xxxxxxxxxxxxxxxx

GITHUB_CLIENT_SECRET

Type: string Required: No (required together with GITHUB_CLIENT_ID) Default: None

Client secret of the GitHub OAuth App. Only the API needs it.

Example:

GITHUB_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

GITHUB_REDIRECT_URI

Type: string Required: For GitHub sign-in Default: None

Full callback URL for GitHub sign-in: ${API_URL}/oauth/github/callback. Must exactly match the authorization callback URL of the GitHub OAuth App. It is not derived from API_URL, so set it explicitly.

Example:

GITHUB_REDIRECT_URI=https://analytics.example.com/api/oauth/github/callback

The dashboard only shows the social login buttons and the Search Console settings when the API has both the client ID and the redirect URI for that feature. The dashboard itself needs none of these variables.

SLACK_CLIENT_ID

Type: string Required: No Default: None

Slack OAuth client ID for Slack integration.

Example:

SLACK_CLIENT_ID=1234567890.1234567890

SLACK_CLIENT_SECRET

Type: string Required: No Default: None

Slack OAuth client secret for Slack integration.

Example:

SLACK_CLIENT_SECRET=your-slack-client-secret

SLACK_OAUTH_REDIRECT_URL

Type: string Required: No Default: None

Slack OAuth redirect URL. Must match the redirect URI configured in your Slack app.

Example:

SLACK_OAUTH_REDIRECT_URL=https://analytics.example.com/api/integrations/slack/callback

SLACK_STATE_SECRET

Type: string Required: No Default: None

Secret for signing Slack OAuth state parameter.

Example:

SLACK_STATE_SECRET=your-state-secret

Self-hosting

SELF_HOSTED

Type: boolean Required: No Default: false

Enable self-hosted mode. Set to true or 1 to enable self-hosting features. Used by both the dashboard frontend and API service.

Example:

SELF_HOSTED=true

Worker & Queue

WORKER_PORT

Type: number Required: No Default: 3000

Port for the worker service to listen on.

Example:

WORKER_PORT=3000

DISABLE_BULLBOARD

Type: boolean Required: No Default: false

Disable BullMQ board UI. Set to true or 1 to disable the queue monitoring dashboard.

Example:

DISABLE_BULLBOARD=true

DISABLE_WORKERS

Type: boolean Required: No Default: false

Disable all worker processes. Set to true or 1 to disable background job processing.

Example:

DISABLE_WORKERS=true

ENABLED_QUEUES

Type: string (comma-separated) Required: No Default: All queues enabled

Comma-separated list of queue names to enable. Available queues: events, events_kafka, sessions, cron, notification, import, insights, gsc, cohortCompute.

Example:

ENABLED_QUEUES=events,sessions,cron

Enable events_kafka to run the Kafka-based events consumer alongside (or instead of) the default events queue. See the Event Streaming (Kafka) section for the full configuration. A common high-throughput layout is to run one worker pool with ENABLED_QUEUES=events_kafka and another pool with everything else.

EVENT_JOB_CONCURRENCY

Type: number Required: No Default: 10

Number of concurrent event processing jobs per worker.

Example:

EVENT_JOB_CONCURRENCY=20

GSC_CONCURRENCY

Type: number Required: No Default: 5

Number of Google Search Console sync/backfill jobs a worker runs in parallel. Only relevant when the integration is enabled; requires gsc (and cron) in ENABLED_QUEUES if that variable is set.

Example:

GSC_CONCURRENCY=2

EVENT_BLOCKING_TIMEOUT_SEC

Type: number Required: No Default: 1

Blocking timeout in seconds for event queue workers.

Example:

EVENT_BLOCKING_TIMEOUT_SEC=2

EVENTS_GROUP_QUEUES_SHARDS

Type: number Required: No Default: 1

Number of shards for the events group queue. Increase for better performance with high event volume.

Example:

EVENTS_GROUP_QUEUES_SHARDS=4

QUEUE_CLUSTER

Type: boolean Required: No Default: false

Enable Redis cluster mode for queues. When enabled, queue names are wrapped with {} for Redis cluster sharding.

Example:

QUEUE_CLUSTER=true

ORDERING_DELAY_MS

Type: number Required: No Default: 100

Delay in milliseconds to hold events for correct ordering when events arrive out of order.

Example:

ORDERING_DELAY_MS=200

Should not exceed 500ms. Higher values may cause delays in event processing.

AUTO_BATCH_MAX_WAIT_MS

Type: number Required: No Default: 0 (disabled)

Maximum wait time in milliseconds for auto-batching events. Experimental feature.

Example:

AUTO_BATCH_MAX_WAIT_MS=100

⚠️ Experimental: This feature is experimental and not used in production. Do not use unless you have a good understanding of the implications and specific performance requirements.

AUTO_BATCH_SIZE

Type: number Required: No Default: 0 (disabled)

Batch size for auto-batching events. Experimental feature.

Example:

AUTO_BATCH_SIZE=100

⚠️ Experimental: This feature is experimental and not used in production. Do not use unless you have a good understanding of the implications and specific performance requirements.

Event Streaming (Kafka)

MakinForU can optionally ingest events through a Kafka-compatible broker (Kafka itself, Redpanda, etc.) instead of the default Redis-backed events queue. This is useful at high throughput, where many consumer instances can process partitions in parallel.

Routing is all-or-nothing: if KAFKA_BROKERS is set, every event is produced to the Kafka topic; otherwise all events stay on the default Redis-backed events queue. Set ENABLED_QUEUES=events_kafka on the worker(s) that should consume from Kafka.

Connections are unauthenticated plaintext by default. For managed or production clusters, enable TLS with KAFKA_SSL and SASL authentication (plain, scram-sha-256 or scram-sha-512) with the KAFKA_SASL_* variables below.

The client speaks the Kafka wire protocol via kafkajs, so any Kafka-compatible broker works. The bundled docker-compose.yml uses Redpanda as a lightweight, single-binary option, but you can point KAFKA_BROKERS at any Kafka cluster.

KAFKA_BROKERS

Type: string (comma-separated) Required: Yes (to enable the Kafka path) Default: None

Comma-separated list of Kafka broker addresses. When set, all events are produced to Kafka; when unset, the Kafka producer/consumer is disabled and all events fall back to the default Redis-backed queue.

Example:

KAFKA_BROKERS=redpanda:9092
# Multiple brokers
KAFKA_BROKERS=kafka-1:9092,kafka-2:9092,kafka-3:9092

KAFKA_SSL

Type: boolean Required: No Default: false (automatically true when SASL credentials are set)

Connect to the brokers over TLS. Set this to true for a TLS-only cluster without authentication. When KAFKA_SASL_USERNAME/KAFKA_SASL_PASSWORD are set, TLS is enabled automatically; set KAFKA_SSL=false explicitly to send SASL over plaintext (only sensible on a trusted internal network).

Example:

KAFKA_SSL=true

KAFKA_SSL_CA_PATH

Type: string Required: No Default: None (system trust store)

Path to a PEM-encoded CA certificate (or bundle) to trust in addition to the system trust store. Use this when your brokers present certificates signed by a private or self-signed CA. Requires TLS to be enabled.

Example:

KAFKA_SSL_CA_PATH=/etc/makinforu/kafka-ca.pem

KAFKA_SSL_REJECT_UNAUTHORIZED

Type: boolean Required: No Default: true

Whether to reject broker certificates that cannot be verified. Only set to false for local development against a self-signed broker; prefer KAFKA_SSL_CA_PATH in production. Requires TLS to be enabled.

Example:

KAFKA_SSL_REJECT_UNAUTHORIZED=false

KAFKA_SASL_USERNAME

Type: string Required: No (required together with KAFKA_SASL_PASSWORD to enable SASL) Default: None

SASL username. Setting a username without a password (or vice versa) is a configuration error and the process refuses to start. Credential values are never logged.

Example:

KAFKA_SASL_USERNAME=makinforu

KAFKA_SASL_PASSWORD

Type: string Required: No (required together with KAFKA_SASL_USERNAME to enable SASL) Default: None

SASL password.

Example:

KAFKA_SASL_PASSWORD=your-secret

KAFKA_SASL_MECHANISM

Type: string Required: No Default: scram-sha-512

SASL mechanism to authenticate with. One of plain, scram-sha-256 or scram-sha-512 (case-insensitive). Any other value is rejected at startup, before a Kafka client is created.

Example:

# TLS + SASL/SCRAM-SHA-512 (the default when credentials are set)
KAFKA_BROKERS=kafka-1.example.com:9093,kafka-2.example.com:9093
KAFKA_SASL_USERNAME=makinforu
KAFKA_SASL_PASSWORD=your-secret

# TLS + SASL/PLAIN with a private CA
KAFKA_BROKERS=kafka.internal:9093
KAFKA_SASL_MECHANISM=plain
KAFKA_SASL_USERNAME=makinforu
KAFKA_SASL_PASSWORD=your-secret
KAFKA_SSL_CA_PATH=/etc/makinforu/kafka-ca.pem

The producer runs in idempotent mode, so the SASL principal needs the IdempotentWrite cluster permission in addition to Write/Describe on the topic and Read on the consumer group. Managed Kafka providers usually grant this by default; on a locked-down cluster you may need to add it explicitly.

KAFKA_EVENTS_TOPIC

Type: string Required: No Default: events

Name of the Kafka topic used for incoming events.

Example:

KAFKA_EVENTS_TOPIC=makinforu-events

KAFKA_CONSUMER_GROUP

Type: string Required: No Default: makinforu-events

Kafka consumer group ID used by the worker. All worker replicas with the same group ID share partition assignments cooperatively.

Example:

KAFKA_CONSUMER_GROUP=makinforu-events

KAFKA_CLIENT_ID

Type: string Required: No Default: makinforu

Kafka client ID used by both producer and consumer. Shows up in broker logs and metrics.

Example:

KAFKA_CLIENT_ID=makinforu-prod

KAFKA_PARTITIONS_CONCURRENT

Type: number Required: No Default: 8

Maximum number of partitions a single consumer instance processes concurrently. Has no effect beyond the number of partitions actually assigned to this consumer.

Example:

KAFKA_PARTITIONS_CONCURRENT=12

KAFKA_MIN_MESSAGES

Type: number Required: No Default: 1

Minimum number of messages the broker should accumulate before responding to a fetch request (each message is assumed to be ~1 KiB internally). Higher values create larger batches at the cost of slightly higher latency.

Example:

KAFKA_MIN_MESSAGES=16

KAFKA_MAX_WAIT_MS

Type: number Required: No Default: 500

Maximum time in milliseconds the broker waits to fulfil KAFKA_MIN_MESSAGES before returning a fetch response. Caps end-to-end latency under low traffic.

Example:

KAFKA_MAX_WAIT_MS=200

KAFKA_MAX_MESSAGES_PER_PARTITION

Type: number Required: No Default: 256

Maximum number of messages returned per partition per fetch request (each message is assumed to be ~1 KiB internally). Caps in-memory batch size during backlog recovery and bounds the worst-case time the consumer spends on a single batch.

Example:

KAFKA_MAX_MESSAGES_PER_PARTITION=512

KAFKA_SESSION_TIMEOUT_MS

Type: number Required: No Default: 30000

Consumer group session timeout in milliseconds. The broker considers a consumer dead and rebalances its partitions if it does not heartbeat within this window.

Example:

KAFKA_SESSION_TIMEOUT_MS=45000

KAFKA_HEARTBEAT_INTERVAL_MS

Type: number Required: No Default: 3000

How often, in milliseconds, the consumer sends background heartbeats to the broker. Should be well below KAFKA_SESSION_TIMEOUT_MS.

Example:

KAFKA_HEARTBEAT_INTERVAL_MS=3000

Buffers

SESSION_BUFFER_BATCH_SIZE

Type: number Required: No Default: Buffer-specific default

Batch size for session buffer operations.

Example:

SESSION_BUFFER_BATCH_SIZE=5000

SESSION_BUFFER_CHUNK_SIZE

Type: number Required: No Default: Buffer-specific default

Chunk size for session buffer operations.

Example:

SESSION_BUFFER_CHUNK_SIZE=1000

EVENT_BUFFER_BATCH_SIZE

Type: number Required: No Default: 4000

Batch size for event buffer operations.

Example:

EVENT_BUFFER_BATCH_SIZE=5000

EVENT_BUFFER_CHUNK_SIZE

Type: number Required: No Default: 1000

Chunk size for event buffer operations.

Example:

EVENT_BUFFER_CHUNK_SIZE=2000

PROFILE_BUFFER_BATCH_SIZE

Type: number Required: No Default: Buffer-specific default

Batch size for profile buffer operations.

Example:

PROFILE_BUFFER_BATCH_SIZE=5000

PROFILE_BUFFER_CHUNK_SIZE

Type: number Required: No Default: Buffer-specific default

Chunk size for profile buffer operations.

Example:

PROFILE_BUFFER_CHUNK_SIZE=1000

PROFILE_BUFFER_TTL_IN_SECONDS

Type: number Required: No Default: Buffer-specific default

Time-to-live in seconds for profile buffer entries.

Example:

PROFILE_BUFFER_TTL_IN_SECONDS=3600

BOT_BUFFER_BATCH_SIZE

Type: number Required: No Default: Buffer-specific default

Batch size for bot detection buffer operations.

Example:

BOT_BUFFER_BATCH_SIZE=1000

Analytics Behavior

FUNNEL_NON_STRICT_ORDERING

Type: boolean (1 or true) Required: No Default: unset (strict ordering)

Funnels use ClickHouse's windowFunnel in strict_increase mode by default: every step's timestamp must be strictly greater than the previous step's. Setting this variable switches funnels to non-strict ordering (>=), where steps sharing the same timestamp still count as an ordered sequence — matching how Mixpanel and Amplitude evaluate funnels. Useful for server-side senders, batched SDKs, or imported data with coarse timestamps.

Example:

FUNNEL_NON_STRICT_ORDERING=1

Performance & Tuning

EVENT_LIST_MAX_LOOKBACK_DAYS

Type: number (whole days, positive integer) Required: No Default: 1825 (5 years)

Ceiling for the empty-result lookback on the event list. When a page's cursor window matches nothing, the window doubles and retries until it reaches this many days. With filters that no index can prune (e.g. a properties value) each retry is a full scan of its window, so large deployments can bound the worst case with a small, human-sized value. Invalid values (non-integer, zero, negative) keep the default.

Example:

EVENT_LIST_MAX_LOOKBACK_DAYS=7

SESSION_LIST_MAX_LOOKBACK_DAYS

Type: number (whole days, positive integer) Required: No Default: 365

Same ceiling for the session list, which has its own default. Invalid values keep the default.

Example:

SESSION_LIST_MAX_LOOKBACK_DAYS=7

COHORT_QUERY_MEMORY_LIMIT_BYTES

Type: number (bytes, positive integer) Required: No Default: unset (server defaults govern)

Hard memory cap applied to property-cohort queries, which aggregate every profile row for a project and are the one cohort query that can outgrow the server's headroom. When set without COHORT_QUERY_SPILL_BYTES, the spill threshold is derived as a third of this limit so the query spills to disk before it can be killed. Unset (together with the spill variable) applies no per-query settings at all. Invalid values are ignored.

Example:

COHORT_QUERY_MEMORY_LIMIT_BYTES=1400000000

COHORT_QUERY_SPILL_BYTES

Type: number (bytes, positive integer) Required: No Default: unset (derived as COHORT_QUERY_MEMORY_LIMIT_BYTES / 3 when that is set)

Point past which a property-cohort GROUP BY spills to disk instead of growing in memory. Must sit below the memory limit — a threshold at or above the kill limit means the query dies before it ever spills, so inverted pairs are re-derived. Invalid values are ignored.

Example:

COHORT_QUERY_SPILL_BYTES=314572800

IMPORT_BATCH_SIZE

Type: number Required: No Default: 5000

Batch size for data import operations.

Example:

IMPORT_BATCH_SIZE=10000

EVENT_PROPERTY_VALUE_AUTOCOMPLETE_LIMIT

Type: number (positive integer)
Required: No
Default: 500

Cap on distinct values returned per event property to the filter autocomplete. High-cardinality keys (ids, urls, tokens) can hold millions of distinct values; the most recent ones win. Invalid values keep the default.

Example:

EVENT_PROPERTY_VALUE_AUTOCOMPLETE_LIMIT=1000

IP_HEADER_ORDER

Type: string (comma-separated) Required: No Default: See default order

Custom order of HTTP headers to check for client IP address. Useful when behind specific proxies or CDNs.

Example:

IP_HEADER_ORDER=cf-connecting-ip,x-real-ip,x-forwarded-for

The default order includes: makinforu-client-ip, cf-connecting-ip, true-client-ip, x-client-ip, x-forwarded-for, x-real-ip, and others. See the source code for the complete default list.

SHUTDOWN_GRACE_PERIOD_MS

Type: number Required: No Default: 5000

Grace period in milliseconds for graceful shutdown of services.

Example:

SHUTDOWN_GRACE_PERIOD_MS=10000

API_PORT

Type: number Required: No Default: 3000

Port for the API service to listen on.

Example:

API_PORT=3000

API_HOST

Type: string Required: No Default: 0.0.0.0 (production) / localhost (development)

Host address for the API service to bind to. Set to :: to enable IPv6 support (useful for platforms like Railway that use IPv6 for internal networking).

Example:

# Default IPv4 only
API_HOST=0.0.0.0

# IPv6 (dual-stack, accepts both IPv4 and IPv6)
API_HOST=::

Use API_HOST=:: when deploying on platforms like Railway where private networking requires IPv6. The :: address enables dual-stack mode, accepting both IPv4 and IPv6 connections on most systems.

Logging

LOG_LEVEL

Type: string Required: No Default: info

Logging level. Options: error, warn, info, debug.

Example:

LOG_LEVEL=debug

LOG_SILENT

Type: boolean Required: No Default: false

Disable all logging output. Set to true to silence logs.

Example:

LOG_SILENT=true

LOG_PREFIX

Type: string Required: No Default: None

Prefix for log messages. Useful for identifying logs from different services.

Example:

LOG_PREFIX=api

HYPERDX_API_KEY

Type: string Required: No Default: None

HyperDX API key for sending logs to HyperDX for monitoring and analysis.

Example:

HYPERDX_API_KEY=your-hyperdx-api-key

Geo

MAXMIND_LICENSE_KEY

Type: string Required: No Default: None

MaxMind GeoLite2 license key for downloading GeoIP databases.

Example:

MAXMIND_LICENSE_KEY=your-maxmind-license-key

Get your license key from MaxMind. Required for downloading GeoIP databases.

Quick Reference

Required Variables

For a basic self-hosted installation, these variables are required:

  • DATABASE_URL - PostgreSQL connection
  • REDIS_URL - Redis connection
  • CLICKHOUSE_URL - ClickHouse connection
  • API_URL - API endpoint URL
  • DASHBOARD_URL - Dashboard URL
  • COOKIE_SECRET - Session encryption secret
  • RESEND_API_KEY or SMTP_HOST - For email features (pick one)
  • EMAIL_SENDER - Email sender address
  • OPENAI_API_KEY and/or ANTHROPIC_API_KEY - For the in-app AI chat assistant
  • ENCRYPTION_KEY - Required for Google Search Console, 2FA and exports
  • GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_REDIRECT_URI - Sign in with Google
  • GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, GITHUB_REDIRECT_URI - Sign in with GitHub
  • GSC_GOOGLE_REDIRECT_URI - Google Search Console integration

See Also

On this page

Database & StorageDATABASE_URLDATABASE_URL_DIRECTDATABASE_URL_REPLICAREDIS_URLCLICKHOUSE_URLCLICKHOUSE_CLUSTERCLICKHOUSE_SETTINGSCLICKHOUSE_SETTINGS_REMOVE_CONVERT_ANY_JOINApplication URLsAPI_URLAPI_URL_SSRDASHBOARD_URLAPI_CORS_ORIGINSAuthentication & SecurityCOOKIE_SECRETENCRYPTION_KEYCOOKIE_TLDSCUSTOM_COOKIE_DOMAINDEMO_USER_IDALLOW_REGISTRATIONALLOW_INVITATIONAI FeaturesOPENAI_API_KEYOPENAI_BASE_URLOPENAI_PROJECTOPENAI_ORGANIZATIONANTHROPIC_API_KEYANTHROPIC_BASE_URLANTHROPIC_TOKENANTHROPIC_VERSIONEmailRESEND_API_KEYEMAIL_SENDERSMTP_HOSTSMTP_PORTSMTP_SECURESMTP_USERSMTP_PASSOAuth & IntegrationsGOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRETGOOGLE_REDIRECT_URIGSC_GOOGLE_REDIRECT_URIGITHUB_CLIENT_IDGITHUB_CLIENT_SECRETGITHUB_REDIRECT_URISLACK_CLIENT_IDSLACK_CLIENT_SECRETSLACK_OAUTH_REDIRECT_URLSLACK_STATE_SECRETSelf-hostingSELF_HOSTEDWorker & QueueWORKER_PORTDISABLE_BULLBOARDDISABLE_WORKERSENABLED_QUEUESEVENT_JOB_CONCURRENCYGSC_CONCURRENCYEVENT_BLOCKING_TIMEOUT_SECEVENTS_GROUP_QUEUES_SHARDSQUEUE_CLUSTERORDERING_DELAY_MSAUTO_BATCH_MAX_WAIT_MSAUTO_BATCH_SIZEEvent Streaming (Kafka)KAFKA_BROKERSKAFKA_SSLKAFKA_SSL_CA_PATHKAFKA_SSL_REJECT_UNAUTHORIZEDKAFKA_SASL_USERNAMEKAFKA_SASL_PASSWORDKAFKA_SASL_MECHANISMKAFKA_EVENTS_TOPICKAFKA_CONSUMER_GROUPKAFKA_CLIENT_IDKAFKA_PARTITIONS_CONCURRENTKAFKA_MIN_MESSAGESKAFKA_MAX_WAIT_MSKAFKA_MAX_MESSAGES_PER_PARTITIONKAFKA_SESSION_TIMEOUT_MSKAFKA_HEARTBEAT_INTERVAL_MSBuffersSESSION_BUFFER_BATCH_SIZESESSION_BUFFER_CHUNK_SIZEEVENT_BUFFER_BATCH_SIZEEVENT_BUFFER_CHUNK_SIZEPROFILE_BUFFER_BATCH_SIZEPROFILE_BUFFER_CHUNK_SIZEPROFILE_BUFFER_TTL_IN_SECONDSBOT_BUFFER_BATCH_SIZEAnalytics BehaviorFUNNEL_NON_STRICT_ORDERINGPerformance & TuningEVENT_LIST_MAX_LOOKBACK_DAYSSESSION_LIST_MAX_LOOKBACK_DAYSCOHORT_QUERY_MEMORY_LIMIT_BYTESCOHORT_QUERY_SPILL_BYTESIMPORT_BATCH_SIZEEVENT_PROPERTY_VALUE_AUTOCOMPLETE_LIMITIP_HEADER_ORDERSHUTDOWN_GRACE_PERIOD_MSAPI_PORTAPI_HOSTLoggingLOG_LEVELLOG_SILENTLOG_PREFIXHYPERDX_API_KEYGeoMAXMIND_LICENSE_KEYQuick ReferenceRequired VariablesOptional but RecommendedSee Also