Skip to content

Add optional idle-shutdown and on-demand startup for the local OpenCode server #224

Description

@ruslansin

Motivation

When used as a mobile client, the bot often runs 24/7 on a low-spec machine (small VPS, home server, laptop that stays on). The heavy resource consumer is the spawned opencode serve process and its model workers (hundreds of MB–GB). For users who work in short, sporadic bursts from a phone, keeping the server alive around the clock wastes memory for no benefit.

The project already manages the local server lifecycle in a few places:

  • manual start/stop (/opencode_start, /opencode_stop)
  • optional health-checked auto-restart (OPENCODE_AUTO_RESTART_ENABLED)

The missing piece is the inverse of auto-restart: stop the server when idle, start it again on demand. This proposal adds that as an optional, opt-in mode that mirrors the existing process-management design.

Proposed behavior

  1. Stop on idle. While the bot is running and opencode serve is active, track "last activity" (the last dispatched prompt / last active run). If the server stays idle for OPENCODE_IDLE_SHUTDOWN_SEC, shut it down gracefully and release all bot-side runtime state, exactly like /opencode_stop does.
  2. Start on demand. When the server is down and a prompt (text/voice/photo/attachment) or a command that needs OpenCode arrives, start the local server and wait for it to become ready before dispatching — the same flow as /opencode_start. The readiness lifecycle (opencodeReadyLifecycle) then re-attaches to the last session and re-subscribes to SSE, so the resumed session and notifications keep working.

Configuration

New env flags (all off by default, matching the existing convention):

# Seconds of inactivity before the local server is stopped (0 = disabled)
OPENCODE_IDLE_SHUTDOWN_SEC=0

# Wait for the server on demand instead of erroring when it is down (default: false)
OPENCODE_START_ON_DEMAND=true

OPENCODE_START_ON_DEMAND is implicitly enabled when OPENCODE_IDLE_SHUTDOWN_SEC > 0.

Important interaction: mutual exclusion with auto-restart

OPENCODE_AUTO_RESTART_ENABLED restarts the server as soon as it sees it unhealthy (src/opencode/auto-restart.ts). That would undo an idle shutdown. The two modes must be mutually exclusive:

  • If auto-restart is enabled, idle-shutdown should be ignored (or rejected) with a clear log message.
  • Committing to health-monitor restart only makes sense for "should always be up"; idle-shutdown is for "should be up only while in use."

Why state is safe across restarts

Sessions and projects are persisted on disk by OpenCode. On server ready, opencodeReadyLifecycle.onReady (src/bot/index.ts) already restores the followed session and re-subscribes to events, so resuming after an idle stop is functionally identical to the existing manual /opencode_start path.

Suggested implementation (self-contained, mirrors existing code)

  • Stop path: reuse findServerPid + killServerProcess (src/opencode/process.ts) and the state-release logic in releaseLocalStateAfterServerStop (src/bot/commands/opencode-stop-command.ts). Add an idle timer that tracks last prompt dispatch time — natural sources are foregroundSessionState and assistantRunState.
  • Start path: reuse startLocalOpencodeServer + the waitForServerReady/health-check block from opencode-start-command.ts, triggered from processUserPrompt (src/bot/handlers/prompt.ts) and the OpenCode-dependent commands before they fail.
  • Orchestration: a small sibling to OpencodeAutoRestartService (e.g. OpencodeIdleShutdownService) so the health/ready notifications stay centralized in ready-lifecycle.ts.

Tradeoffs

  • Cold start latency: the first prompt after an idle period waits for server startup + model load (a few seconds). Acceptable in exchange for RAM savings, but worth flagging in the response text.
  • Scope: this is an ops/resource optimization, not a UX change, and stays strictly within the "single OpenCode CLI window" concept.

Open questions for the maintainer

  • Should idle-shutdown also consider a dedicated /opencode_stop//opencode_start command rather than pure auto behavior? (Commands already exist; this proposal keeps them.)
  • Preferred inactivity unit/limits and whether to expose a per-user setting via /settings or keep it env-only.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions