Maintenance Mode
Official plugin — drain HTTP traffic with one flag: every flow returns a 503 ServiceUnavailable envelope with an optional Retry-After, while allow-listed paths and an operator bypass header stay alive.
maintenanceMode() short-circuits every HTTP invocation at onRequest — the earliest pipeline stage — with a typed 503 ServiceUnavailable envelope. Deploys, migrations, and incidents stop traffic with one flag instead of a deploy-time firewall rule.
Quick start
import { oke } from "okengine";
import { maintenanceMode } from "okengine/plugins";
export const app = oke({ name: "shop", env: "dev" }).plug(
maintenanceMode({ enabled: process.env.MAINTENANCE_MODE === "1" }),
);With MAINTENANCE_MODE=1 in the environment, every HTTP flow answers:
{
"data": null,
"error": {
"code": "ServiceUnavailable",
"data": { "retryAfter": 300 },
"message": "Service is under maintenance."
}
}Options
| Option | Type | Default | Does |
|---|---|---|---|
enabled | boolean | true | Master switch — drive it from the environment |
retryAfter | number | — (omitted) | Retry-After seconds on the 503 |
allowPaths | string[] | — (none) | Path prefixes that keep serving (e.g. ["/health"]) |
bypassHeader | string | — (none) | Header whose non-empty value lets a request through |
message | string | "Service is under maintenance." | Failure message in the envelope |
.plug(
maintenanceMode({
enabled: process.env.MAINTENANCE_MODE === "1",
retryAfter: 300,
allowPaths: ["/health"], // load-balancer checks stay green
bypassHeader: "x-ops-token", // operators keep working
}),
)The bypass header is presence-based — an ops convenience, not authentication. Anyone who learns the header name passes through, so treat its value as a light secret and never as a security boundary.
Notes
| Behavior | Detail |
|---|---|
| Pipeline position | onRequest — flows never parse, authenticate, or execute |
| Still shaped | The 503 flows through onResponse, so Security Headers and Compression apply to it |
| Non-HTTP triggers | No-op — clock flows and signal subscribers keep running |
| Infra routes | /_oke/* bypass the pipeline entirely and stay up |
Runtime configuration
The flagship configSource() use case — flip enabled from the database and drain traffic without a redeploy:
const maintenance = configSource({
plugin: "maintenance-mode",
code: { enabled: false },
db: { store: db },
kv: cache,
});
on(every("30s"), maintenance.sync());
export const app = oke({ name: "shop", env: "dev" }).plug(maintenanceMode(maintenance));See Plugins → Runtime configuration for the full contract.
Next
IP Allowlist
Official plugin — allow/deny rules by client IP at the edge of the pipeline, with the same typed Forbidden denial the gate element produces.
Compression
Official plugin — gzip response bodies for clients that send Accept-Encoding: gzip, with a size threshold and content-type matcher. Bun.serve does not compress on its own.