nimbus.toml Reference
Complete reference for the main Nimbus configuration file, including network, controller, API, database, cluster, and Java settings.
The main configuration file for Nimbus. Located at config/nimbus.toml inside your Nimbus installation directory. If this file does not exist on first launch, Nimbus uses built-in defaults for all options.
After editing nimbus.toml, restart Nimbus for changes to take effect. Group configs can be hot-reloaded with the reload command, but main config changes require a restart.
Environment Variables
Sensitive config values can be overridden via environment variables. Env vars take precedence over nimbus.toml.
| Environment Variable | Overrides | Description |
|---|---|---|
NIMBUS_API_TOKEN | [api] token | API bearer token |
NIMBUS_DB_TYPE | [database] type | Database type (sqlite, mysql, postgresql) |
NIMBUS_DB_HOST | [database] host | Database hostname |
NIMBUS_DB_PORT | [database] port | Database port |
NIMBUS_DB_NAME | [database] name | Database name |
NIMBUS_DB_USERNAME | [database] username | Database username |
NIMBUS_DB_PASSWORD | [database] password | Database password |
NIMBUS_CLUSTER_TOKEN | [cluster] token | Cluster authentication token |
NIMBUS_CLUSTER_KEYSTORE_PASSWORD | [cluster] keystore_password | TLS keystore password |
NIMBUS_LOG_FORMAT | — | Set to json to emit structured JSON logs (one object per line, via logstash-logback-encoder). Default plain-text. Added in v0.12.0. |
Agent env vars: NIMBUS_AGENT_TOKEN, NIMBUS_AGENT_CONTROLLER (see agent docs).
Complete Example
[network]
name = "Nimbus"
bind = "0.0.0.0"
[controller]
max_memory = "10G"
max_services = 20
heartbeat_interval = 5000
scaling_tick_interval = 10
service_stale_timeout = 300
strict_config = false
[console]
colored = true
log_events = true
history_file = ".nimbus_history"
[paths]
templates = "templates"
services = "services"
dedicated = "dedicated"
logs = "logs"
[api]
enabled = true
bind = "127.0.0.1"
port = 8080
token = ""
allowed_origins = ["https://dashboard.nimbuspowered.org", "http://localhost:3000"]
[database]
type = "sqlite"
host = "localhost"
port = 3306
name = "nimbus"
username = ""
password = ""
[loadbalancer]
enabled = false
bind = "0.0.0.0"
port = 25565
strategy = "least-players"
proxy_protocol = false
connection_timeout = 5000
buffer_size = 16384
max_connections = 10000
idle_timeout = 30000
health_check_interval = 10
health_check_timeout = 3000
unhealthy_threshold = 3
healthy_threshold = 2
[permissions]
deploy_plugin = true
[bedrock]
enabled = false
base_port = 19132
[cluster]
enabled = false
token = ""
agent_port = 8443
bind = "0.0.0.0"
heartbeat_interval = 5000
node_timeout = 15000
placement_strategy = "least-services"
[audit]
enabled = true
retention_days = 90
[metrics]
retention_days = 30
[java]
java_16 = ""
java_17 = ""
java_21 = ""
[curseforge]
api_key = ""[network]
Network identity and bind settings.
| Option | Type | Default | Description |
|---|---|---|---|
name | String | "Nimbus" | Display name for the network. Used in logging and API responses. |
bind | String | "0.0.0.0" | Default bind address for all managed servers. Use 0.0.0.0 to listen on all interfaces, or a specific IP to restrict. |
[network]
name = "MyNetwork"
bind = "0.0.0.0"[controller]
Resource limits and scaling engine settings.
| Option | Type | Default | Description |
|---|---|---|---|
max_memory | String | "10G" | Total memory budget for all running services. Format: number + M or G (e.g., "512M", "8G"). Validated on startup — Nimbus will not start if the format is invalid. Nimbus will not start new services if the total allocated memory would exceed this limit. |
max_services | Int | 20 | Maximum number of concurrent services across all groups. Enforced as a global hard cap by the scaling engine — no new instances are started once this limit is reached, regardless of per-group max_instances settings. Also enforced by the warm pool manager. |
heartbeat_interval | Long | 5000 | Interval in milliseconds between scaling engine evaluation cycles. Each cycle checks player counts and applies scaling rules. |
scaling_tick_interval | Long | 10 | Interval in seconds between scaling engine evaluation ticks. Lower values (e.g., 5) make scaling more responsive for fast-paced game modes. Higher values reduce CPU overhead on large clusters. |
service_stale_timeout | Long | 300 | Seconds a service can remain READY without any heartbeat or API activity before being flagged as stale. 0 disables the check. Stale services are surfaced by the doctor command and the health API. |
strict_config | Boolean | false | When true, unknown keys in controller-owned TOML configs (nimbus.toml, groups/*.toml, dedicated/*.toml, config/modules/syncproxy/*.toml, config/modules/auth/auth.toml, config/modules/docker/docker.toml) cause a fatal startup error instead of a warning. Defaults to false in 0.13 (warn-only — each unknown key logs one WARN line naming the key and scope). Will default to true in Nimbus 1.0. User-editable message templates (auth-messages.toml, punishments/messages.toml) stay lenient regardless of this flag to keep forward-compat with future placeholder keys. |
[controller]
max_memory = "16G"
max_services = 50
heartbeat_interval = 3000Setting heartbeat_interval too low (below 1000ms) may cause excessive server list pings. The default of 5000ms is suitable for most setups.
[console]
Interactive console appearance and behavior.
| Option | Type | Default | Description |
|---|---|---|---|
colored | Boolean | true | Enable ANSI colored output in the console. Disable if your terminal doesn't support color codes. |
log_events | Boolean | true | Log internal events (service start/stop, scaling decisions) to the console. |
history_file | String | ".nimbus_history" | File path for command history persistence. Supports up-arrow recall between sessions. Relative to the Nimbus root directory. |
[console]
colored = true
log_events = true
history_file = ".nimbus_history"[paths]
Directory paths for templates, running services, and logs. All paths are relative to the Nimbus root directory unless an absolute path is specified.
| Option | Type | Default | Description |
|---|---|---|---|
templates | String | "templates" | Directory containing server templates. Each group references a template by name (subdirectory). |
services | String | "services" | Directory where running service instances are created. Each service gets its own subdirectory (e.g., services/Lobby-1/). |
dedicated | String | "dedicated" | Base directory for dedicated service working directories. Each dedicated service gets its own subdirectory (e.g., dedicated/sandbox/). |
logs | String | "logs" | Directory for Nimbus log files. |
[paths]
templates = "templates"
services = "services"
dedicated = "dedicated"
logs = "logs"Dynamic services have their working directories recreated from the template on every start. Static services preserve their directories across restarts — see Templates for details.
[api]
REST API and WebSocket server configuration.
| Option | Type | Default | Description |
|---|---|---|---|
enabled | Boolean | true | Enable the HTTP API server. Required for the bridge plugin and SDK to communicate with Nimbus. |
bind | String | "127.0.0.1" | Bind address for the API server. Use 127.0.0.1 for local-only access (recommended) or 0.0.0.0 for remote access. |
port | Int | 8080 | Port for the API server. |
token | String | "" | Bearer token for API authentication. If empty, Nimbus auto-generates a random token on every start and logs it to the console. Set a permanent token for production. |
allowed_origins | List<String> | ["https://dashboard.nimbuspowered.org", "http://localhost:3000"] | CORS allowed origins. The hosted dashboard and local dev server (http://localhost:3000) are included by default. Empty list allows all origins (with a warning). Hostnames without scheme are accepted too — both http and https variants are allowed automatically. |
trust_forwarded_for | Boolean | false | Trust X-Forwarded-For header for rate limiting. Enable when running behind a reverse proxy (Nginx, Traefik, Cloudflare) so rate limits apply to real client IPs instead of the proxy address. Leave disabled unless you control the proxy — spoofable otherwise. |
jwt_enabled | Boolean | false | Enable JWT scoped token generation. When enabled, the POST /api/tokens endpoint becomes available for generating scoped JWT tokens with fine-grained permissions. Legacy bearer tokens always work regardless of this setting. |
[api]
enabled = true
bind = "127.0.0.1"
port = 8080
token = "my-secret-token"
allowed_origins = ["dashboard.nimbuspowered.org", "localhost:3000"]The API token grants full control over your Nimbus instance. Keep it secret. If you expose the API beyond localhost, always use a strong token and consider placing it behind a reverse proxy with TLS.
Service token
Nimbus automatically derives a restricted service token from the admin token. Game servers receive this service token (via NIMBUS_API_TOKEN env var) and can only access service-level endpoints. The Velocity proxy receives the full admin token for bridge plugin access. This limits the blast radius if a game server plugin is compromised.
File permissions
nimbus.toml is automatically created with restricted file permissions (600 / owner-only) on Linux/macOS, since it contains the API token and database credentials.
The /api/health endpoint is always public (no authentication required) and can be used for external health checks. All other endpoints, including /api/metrics, require authentication.
Rate limiting
The API enforces per-IP rate limits: 120 requests/minute globally, 5 requests/minute for stress test endpoints.
[database]
Database backend configuration for permissions and cloud metrics.
| Option | Type | Default | Description |
|---|---|---|---|
type | String | "sqlite" | Database type. Supported values: sqlite, mysql, mariadb, postgresql, postgres. |
host | String | "localhost" | Database server hostname. Only used for MySQL and PostgreSQL. |
port | Int | 3306 | Database server port. Must be between 1 and 65535. Only used for MySQL and PostgreSQL. Automatically defaults to 5432 for PostgreSQL if set to 3306. |
name | String | "nimbus" | Database name. Only used for MySQL and PostgreSQL. For MySQL, the database is auto-created if it doesn't exist. |
username | String | "" | Database username. Only used for MySQL and PostgreSQL. |
password | String | "" | Database password. Only used for MySQL and PostgreSQL. |
pool_size | Int | 10 | HikariCP connection pool maximum size. Only used for MySQL and PostgreSQL. Increase for large deployments with many concurrent scaling events. |
SQLite (default)
[database]
type = "sqlite"No additional configuration needed. The database file is stored at data/nimbus.db inside your Nimbus directory.
MySQL / MariaDB
[database]
type = "mysql"
host = "localhost"
port = 3306
name = "nimbus"
username = "nimbus"
password = "secret"SSL
MySQL connections use SSL by default (useSSL=true). Ensure your MySQL server has SSL enabled, or use SQLite/PostgreSQL instead.
PostgreSQL
[database]
type = "postgresql"
host = "localhost"
port = 5432
name = "nimbus"
username = "nimbus"
password = "secret"SSL
PostgreSQL connections require SSL by default (sslmode=require). Ensure your PostgreSQL server has SSL enabled.
SQLite is recommended for single-node setups. Use MySQL or PostgreSQL if you need shared database access across multiple machines or want external tooling for querying metrics.
The database stores permission groups, player assignments, and cloud metrics (service events, scaling events, player sessions). All tables are created automatically on first launch.
[loadbalancer]
TCP load balancer configuration. When enabled, Nimbus binds a Layer-4 TCP proxy on the configured port and distributes incoming connections across all running Velocity proxy instances.
The load balancer is disabled by default. Single-node setups do not need it. Enable it when running multiple Velocity proxy instances (e.g., for redundancy or multi-node setups).
| Option | Type | Default | Description |
|---|---|---|---|
enabled | Boolean | false | Enable the TCP load balancer. When enabled, player connections arrive at the LB port and are forwarded to a backend Velocity proxy. |
bind | String | "0.0.0.0" | Bind address for the load balancer listener. |
port | Int | 25565 | Port to listen on. Typically 25565 (the Minecraft default) so players connect directly to the LB. |
strategy | String | "least-players" | Backend selection strategy. "least-players" routes to the proxy with the fewest players; "round-robin" distributes evenly. |
proxy_protocol | Boolean | false | Send HAProxy PROXY protocol v2 headers to backend Velocity instances, preserving real client IPs. Velocity must have haproxy-protocol = true in its config. |
connection_timeout | Int | 5000 | Timeout in milliseconds for connecting to a backend proxy. |
buffer_size | Int | 16384 | TCP relay buffer size in bytes. |
max_connections | Int | 10000 | Maximum number of simultaneous connections. Connections beyond this limit are rejected immediately. |
idle_timeout | Int | 30000 | Idle timeout in milliseconds. Connections with no traffic in either direction for this duration are closed. Prevents half-open TCP connections from lingering. |
health_check_interval | Int | 10 | Interval in seconds between health checks for each backend proxy. Uses Minecraft Server List Ping to verify the backend is responsive. |
health_check_timeout | Int | 3000 | Timeout in milliseconds for each health check ping. |
unhealthy_threshold | Int | 3 | Number of consecutive health check failures before a backend is marked UNHEALTHY and removed from rotation. |
healthy_threshold | Int | 2 | Number of consecutive health check successes before an UNHEALTHY backend is restored to HEALTHY. |
[loadbalancer]
enabled = true
bind = "0.0.0.0"
port = 25565
strategy = "least-players"
proxy_protocol = true
max_connections = 10000
health_check_interval = 10
unhealthy_threshold = 3Health Checks
When the load balancer is running, it periodically pings each backend Velocity proxy using the Minecraft Server List Ping protocol. This verifies that the proxy is actually responding to game traffic, not just accepting TCP connections.
- A backend that fails
unhealthy_thresholdconsecutive checks is marked UNHEALTHY and removed from the rotation — no new connections are routed to it. - Once it passes
healthy_thresholdconsecutive checks again, it is restored to HEALTHY. - If all backends are unhealthy (e.g., during a transient network blip), the LB falls back to trying any
READYbackend to avoid a total outage. - When a Velocity service is being stopped, the LB automatically marks it as DRAINING — existing connections continue but no new ones are routed there.
When the load balancer is enabled, Velocity proxies are allocated backend ports (30000+) instead of 25565. The LB owns port 25565. Make sure your firewall allows connections to the LB port.
[permissions]
Controls deployment of the NimbusPerms plugin to backend servers. This section is read by the Permissions module at startup.
| Option | Type | Default | Description |
|---|---|---|---|
deploy_plugin | Boolean | true | Deploy the NimbusPerms plugin to all backend servers. Disable if you prefer to manage permissions with LuckPerms or another system. |
[permissions]
deploy_plugin = trueEven with deploy_plugin = false, the permission system on the controller (groups, players, API, console commands) remains fully functional. This setting only controls whether the NimbusPerms plugin is auto-deployed to new service instances. To fully disable the permission system, uninstall the module with modules uninstall perms.
[punishments]
Controls the Punishments module (ban/mute/kick/warn enforcement). See the Punishments guide.
| Option | Type | Default | Description |
|---|---|---|---|
deploy_plugin | Boolean | true | Deploy the nimbus-punishments.jar (Velocity) and nimbus-punishments-backend.jar (Paper-family) enforcement plugins at runtime on every service prepare. |
check_cache_ttl | Int | 5 | Ban/mute check cache TTL in seconds. Higher = less DB load, slower revoke propagation. |
expiry_check_interval | Int | 30 | How often the expiry loop runs (seconds). Deactivates TEMPBANs / TEMPMUTEs that have passed their expiresAt. |
[punishments]
deploy_plugin = true
check_cache_ttl = 5
expiry_check_interval = 30Even with deploy_plugin = false, the REST API, console punish command, and database records remain fully functional — only automatic enforcement on proxies and backends is skipped. Use this if you want to integrate with a different ban plugin but still keep Nimbus as the system of record.
[resourcepacks]
Controls the Resource Packs module. See the Resource Packs guide.
| Option | Type | Default | Description |
|---|---|---|---|
deploy_plugin | Boolean | true | Deploy the nimbus-resourcepacks.jar applier plugin at runtime on every backend service prepare. |
max_upload_bytes | Long | 262144000 (250 MB) | Maximum size for uploaded pack .zip files. Enforced by both the REST API and the console resourcepack upload command. |
public_base_url | String | "" | Public URL base the backend plugin should use to fetch locally-hosted packs. Leave empty to derive from the API bind. Override when the controller sits behind a reverse proxy with a different hostname than backends can reach. |
[resourcepacks]
deploy_plugin = true
max_upload_bytes = 524288000 # 500 MB
public_base_url = "https://packs.example.com"[bedrock]
Bedrock Edition crossplay support via Geyser + Floodgate. When enabled, Bedrock Edition players (mobile, console, Windows 10/11) can join your Java Edition network.
Bedrock support is disabled by default. When enabled, Nimbus automatically downloads Geyser and Floodgate from the GeyserMC API and deploys them to the appropriate templates.
| Option | Type | Default | Description |
|---|---|---|---|
enabled | Boolean | false | Enable Bedrock Edition support. Nimbus auto-deploys Geyser (Velocity plugin) and Floodgate (Velocity + backend plugin). |
base_port | Int | 19132 | Starting UDP port for Bedrock connections. Must be between 1 and 65535. Each proxy instance gets its own port, incrementing from this value (19132, 19133, ...). |
[bedrock]
enabled = true
base_port = 19132How it works
When Bedrock support is enabled, Nimbus:
- Downloads Geyser (Velocity plugin) — Translates Bedrock protocol to Java protocol inside the proxy
- Downloads Floodgate (Velocity + Paper plugin) — Allows Bedrock players to authenticate via Xbox Live without a Java account
- Manages
key.pem— Floodgate's encryption key is generated once and distributed to all proxy and backend instances automatically - Configures Geyser — Each proxy instance gets a unique Bedrock UDP port and auto-generated Geyser config with MOTD, player count, and server icon passthrough enabled
- Allocates UDP ports — Separate from TCP ports, starting at
base_port
Architecture
Bedrock (UDP:19132) ──► Velocity + Geyser + Floodgate ──► Backends + Floodgate
Java (TCP:25565) ──► ──►After Geyser translates the connection, backends see all players as normal Java players. No backend configuration changes are needed.
Plugin deployment
| Plugin | Deployed To | Purpose |
|---|---|---|
| Geyser | Proxy (Velocity) | Bedrock → Java protocol translation |
| Floodgate | Proxy + all Paper/Purpur/Leaf/Folia backends | Xbox Live authentication, Bedrock player identification |
| key.pem | Proxy + all backends | Shared encryption key for Floodgate auth verification |
Floodgate is deployed to Paper/Purpur/Leaf/Folia backends only. Modded servers (Fabric, Forge, NeoForge) do not receive Floodgate automatically — Bedrock players can still connect through the proxy, but backend plugins won't be able to identify them as Bedrock players.
Bedrock player names are prefixed with . by default (e.g., .BedrockPlayer123) to avoid name collisions with Java players. This is configured in Floodgate's settings.
[cluster]
Multi-node cluster configuration. When enabled, Nimbus acts as a controller that accepts connections from remote agent nodes. Agents run services on behalf of the controller, allowing you to distribute Minecraft servers across multiple machines.
Cluster mode is disabled by default. Single-node setups do not need it. All features are gated behind enabled = true and existing single-node installations are completely unaffected.
| Option | Type | Default | Description |
|---|---|---|---|
enabled | Boolean | false | Enable cluster mode. When enabled, Nimbus accepts agent WebSocket connections and can place services on remote nodes. |
token | String | "" | Shared secret token for authenticating agents. Agents must present this token when connecting. |
agent_port | Int | 8443 | WebSocket port for agent connections. Agents connect to this port on the controller. |
bind | String | "0.0.0.0" | Bind address for the cluster WebSocket endpoint (served via the existing API server). |
heartbeat_interval | Long | 5000 | Interval in milliseconds between heartbeat requests sent to agents. |
node_timeout | Long | 15000 | Time in milliseconds after which a node is considered disconnected if no heartbeat response is received. |
placement_strategy | String | "least-services" | Strategy for placing new services on nodes. "least-services" places on the node running the fewest services; "least-memory" uses the node with the most free memory. |
tls_enabled | Boolean | true | Enable TLS encryption for cluster WebSocket connections. When enabled without a keystore, Nimbus auto-generates a self-signed certificate. |
keystore_path | String | "" | Path to a JKS/PKCS12 keystore for TLS. If empty and tls_enabled = true, a self-signed keystore is auto-generated at config/cluster.jks. |
keystore_password | String | "" | Keystore password. If empty during auto-generation, a cryptographically random password is generated. Set explicitly or override via NIMBUS_CLUSTER_KEYSTORE_PASSWORD env var. |
extra_sans | List<String> | [] | Additional SANs (hostnames or IPs) baked into the auto-generated TLS cert. Strings matching N.N.N.N are added as IP SANs, everything else as DNS SANs. Only applied when the keystore is generated — to change SANs after the fact, run cluster cert regenerate and restart. |
public_host | String | "" | Hostname or IP returned in the wsUrl of the /api/cluster/bootstrap response. Defaults to the bind address (when not 0.0.0.0) or the local hostname. Set this if the controller is behind NAT or has multiple interfaces. |
sync_disk_quota_bytes | Long | 0 | Maximum total size in bytes that state-sync canonical copies may occupy (under services/state/ + any dedicated service roots). 0 = unlimited. Pushes that would exceed this limit are rejected with HTTP 507 Insufficient Storage. Example: sync_disk_quota_bytes = 10737418240 for a 10 GB cap. |
reconciliation_delay | Long | 10000 | Milliseconds to wait for agent reconnections before starting services. During this window, agents report recovered services. Only after the delay does startMinimumInstances() run, preventing duplicate service starts. |
[cluster]
enabled = true
token = "my-cluster-secret"
agent_port = 8443
tls_enabled = true
# keystore_path = "" # Auto-generated if empty
# keystore_password = "" # Auto-generated if empty
heartbeat_interval = 5000
node_timeout = 15000
placement_strategy = "least-services"The cluster token grants remote nodes the ability to run services on behalf of the controller. Use a strong, randomly generated token and keep it secret.
You can manage all cluster and load balancer settings from the console using the cluster command instead of editing this file manually. See Commands Reference — cluster. For the TLS trust model, fingerprint pinning, and cert rotation flow, see Cluster TLS & Security.
[audit]
Audit logging records administrative actions for compliance and debugging.
| Option | Type | Default | Description |
|---|---|---|---|
enabled | Boolean | true | Enable audit logging. Events are stored in the database. |
retention_days | Long | 90 | Days to retain audit entries before auto-pruning. |
[audit]
enabled = true
retention_days = 90Recorded events: service lifecycle (start/stop/crash), scaling decisions, group changes, maintenance toggles, config reloads, module lifecycle, API start/stop. Each entry includes timestamp, actor, action, target, and details. Query via audit console command or GET /api/audit.
[metrics]
Retention policy for time-series metrics collected by MetricsCollector (player counts, service events, scaling decisions).
| Option | Type | Default | Description |
|---|---|---|---|
retention_days | Long | 30 | Days to retain metrics rows before auto-pruning. Lower values reduce database growth on high-traffic networks. |
[metrics]
retention_days = 30Metrics are exposed via GET /api/metrics (Prometheus format). See API Reference for scrape configuration.
[java]
Java installation paths for different versions. Nimbus uses these to launch servers that require specific Java versions.
If a path is empty, Nimbus will auto-detect installed JDKs by scanning environment variables (JAVA_16_HOME, JAVA_17_HOME, etc.), JAVA_HOME, and common directories (/usr/lib/jvm, ~/.sdkman/candidates/java, ~/.jdks). If no compatible JDK is found, Nimbus downloads one from Adoptium automatically and caches it in the jdks/ directory.
| Option | Type | Default | Description |
|---|---|---|---|
java_16 | String | "" | Path to Java 16 binary. For Minecraft 1.8.x - 1.17.x (minimum supported runtime). |
java_17 | String | "" | Path to Java 17 binary. For Minecraft 1.18.x - 1.20.4. |
java_21 | String | "" | Path to Java 21 binary. For Minecraft 1.20.5+ and Velocity. Auto-detected if available on PATH. |
[java]
java_16 = "/usr/lib/jvm/java-16-openjdk/bin/java"
java_17 = "/usr/lib/jvm/java-17-openjdk/bin/java"
java_21 = "/usr/lib/jvm/java-21-openjdk/bin/java"Resolution order
When starting a server, Nimbus resolves the Java executable in this order:
- Per-group
java_pathoverride (from the group config) - Configured paths from this
[java]section - Auto-detected installations on the system
- Auto-downloaded JDK from Adoptium (cached in
jdks/)
You can leave all [java] paths empty. Nimbus will find or download what it needs. Only set explicit paths if you want to pin a specific JDK distribution (e.g., GraalVM instead of Temurin).
For a detailed explanation of Java version requirements per Minecraft version, see Automatic JDK Management.
[curseforge]
CurseForge API configuration for modpack imports. Only needed if you import modpacks from CurseForge.
| Option | Type | Default | Description |
|---|---|---|---|
api_key | String | "" | CurseForge API key for fetching modpack metadata and files. Required for import curseforge: commands and CurseForge URL imports. Get one at console.curseforge.com. Server pack ZIP uploads work without an API key. |
[curseforge]
api_key = "your-curseforge-api-key"[sandbox]
Global defaults for the managed sandbox: a thin wrapper that spawns each service inside its own cgroup v2 scope via systemd-run --user --scope so memory and CPU limits are enforced by the kernel instead of only by -Xmx. Introduced in v0.12.0. Per-group overrides live under [group.sandbox] in the group TOML — see Groups.
| Option | Type | Default | Description |
|---|---|---|---|
default_mode | String | "auto" | Default sandbox backend for groups that don't set their own [group.sandbox] mode. Values: "auto" (managed on Linux with systemd-run reachable, otherwise bare), "managed", "bare". |
memory_overhead_percent | Int | 30 | JVM native-memory overhead budget added on top of [group.resources] memory when auto-deriving the hard memory cap. |
memory_overhead_min_mb | Long | 256 | Absolute floor for the overhead budget — keeps small-heap services from being OOM-killed by a too-tight cap. |
[sandbox]
default_mode = "auto" # or "managed" / "bare"
memory_overhead_percent = 30
memory_overhead_min_mb = 256On Linux with a reachable user systemd bus, managed mode is selected automatically. Verify after upgrade with systemctl --user list-units | grep nimbus- — you should see a *.scope unit per running service. Docker-backed services ([group.docker] enabled = true) are unaffected and keep using the Docker module's own cgroup enforcement.
No separate "disable" knob — set default_mode = "bare" to opt out globally, or use [group.sandbox] mode = "bare" per group. WSL1, macOS, and hosts without user-level systemd automatically fall back to bare with a single INFO log at startup.