Deployment Modes

bext supports three deployment modes that cover everything from a single side project to a globally distributed fleet. Each mode uses the same binary -- only the configuration changes.

Single-App Mode (Default)

The simplest way to run bext. Point it at a directory containing your framework app and it handles the rest: detection, build, and serving.

bext run .

bext reads bext.config.toml from the project root. A minimal config is all you need:

[server]
listen = "0.0.0.0:3061"
static_dir = "./dist/static"

[cache.isr]
default_ttl_ms = 60000
default_swr_ms = 3600000

Single-app mode is the right choice when you are deploying one application per server or container. It is also what bext dev uses during development. The entire request lifecycle -- TLS termination, compression, SSR, caching -- happens inside the single process with zero inter-process overhead.

When to use: solo projects, microservices behind a load balancer, Docker/Kubernetes pods where each replica runs one app.

Multi-App Mode (Virtual Hosts)

When you need to serve multiple applications from one bext instance, switch to multi-app mode. Define each app in the [apps] table of a platform.toml file and start with bext serve:

bext serve --config platform.toml
[platform]
listen = "0.0.0.0:443"
data_dir = "/var/lib/bext"
max_apps = 50

[apps.marketing]
source = "/srv/marketing"
domains = ["example.com", "www.example.com"]
runtime = "nextjs"

[apps.marketing.cache]
default_ttl = "60s"
max_entries = 10000

[apps.blog]
source = "/srv/blog"
domains = ["blog.example.com"]
runtime = "hono"

[apps.blog.cache]
default_ttl = "300s"

[apps.api]
source = "/srv/api"
domains = ["api.example.com"]
runtime = "express"

bext routes incoming requests by matching the Host header against each app's domains list using a trie-based virtual host router. Each app gets its own ISR cache namespace, rate limiter, worker pool, and optional per-app plugin configuration.

Per-app settings you can customize:

Setting Description
cache.default_ttl ISR cache TTL for this app
cache.max_entries Max ISR entries before LRU eviction
rate_limit.rpm Requests per minute cap
isolate.workers Number of SSR workers
isolate.memory_limit Max memory per worker (e.g., "256mb")
deploy.keep_versions How many previous versions to keep
hooks.pre_build Shell command to run before build
hooks.post_deploy Shell command to run after deploy

When to use: hosting multiple sites on a single VPS, internal platform-as-a-service, staging environments where several feature branches share one server.

Edge Mode (Distributed with Redis L2)

Edge mode extends multi-app or single-app mode with a shared Redis backend for cache synchronization across multiple bext instances. This is a Pro feature.

[server]
listen = "0.0.0.0:443"

[redis]
url = "redis://redis.internal:6379"
prefix = "bext:"

[cache.isr]
max_entries = 50000
default_ttl_ms = 60000
default_swr_ms = 3600000

When the [redis] section is present and url resolves, bext activates cluster mode:

- L1 + L2 tiered cache -- in-memory DashMap as L1, Redis as L2. L2 hits are promoted to L1 automatically.

- Distributed invalidation -- cache tag invalidation is broadcast over Redis Pub/Sub so all instances purge simultaneously.

- Shared rate limiting -- rate limit counters use Redis INCR so the limit applies across your entire fleet, not per-instance.

- Write-through consistency -- every ISR cache write is persisted to Redis synchronously (configurable).

When Redis is unreachable, bext degrades gracefully: L1 continues to serve cached content and new renders still work. Reconnection is automatic.

# Instance A (us-east)
REDIS_URL=redis://redis.internal:6379 bext run .

# Instance B (eu-west)
REDIS_URL=redis://redis.internal:6379 bext run .

Both instances share the same cache. A page rendered by Instance A is immediately available to Instance B via the Redis L2 layer.

When to use: multi-region deployments behind a global load balancer, high-availability setups where cache coherence matters, any deployment where you need horizontal scaling beyond a single server.

Choosing the Right Mode

Consideration Single-App Multi-App Edge
Number of apps 1 Many 1 or many
Servers 1 1 2+
Cache shared across instances No N/A Yes
Redis required No No Yes
License tier Community Community Pro
Config file bext.config.toml platform.toml bext.config.toml + [redis]

You can always start with single-app mode and migrate to multi-app or edge mode later -- the bext.config.toml settings carry over unchanged.