Nimbusv1.0.0

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 VariableOverridesDescription
NIMBUS_API_TOKEN[api] tokenAPI bearer token
NIMBUS_DB_TYPE[database] typeDatabase type (sqlite, mysql, postgresql)
NIMBUS_DB_HOST[database] hostDatabase hostname
NIMBUS_DB_PORT[database] portDatabase port
NIMBUS_DB_NAME[database] nameDatabase name
NIMBUS_DB_USERNAME[database] usernameDatabase username
NIMBUS_DB_PASSWORD[database] passwordDatabase password
NIMBUS_CLUSTER_TOKEN[cluster] tokenCluster authentication token
NIMBUS_CLUSTER_KEYSTORE_PASSWORD[cluster] keystore_passwordTLS keystore password
NIMBUS_LOG_FORMATSet 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

config/nimbus.toml
[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.

OptionTypeDefaultDescription
nameString"Nimbus"Display name for the network. Used in logging and API responses.
bindString"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.
config/nimbus.toml
[network]
name = "MyNetwork"
bind = "0.0.0.0"

[controller]

Resource limits and scaling engine settings.

OptionTypeDefaultDescription
max_memoryString"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_servicesInt20Maximum 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_intervalLong5000Interval in milliseconds between scaling engine evaluation cycles. Each cycle checks player counts and applies scaling rules.
scaling_tick_intervalLong10Interval 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_timeoutLong300Seconds 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_configBooleanfalseWhen 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.
config/nimbus.toml
[controller]
max_memory = "16G"
max_services = 50
heartbeat_interval = 3000

Setting 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.

OptionTypeDefaultDescription
coloredBooleantrueEnable ANSI colored output in the console. Disable if your terminal doesn't support color codes.
log_eventsBooleantrueLog internal events (service start/stop, scaling decisions) to the console.
history_fileString".nimbus_history"File path for command history persistence. Supports up-arrow recall between sessions. Relative to the Nimbus root directory.
config/nimbus.toml
[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.

OptionTypeDefaultDescription
templatesString"templates"Directory containing server templates. Each group references a template by name (subdirectory).
servicesString"services"Directory where running service instances are created. Each service gets its own subdirectory (e.g., services/Lobby-1/).
dedicatedString"dedicated"Base directory for dedicated service working directories. Each dedicated service gets its own subdirectory (e.g., dedicated/sandbox/).
logsString"logs"Directory for Nimbus log files.
config/nimbus.toml
[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.

OptionTypeDefaultDescription
enabledBooleantrueEnable the HTTP API server. Required for the bridge plugin and SDK to communicate with Nimbus.
bindString"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.
portInt8080Port for the API server.
tokenString""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_originsList<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_forBooleanfalseTrust 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_enabledBooleanfalseEnable 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.
config/nimbus.toml
[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.

OptionTypeDefaultDescription
typeString"sqlite"Database type. Supported values: sqlite, mysql, mariadb, postgresql, postgres.
hostString"localhost"Database server hostname. Only used for MySQL and PostgreSQL.
portInt3306Database server port. Must be between 1 and 65535. Only used for MySQL and PostgreSQL. Automatically defaults to 5432 for PostgreSQL if set to 3306.
nameString"nimbus"Database name. Only used for MySQL and PostgreSQL. For MySQL, the database is auto-created if it doesn't exist.
usernameString""Database username. Only used for MySQL and PostgreSQL.
passwordString""Database password. Only used for MySQL and PostgreSQL.
pool_sizeInt10HikariCP connection pool maximum size. Only used for MySQL and PostgreSQL. Increase for large deployments with many concurrent scaling events.

SQLite (default)

config/nimbus.toml
[database]
type = "sqlite"

No additional configuration needed. The database file is stored at data/nimbus.db inside your Nimbus directory.

MySQL / MariaDB

config/nimbus.toml
[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

config/nimbus.toml
[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).

OptionTypeDefaultDescription
enabledBooleanfalseEnable the TCP load balancer. When enabled, player connections arrive at the LB port and are forwarded to a backend Velocity proxy.
bindString"0.0.0.0"Bind address for the load balancer listener.
portInt25565Port to listen on. Typically 25565 (the Minecraft default) so players connect directly to the LB.
strategyString"least-players"Backend selection strategy. "least-players" routes to the proxy with the fewest players; "round-robin" distributes evenly.
proxy_protocolBooleanfalseSend HAProxy PROXY protocol v2 headers to backend Velocity instances, preserving real client IPs. Velocity must have haproxy-protocol = true in its config.
connection_timeoutInt5000Timeout in milliseconds for connecting to a backend proxy.
buffer_sizeInt16384TCP relay buffer size in bytes.
max_connectionsInt10000Maximum number of simultaneous connections. Connections beyond this limit are rejected immediately.
idle_timeoutInt30000Idle timeout in milliseconds. Connections with no traffic in either direction for this duration are closed. Prevents half-open TCP connections from lingering.
health_check_intervalInt10Interval in seconds between health checks for each backend proxy. Uses Minecraft Server List Ping to verify the backend is responsive.
health_check_timeoutInt3000Timeout in milliseconds for each health check ping.
unhealthy_thresholdInt3Number of consecutive health check failures before a backend is marked UNHEALTHY and removed from rotation.
healthy_thresholdInt2Number of consecutive health check successes before an UNHEALTHY backend is restored to HEALTHY.
config/nimbus.toml
[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 = 3

Health 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_threshold consecutive checks is marked UNHEALTHY and removed from the rotation — no new connections are routed to it.
  • Once it passes healthy_threshold consecutive 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 READY backend 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.

OptionTypeDefaultDescription
deploy_pluginBooleantrueDeploy the NimbusPerms plugin to all backend servers. Disable if you prefer to manage permissions with LuckPerms or another system.
config/nimbus.toml
[permissions]
deploy_plugin = true

Even 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.

OptionTypeDefaultDescription
deploy_pluginBooleantrueDeploy the nimbus-punishments.jar (Velocity) and nimbus-punishments-backend.jar (Paper-family) enforcement plugins at runtime on every service prepare.
check_cache_ttlInt5Ban/mute check cache TTL in seconds. Higher = less DB load, slower revoke propagation.
expiry_check_intervalInt30How often the expiry loop runs (seconds). Deactivates TEMPBANs / TEMPMUTEs that have passed their expiresAt.
config/nimbus.toml
[punishments]
deploy_plugin = true
check_cache_ttl = 5
expiry_check_interval = 30

Even 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.

OptionTypeDefaultDescription
deploy_pluginBooleantrueDeploy the nimbus-resourcepacks.jar applier plugin at runtime on every backend service prepare.
max_upload_bytesLong262144000 (250 MB)Maximum size for uploaded pack .zip files. Enforced by both the REST API and the console resourcepack upload command.
public_base_urlString""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.
config/nimbus.toml
[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.

OptionTypeDefaultDescription
enabledBooleanfalseEnable Bedrock Edition support. Nimbus auto-deploys Geyser (Velocity plugin) and Floodgate (Velocity + backend plugin).
base_portInt19132Starting UDP port for Bedrock connections. Must be between 1 and 65535. Each proxy instance gets its own port, incrementing from this value (19132, 19133, ...).
config/nimbus.toml
[bedrock]
enabled = true
base_port = 19132

How it works

When Bedrock support is enabled, Nimbus:

  1. Downloads Geyser (Velocity plugin) — Translates Bedrock protocol to Java protocol inside the proxy
  2. Downloads Floodgate (Velocity + Paper plugin) — Allows Bedrock players to authenticate via Xbox Live without a Java account
  3. Manages key.pem — Floodgate's encryption key is generated once and distributed to all proxy and backend instances automatically
  4. 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
  5. Allocates UDP ports — Separate from TCP ports, starting at base_port

Architecture

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

PluginDeployed ToPurpose
GeyserProxy (Velocity)Bedrock → Java protocol translation
FloodgateProxy + all Paper/Purpur/Leaf/Folia backendsXbox Live authentication, Bedrock player identification
key.pemProxy + all backendsShared 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.

OptionTypeDefaultDescription
enabledBooleanfalseEnable cluster mode. When enabled, Nimbus accepts agent WebSocket connections and can place services on remote nodes.
tokenString""Shared secret token for authenticating agents. Agents must present this token when connecting.
agent_portInt8443WebSocket port for agent connections. Agents connect to this port on the controller.
bindString"0.0.0.0"Bind address for the cluster WebSocket endpoint (served via the existing API server).
heartbeat_intervalLong5000Interval in milliseconds between heartbeat requests sent to agents.
node_timeoutLong15000Time in milliseconds after which a node is considered disconnected if no heartbeat response is received.
placement_strategyString"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_enabledBooleantrueEnable TLS encryption for cluster WebSocket connections. When enabled without a keystore, Nimbus auto-generates a self-signed certificate.
keystore_pathString""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_passwordString""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_sansList<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_hostString""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_bytesLong0Maximum 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_delayLong10000Milliseconds 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.
config/nimbus.toml
[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.

OptionTypeDefaultDescription
enabledBooleantrueEnable audit logging. Events are stored in the database.
retention_daysLong90Days to retain audit entries before auto-pruning.
config/nimbus.toml
[audit]
enabled = true
retention_days = 90

Recorded 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).

OptionTypeDefaultDescription
retention_daysLong30Days to retain metrics rows before auto-pruning. Lower values reduce database growth on high-traffic networks.
config/nimbus.toml
[metrics]
retention_days = 30

Metrics 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.

OptionTypeDefaultDescription
java_16String""Path to Java 16 binary. For Minecraft 1.8.x - 1.17.x (minimum supported runtime).
java_17String""Path to Java 17 binary. For Minecraft 1.18.x - 1.20.4.
java_21String""Path to Java 21 binary. For Minecraft 1.20.5+ and Velocity. Auto-detected if available on PATH.
config/nimbus.toml
[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:

  1. Per-group java_path override (from the group config)
  2. Configured paths from this [java] section
  3. Auto-detected installations on the system
  4. 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.

OptionTypeDefaultDescription
api_keyString""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.
config/nimbus.toml
[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.

OptionTypeDefaultDescription
default_modeString"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_percentInt30JVM native-memory overhead budget added on top of [group.resources] memory when auto-deriving the hard memory cap.
memory_overhead_min_mbLong256Absolute floor for the overhead budget — keeps small-heap services from being OOM-killed by a too-tight cap.
config/nimbus.toml
[sandbox]
default_mode = "auto"            # or "managed" / "bare"
memory_overhead_percent = 30
memory_overhead_min_mb = 256

On 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.