Skip to content

en deploy settings

langbot-wiki-sync[bot] edited this page Aug 11, 2026 · 3 revisions

System Environment Settings

LangBot runtime configuration lives in data/config.yaml. The first startup generates it from the default template. The example below is kept aligned with src/langbot/templates/config.yaml.

Note

Most self-hosted deployments only need to change public URLs, databases/vector stores, object storage, and Box Runtime. Keep capacity and Cloud safety limits at their defaults unless you understand their operational impact.

Complete default configuration

api:
    port: 5300
    webhook_prefix: 'http://127.0.0.1:5300'
    extra_webhook_prefix: ''
    # Canonical browser origin when WebUI and API use different origins in
    # development (for example http://localhost:3000). Production bundled UI
    # may leave this empty when webhook_prefix already has the browser origin.
    # OAuth redirects trust only these server-side values, never request Host
    # or Origin headers.
    webui_url: ''
    # Global API key for the HTTP service API and the MCP server. When set to a
    # non-empty string, this key is accepted anywhere a web-UI-created API key is
    # accepted (X-API-Key header or "Authorization: Bearer <key>"), WITHOUT any
    # login session and without a database record. Leave empty to disable.
    # Keep this value secret; only enable it on trusted/internal deployments.
    global_api_key: ''
workspace:
    invitations:
        # Public WebUI origin used to build invitation links. Leave empty to
        # use api.webui_url, then api.webhook_prefix. Set via
        # WORKSPACE__INVITATIONS__PUBLIC_WEB_URL in container deployments.
        public_web_url: ''
        email:
            # Optional invitation email delivery. Empty provider keeps
            # invitations link-only. Supported: resend, smtp.
            provider: ''
            from: ''
            timeout_seconds: 10
            resend:
                api_url: 'https://api.resend.com/emails'
                # Secret. Set via WORKSPACE__INVITATIONS__EMAIL__RESEND__API_KEY.
                api_key: ''
            smtp:
                host: ''
                port: 587
                username: ''
                # Secret. Set via WORKSPACE__INVITATIONS__EMAIL__SMTP__PASSWORD.
                password: ''
                starttls: true
                ssl: false
command:
    enable: true
    prefix:
    - '!'
    - 
    privilege: {}
concurrency:
    pipeline: 20
    session: 1
    # Hard admission limits for queued + running pipeline queries.
    pending_queries: 1000
    pending_queries_per_workspace: 100
webhooks:
    # Bound database materialization and per-message outbound fan-out.
    # Existing rows above this limit remain deletable through the management
    # API, but only this many enabled destinations are dispatched.
    # Supports WEBHOOKS__MAX_PER_WORKSPACE (hard cap: 64).
    max_per_workspace: 16
    # Instance-wide request admission. Delivery fails open when every slot is
    # occupied instead of retaining an unbounded queue of webhook tasks.
    # Supports WEBHOOKS__MAX_INFLIGHT_REQUESTS (hard cap: 128).
    max_inflight_requests: 16
cloud:
    # Operational safety ceilings for the one logical Cloud instance. These
    # are not subscription entitlements. An authoritative directory update
    # that would exceed them is rejected atomically rather than truncated.
    directory:
        # Tune downward from the measured production capacity curve. Core has
        # an absolute safety ceiling of 5,000 active Workspaces.
        max_active_workspaces: 1000
        # Full snapshots contain current Workspaces only. Archived tombstones
        # are delivered through bounded per-Workspace deltas.
        max_snapshot_workspaces: 1000
        # Aggregate memberships accepted in one signed snapshot or delta.
        max_snapshot_memberships: 20000
        # Signed control-plane envelope buffered by the closed adapter before
        # JSON/JWS verification (32 MiB; absolute maximum 64 MiB).
        max_response_bytes: 33554432
proxy:
    http: ''
    https: ''
system:
    instance_id: ''
    edition: community
    recovery_key: ''
    allow_modify_login_info: true
    disabled_adapters: []
    blocking_executor:
        # All asyncio.to_thread work shares this process-wide bounded pool.
        # Both running threads and queued calls are capped to prevent tenant
        # bursts from creating an unbounded queue of retained request objects.
        max_workers: 8
        max_pending: 128
        # One trusted Workspace can occupy at most this many running + queued
        # slots. This must not exceed half of max_workers.
        max_inflight_per_scope: 4
    # Public outbound IP addresses of this LangBot deployment. Some platforms
    # (e.g. WeCom, WeChat Official Account, QQ Official API) require the
    # caller's IPs to be added to their trusted-IP / IP-whitelist settings.
    # When set, the web UI shows these IPs on the bot config form of such
    # adapters. Also settable via the SYSTEM__OUTBOUND_IPS env var
    # (comma-separated). Empty list = hidden in the web UI.
    outbound_ips: []
    limitation:
        max_bots: -1
        max_pipelines: -1
        max_extensions: -1
        max_knowledge_bases: -1
        # When set to a non-empty string, every pipeline is forced to use this
        # Box sandbox-scope template regardless of its own configuration, and
        # the per-pipeline "Sandbox Scope" selector is locked in the web UI.
        # Used by SaaS deployments to confine a tenant to a single shared
        # sandbox (set to '{global}'). Empty string = no restriction.
        force_box_session_id_template: ''
    task_retention:
        # Keep at most this many completed async task records in memory
        completed_limit: 200
        # Bound progress output retained by one task, including running tasks.
        max_log_chars: 200000
        # Protect the shared process from user-triggered operation storms.
        max_active_user_tasks: 256
        max_active_user_tasks_per_workspace: 8
    session_retention:
        # Process-local conversation sessions are a cache, not durable history.
        max_entries: 2000
        max_entries_per_workspace: 200
        idle_ttl_seconds: 86400
        max_conversations_per_session: 20
        max_messages_per_conversation: 100
    websocket_retention:
        # Bound live browser sockets and per-Workspace fan-out in the shared process.
        max_connections: 1024
        max_connections_per_workspace: 32
        # Idle proxy runtimes are evicted when this process-local cache fills.
        max_workspace_proxies: 1024
        max_conversations_per_workspace: 200
        max_messages_per_conversation: 100
        conversation_idle_ttl_seconds: 86400
        send_queue_size: 100
    response_limits:
        # Defense in depth for tenant-configured upstream providers.
        max_generated_chars: 1048576
        max_stream_chunks: 100000
    jwt:
        expire: 604800
        secret: ''
database:
    use: sqlite
    sqlite:
        path: 'data/langbot.db'
    postgresql:
        # Optional SQLAlchemy URL (postgresql[+asyncpg]://...). When set, it
        # overrides the structured fields and preserves TLS/query options.
        url: ''
        host: '127.0.0.1'
        port: 5432
        user: 'postgres'
        password: 'postgres'
        database: 'postgres'
        # One bounded pool is shared by business data and Cloud pgvector.
        pool_size: 10
        max_overflow: 10
        pool_timeout_seconds: 30
        pool_recycle_seconds: 1800
        # Applied only to Cloud runtime connections. The one-shot release
        # migration uses its operator connection without these short limits.
        statement_timeout_ms: 60000
        lock_timeout_ms: 5000
        idle_in_transaction_session_timeout_ms: 60000
    cloud_migration:
        # `langbot migrate --cloud` reads an operator-only PostgreSQL DSN from
        # this environment variable. The operator role must differ from the
        # runtime role above; never put its password in this file or CLI args.
        operator_dsn_env: 'LANGBOT_CLOUD_MIGRATION_DSN'
vdb:
    use: chroma
    # Bound process-local collection/index handles across all Workspaces.
    runtime_cache_limit: 1024
    qdrant:
        url: ''
        host: localhost
        port: 6333
        api_key: ''
    seekdb:
        mode: embedded  # 'embedded' or 'server'
        # Embedded mode options:
        path: './data/seekdb'
        database: 'langbot'
        # Server mode options (used when mode='server'):
        host: 'localhost'
        port: 2881
        user: 'root'
        password: ''
        tenant: ''  # Optional, for OceanBase server
    milvus:
        uri: 'http://127.0.0.1:19530'
        token: ''
        db_name: ''
    pgvector:
        # SaaS/shared-schema deployments reuse database.postgresql. OSS can
        # keep this false when deliberately using an external pgvector DB.
        use_business_database: false
        # Release migrations create one partial ANN index per enabled value.
        allowed_dimensions: [384, 512, 768, 1024, 1536]
        host: '127.0.0.1'
        port: 5433
        database: 'langbot'
        user: 'postgres'
        password: 'postgres'
    valkey_search:
        host: 'localhost'
        port: 6379            # integration tests use 6380 -> valkey/valkey-bundle:9.1.0
        db: 0
        password: ''          # optional (toB auth)
        username: ''          # optional (ACL user, toB)
        tls: false            # optional (toB/SaaS)
        index_algorithm: 'HNSW'   # HNSW | FLAT
        distance_metric: 'COSINE' # COSINE | L2 | IP
        request_timeout: 5000     # per-request timeout in ms (glide default 250ms is too low for KNN)
storage:
    use: local
    # Bound every object materialized into Core memory. Built-in Local/S3
    # providers enforce this while reading (hard cap: 64 MiB).
    max_object_read_bytes: 10485760
    cleanup:
        # Enable periodic cleanup of local/S3 uploaded files and old log files
        enabled: true
        # Cleanup check interval in hours
        check_interval_hours: 1
        # Root-level uploaded files older than this will be deleted
        uploaded_file_retention_days: 7
        # LangBot log files older than this many days will be deleted
        log_retention_days: 3
        # Bound per-Workspace file cleanup and diagnostic candidate lists.
        # Supports STORAGE__CLEANUP__MAX_FILES_PER_RUN (hard cap: 10000).
        max_files_per_run: 1000
    s3:
        endpoint_url: ''
        access_key_id: ''
        secret_access_key: ''
        region: 'us-east-1'
        bucket: 'langbot-storage'
        # boto3 is synchronous; bound the number of operations delegated to
        # worker threads so an S3 slowdown cannot saturate the process.
        max_concurrency: 16
plugin:
    enable: true
    runtime_ws_url: 'ws://langbot_plugin_runtime:5400/control/ws'
    enable_marketplace: true
    display_plugin_debug_url: 'ws://localhost:5401/plugin/debug/ws'
    worker:
        # Instance-wide maximum for every plugin installation. Plugin
        # manifests cannot raise or override these limits.
        max_cpus: 1.0
        max_memory_mb: 512
        max_pids: 128
        max_open_files: 256
        max_file_size_mb: 512
        # Instance-wide admission budgets. The effective worker count is the
        # lowest of max_workers, max_total_cpus/max_cpus and
        # max_total_memory_mb/max_memory_mb.
        max_workers: 16
        max_total_cpus: 8.0
        max_total_memory_mb: 8192
        # Includes disabled and historical installation fences retained to
        # reject stale desired-state replay.
        max_installations: 10000
        # Restart storms are globally serialized by default. Repeated
        # unexpected exits within the configured window open a Runtime-wide
        # circuit; one half-open probe must remain stable before other
        # installations may restart.
        max_concurrent_restarts: 1
        restart_failure_threshold: 8
        restart_failure_window_seconds: 30.0
        restart_circuit_open_seconds: 60.0
        # Cloud shared Runtime sets this to true and fails closed unless
        # delegated cgroup v2 controllers are available.
        require_hard_limits: false
    binary_storage:
        # Max bytes for a single plugin binary storage value
        max_value_bytes: 10485760
mcp:
    # Bound instance-wide MCP startup and shutdown bursts. Supports
    # MCP__LIFECYCLE_CONCURRENCY and is clamped to a maximum of 128.
    lifecycle_concurrency: 16
    stdio:
        # Independent gate for local stdio MCP transports. Cloud v2 sets
        # MCP__STDIO__ENABLED=false even when Box Runtime is available.
        enabled: true
monitoring:
    query_limits:
        # Maximum records materialized by one paginated monitoring request.
        # Supports MONITORING__QUERY_LIMITS__PAGE_ROWS (hard cap: 5000).
        page_rows: 1000
        # CSV exports are currently assembled in memory. Keep this lower than
        # the historical 100000-row default (hard cap: 50000).
        export_rows: 10000
        # Maximum related records returned by one session/message detail view
        # (hard cap: 10000). Aggregate statistics remain database-computed.
        detail_rows: 2000
        # Token charts are grouped in SQL and return only the newest buckets
        # (hard cap: 10000). Supports an environment variable override.
        timeseries_buckets: 1000
        # Bound high-offset scans that can otherwise monopolize PostgreSQL CPU
        # (hard cap: 10000000).
        max_offset: 1000000
    auto_cleanup:
        # Enable automatic cleanup of expired monitoring records
        enabled: true
        # Retention period in days, records older than this will be deleted
        retention_days: 30
        # Cleanup check interval in hours
        check_interval_hours: 1
        # Number of expired rows to delete per table batch
        delete_batch_size: 1000
        # Prevent one large Workspace backlog from monopolizing PostgreSQL.
        # Supports MONITORING__AUTO_CLEANUP__MAX_BATCHES_PER_TABLE_PER_RUN.
        max_batches_per_table_per_run: 4
box:
    # Master switch for the Box sandbox runtime. When false, LangBot does NOT
    # attempt to connect to a remote Box runtime nor start a local stdio Box
    # subprocess. Disabling Box also disables every feature that depends on it:
    # the native sandbox tools (exec/read/write/edit/glob/grep), the activate
    # skill tool, skill add/edit, and stdio-mode MCP servers. Skills can still
    # be listed read-only and http/sse MCP servers continue to work.
    enabled: true
    backend: 'local'  # 'local' (Docker/nsjail), 'docker', 'nsjail', or 'e2b'. Can be written via BOX__BACKEND.
    runtime:
        # LANGBOT_BOX_CONTROL_TOKEN is optional for OSS external WebSocket
        # runtimes. To protect an exposed endpoint, set the same strong secret
        # in both LangBot and Box. Keep it out of this config file.
        endpoint: ''  # External Box Runtime base URL, e.g. 'ws://127.0.0.1:5410'. Leave empty for local auto-managed runtime.
    limits:
        max_sessions: 64
        max_managed_processes: 64
        max_completed_processes: 256
        # Core scans a Workspace before and after quota-enforced executions.
        # Fail closed instead of repeatedly walking an inode bomb.
        # Supports BOX__LIMITS__MAX_WORKSPACE_ENTRIES (hard cap: 1000000).
        max_workspace_entries: 100000
        # Retained admission fences prevent replay after entitlement expiry or
        # revocation. Fail closed before that monotonic state can grow without
        # bound; Cloud may override this with BOX__LIMITS__MAX_ADMISSION_RECORDS.
        max_admission_records: 100000
        max_rpc_file_bytes: 20971520
    # Cloud v2 overrides these values through the instance config/environment.
    # OSS keeps admission disabled and preserves the existing multi-session
    # local behavior. These limits are Runtime-owned and cannot be relaxed by
    # a pipeline, Workspace entitlement, or tool call.
    admission:
        required: false
        logical_session_id: 'global'
        required_backend: 'nsjail'
        max_sessions: 1
        max_managed_processes: 0
        max_grant_ttl_sec: 300
        max_timeout_sec: 120
        cpus: 1.0
        memory_mb: 512
        pids_limit: 128
        read_only_rootfs: true
        # OSS admission-disabled mode uses 0 for unlimited compatibility.
        # Cloud bootstrap requires a positive hard quota.
        workspace_quota_mb: 0
        readiness_cache_sec: 15
    local:
        profile: 'default'
        image: ''  # Custom local sandbox image. Leave empty to use the profile default.
        host_root: './data/box'  # Base host directory for local workspace mounts. Docker deployments should override this with an absolute host path.
        default_workspace: ''  # Defaults to '<host_root>/default'. Relative paths are resolved under host_root.
        skills_root: 'skills'  # Box-owned skill package directory. Relative paths are resolved under host_root.
        allowed_mount_roots:  # Defaults to ['<host_root>'] when left empty.
            - './data/box'
            - '/tmp'
        workspace_quota_mb: null  # Optional disk quota override (>= 0). null = profile default.
    # Default nsjail cgroup memory limit for each MCP stdio server process, in MB.
    # Node.js MCP servers (npx/bunx) need more memory than Python ones because V8
    # and WebAssembly modules (e.g. undici llhttp) reserve large virtual address
    # space at startup. Setting this too low causes processes to be killed with
    # return_code=137 (OOM kill); the symptom is "Box managed process exited
    # unexpectedly" in the logs.  Raise on machines with ample RAM; lower only if
    # you run exclusively Python (uvx) MCP servers.
    # Can also be set via BOX__DEFAULT_MEMORY_MB. Default: 1536.
    default_memory_mb: 1536
    docker:
        cpu_limit_enabled: true  # When false, Docker sandbox containers are started without --cpus. Memory and PID limits still apply.
    e2b:
        api_key: ''  # Can also be set via E2B_API_KEY env var.
        api_url: ''  # Custom API URL for self-hosted deployments.
        template: ''  # Default template ID (e.g. 'base', 'python-3.11').
space:
    # Space service URL for OAuth and API
    url: 'https://space.langbot.app'
    # Space API URL for model requests (MaaS)
    models_gateway_api_url: 'https://api.langbot.cloud/v1'
    # OAuth authorization page URL (user will be redirected here)
    oauth_authorize_url: 'https://space.langbot.app/auth/authorize'
    disable_models_service: false
    disable_telemetry: false

Configuration groups

API, WebUI, and invitations

  • api.port is the HTTP API and WebUI port. api.webhook_prefix is the public base URL used to generate platform callback URLs; production deployments normally set it to the HTTPS reverse-proxy origin.
  • Set api.webui_url when the browser UI and API use different origins. OAuth redirects trust only this server-side value and webhook_prefix, never request Host or Origin headers.
  • api.global_api_key authenticates the HTTP Service API and built-in MCP server through X-API-Key or Authorization: Bearer, without a login session or a database-backed lbk_ key. Empty means disabled.
  • workspace.invitations.public_web_url controls invitation links and falls back to api.webui_url, then api.webhook_prefix. Email delivery is optional; choose resend or smtp, or leave provider empty for link-only invitations.

Warning

Treat the global API key, JWT secret, database credentials, S3 credentials, email-provider secrets, and E2B key as secrets. Prefer environment variables in production, never commit real values, and expose authenticated endpoints only over HTTPS.

Admission and capacity limits

  • concurrency bounds running and queued pipeline work globally and per Workspace.
  • webhooks bounds enabled destinations per Workspace and instance-wide outbound requests. Full request admission fails open rather than retaining an unbounded task queue.
  • cloud.directory contains operational safety ceilings for one logical Cloud instance, not subscription entitlements. Oversized authoritative directory updates are rejected atomically instead of being truncated. Most self-hosted deployments should keep these defaults.
  • system.blocking_executor, task_retention, session_retention, websocket_retention, and response_limits bound process-local workers, cached records, sockets, and upstream output.
  • Values under system.limitation are instance limits; -1 means unlimited. force_box_session_id_template is intended for SaaS sandbox confinement and should remain empty for normal self-hosting.

Databases and vector stores

  • database.use selects SQLite or PostgreSQL. A non-empty database.postgresql.url overrides the structured connection fields and preserves TLS/query options.
  • PostgreSQL pool and timeout settings bound shared runtime resources. database.cloud_migration.operator_dsn_env names the environment variable containing the operator-only migration DSN; keep that role separate from the runtime role.
  • vdb.use selects the vector backend. Configure only the selected backend. runtime_cache_limit bounds process-local collection/index handles.
  • vdb.pgvector.use_business_database reuses database.postgresql; allowed_dimensions controls the partial ANN indexes created by release migrations.
  • Valkey Search requires a Valkey server with the Search module, such as valkey/valkey-bundle:9.1.0.

Storage, plugins, MCP, and monitoring

  • storage.max_object_read_bytes caps objects materialized into Core memory. Cleanup limits bound file scans, and s3.max_concurrency bounds synchronous boto3 operations delegated to worker threads.
  • plugin.worker defines hard per-installation and instance-wide budgets. Plugin manifests cannot raise them. Restart-window settings suppress Runtime restart storms.
  • mcp.lifecycle_concurrency bounds MCP startup/shutdown bursts. mcp.stdio.enabled can disable local stdio transports without disabling HTTP/SSE MCP servers.
  • Monitoring query and cleanup limits prevent large pages, exports, offsets, or backlogs from monopolizing memory or PostgreSQL.

Box sandbox

  • box.enabled is the master switch. Disabling it also disables native sandbox tools, Skill add/edit, and stdio MCP, while read-only Skill listing and HTTP/SSE MCP remain available.
  • box.backend selects local, docker, nsjail, or e2b; runtime.endpoint connects an external WebSocket Runtime.
  • box.limits bounds sessions, processes, workspace scans, retained admission fences, and RPC file size.
  • box.admission is the Cloud v2 hard-admission policy. OSS defaults to required: false; pipelines, Workspace entitlements, and tool calls cannot relax Runtime-owned limits.
  • box.local controls workspace roots and mount allowlists. In Docker deployments, use an absolute host_root that the Box container can mount.
  • box.default_memory_mb is the default nsjail cgroup limit for each stdio MCP process. Node.js MCP servers usually need more memory than Python servers; too little commonly produces exit code 137.

LangBot Space

space.url, models_gateway_api_url, and oauth_authorize_url control Space OAuth/API and MaaS endpoints. The two disable_* flags independently disable model service use and telemetry.

Environment-variable overrides

Convert a nested key to uppercase and join levels with double underscores:

  • API__PORTapi.port
  • WORKSPACE__INVITATIONS__PUBLIC_WEB_URLworkspace.invitations.public_web_url
  • CONCURRENCY__PENDING_QUERIES_PER_WORKSPACEconcurrency.pending_queries_per_workspace
  • DATABASE__POSTGRESQL__POOL_SIZEdatabase.postgresql.pool_size
  • STORAGE__CLEANUP__MAX_FILES_PER_RUNstorage.cleanup.max_files_per_run
  • PLUGIN__WORKER__MAX_TOTAL_MEMORY_MBplugin.worker.max_total_memory_mb
  • MCP__STDIO__ENABLEDmcp.stdio.enabled
  • BOX__DEFAULT_MEMORY_MBbox.default_memory_mb

At startup, LangBot applies these overrides and writes the resulting configuration to data/config.yaml.

Note

In Docker deployments, set unified BOX__* variables on the langbot service. LangBot sends Box configuration to langbot_box through INIT RPC; variables set directly on langbot_box are not read.

LangBot Documentation

Home

简体中文
指南
开发者
API 参考
Other pages
English
Guides
Developers
API Reference
Other pages
日本語
ガイド
開発者
API リファレンス
Other pages

Clone this wiki locally