Skip to content

[FEATURE]: Add an ephemeral mode that does not persist sessions locally #53921

Open

Description

@xabipalmer

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

Feature request

OpenCode currently persists session conversations locally in its database. It would be useful to have an optional ephemeral mode for users who do not want sessions to be stored after OpenCode exits.

Use case

This would be useful when working with sensitive, proprietary, or temporary projects where conversation history should not remain on disk.

Proposed behavior

Add a configuration option or command-line flag such as:

{
  "session": {
    "persist": false
  }
}

or:

opencode --no-session-persistence

When enabled:

- Do not persist the conversation transcript locally.
- Do not create a recoverable session entry in the local database.
- Do not make the session available through session list.
- Keep the session available in memory while OpenCode is running.
- Discard the session automatically when OpenCode exits.
- Clearly indicate in the UI that ephemeral mode is enabled.
- 
It would also be useful for this mode to disable or clean up related session data, such as snapshots and temporary metadata.

Activity

  1. opencode-agent commented on Oct 8, 2026

    @opencode-agent
    Contributor

    Thanks for the detailed request, @xabipalmer!

    To restate it: you'd like an opt-in ephemeral mode (a config option such as session.persist: false or a CLI flag) where a session exists only in memory while OpenCode runs. Nothing would be written to the local database, it wouldn't show up in the session list, snapshots and related metadata would be skipped or cleaned up, and the UI would show that the mode is on.

    I couldn't find an open request for exactly this, but these are related:

    A plugin can't fully do this today, because sessions are written to disk before any plugin hook runs. Maintainers will consider it as a feature request.

  2. marksteward commented on Oct 12, 2026

    @marksteward

    Genuinely amazed that ephemeral/incognito sessions aren't a feature yet. If nothing else, I regularly want to ask a quick question that has a simple answer and don't want the hassle of copying the session ID into opencode session delete. Along with the lack of a /delete command, it kind of feels like there's some high level desire to leave old session data on disk for a while. See also #12766.

    Given #459 and #10416 and #46115, this all feels pretty sus from a privacy perspective.

  3. BrandoB commented on Oct 25, 2026

    @BrandoB

    Same need here, so I put together a workaround that gets most of the way there on 2.1.4 (Linux). It's a bash function that intercepts --incognito and runs a private server with nothing on disk:

    opencode() {
      local bin a incog=0 args=()
      bin=$(type -P opencode)
      for a in "$@"; do
        if [ "$a" = "--incognito" ]; then incog=1; else args+=("$a"); fi
      done
      [ "$incog" = 1 ] || { "$bin" "$@"; return; }
      local first="${args[0]:-}" cmd d p root rc
      if [ "$first" = run ]; then
        cmd=("$bin" run --standalone "${args[@]:1}")
      elif [ -z "$first" ] || [ "${first#-}" != "$first" ] || [ -d "$first" ]; then
        cmd=("$bin" --standalone "${args[@]}")
      else
        echo "opencode --incognito: only the TUI and 'run'" >&2; return 2
      fi
      for d in /dev/shm/oc-incognito.*; do   # leftovers from a crashed session
        [ -d "$d" ] && [ -O "$d" ] || continue
        p=$(cat "$d/.pid" 2>/dev/null)
        if [ -z "$p" ] || ! kill -0 "$p" 2>/dev/null; then rm -rf -- "$d"; fi
      done
      root=$(mktemp -d /dev/shm/oc-incognito.XXXXXXXX) || return 1
      chmod 700 "$root"
      mkdir -p "$root/data/opencode" "$root/state"
      [ -f "$HOME/.local/share/opencode/auth.json" ] && \
        install -m 600 "$HOME/.local/share/opencode/auth.json" "$root/data/opencode/auth.json"
      (
        ulimit -c 0
        echo "$BASHPID" > "$root/.pid"
        export XDG_DATA_HOME="$root/data" XDG_STATE_HOME="$root/state" \
          OPENCODE_DB=":memory:" OPENCODE_DISABLE_AUTOUPDATE=1 \
          OPENCODE_DISABLE_FREE_MODELS=1 OPENCODE_DISABLE_MODELS_FETCH=1
        exec "${cmd[@]}"
      )
      rc=$?
      rm -rf -- "$root"
      return $rc
    }

    Some things I ran into:

    • --standalone matters. In 2.x the TUI talks to the background service by default, so a session started without it still lands in the service's database even if you redirect the data dir.
    • --standalone has to come after the subcommand. opencode --standalone run ... fails with "Unrecognized flag: --standalone in command opencode run"; opencode run --standalone ... works.
    • Normal sessions also write the prompt text to ~/.local/share/opencode/log/opencode.log, not just the DB. Worth covering if this becomes a real feature, since session delete won't remove it.
    • Session titles come from a separate model call. With no small_model set, mine went to the session's own (local) model. OPENCODE_DISABLE_FREE_MODELS=1 is there so it can't fall back to a hosted free model.
    • Even with --standalone and a local model, opencode fetches https://models.opencode.ai/api.json every 5 minutes while a server runs (packages/core/src/models-dev.ts). It's a plain GET with a User-Agent and ETag, no prompt data, but it does tell the outside world when you're using it. OPENCODE_DISABLE_MODELS_FETCH=1 stops it (or OPENCODE_MODELS_PATH for a local catalog); disabling the built-in opencode provider doesn't.
    • I set "share": "disabled" globally so a stray /share can't upload anything.

    To check it, I ran a session with a canary string and then searched the data, state, cache and config dirs, /tmp and /dev/shm for it. Nothing turned up and no file in those dirs changed. As a control, a normal session with a different canary showed up in opencode.db-wal and log/opencode.log. Watching ss during a run, the incognito process only talks to the local model server and localhost.

    I also added a small TUI plugin that shows an "INCOGNITO · RAM ONLY" marker in prompt.footer.status when the session is ephemeral, loaded only for these sessions through OPENCODE_CLI_CONFIG_CONTENT. Happy to share it.

    What it doesn't cover: files that tools deliberately write into the project, tmpfs pages that get swapped out (fine if your swap is encrypted), and anything your model provider logs on its side.

    A built-in flag would still be better. This is just what works today.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions