Session management deep dive
기준일: 2026-07-26
공식 기준: Session management deep dive
Session management deep dive 문서는 OpenClaw 공식 문서(reference/session-management-compaction)를 한국어로 정리한 가이드입니다. Deep dive: session store + transcripts, lifecycle, and (auto)compaction internals 명령·설정 키·코드 예시는 공식 문서를 그대로 보존하며, 해석과 절차 안내는 한국어로 제공합니다. 최종 동작은 설치된 CLI 버전과 공식 원문을 확인하세요.
핵심 요약
Deep dive: session store + transcripts, lifecycle, and (auto)compaction internals
한국어 가이드 범위: reference/session-management-compaction 경로의 설정·명령·제약·예시를 학습용으로 재구성합니다.
문서 구성
공식 문서의 주요 섹션은 다음과 같습니다.
- Two persistence layers
- On-disk locations
- Store maintenance and disk controls
- Downgrading After The SQLite Flip
- Cron sessions and run logs
- Session keys (sessionKey)
- Session ids (sessionId)
- Session store schema
- Transcript event structure
- Context windows vs tracked tokens
- Compaction: what it is
- Chunk boundaries and tool pairing
- When auto-compaction happens
- Compaction settings
- Pluggable compaction providers
- User-visible surfaces
- Silent housekeeping (NO_REPLY)
- Pre-compaction memory flush
- Troubleshooting checklist
- 관련 문서
상세 내용
본문
A single Gateway process owns session state end-to-end. UIs (macOS app, web Control UI, TUI) query the Gateway for session lists and token counts. In remote mode, session files live on the remote host, so checking your local Mac's files will not reflect what the Gateway is using.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
Two persistence layers
- Session rows (per-agent SQLite) - key/value map
sessionKey -> SessionEntry. Mutable runtime state owned by the Gateway. Tracks metadata: current session id, last activity, toggles, token counters. 2. Transcript events (per-agent SQLite) - append-only, tree-structured (entries haveid+parentId). Stores the conversation, tool calls, and compaction summaries; rebuilds model context for future turns. Compaction checkpoints are metadata over the compacted successor transcript - a new compaction does not write a second.checkpoint.*.jsonlcopy.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
On-disk locations
Per agent, on the Gateway host (resolved via src/config/sessions.ts):
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- Runtime session row store:
~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite - Runtime transcript rows:
~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite - Legacy/archive transcript artifacts:
~/.openclaw/agents/<agentId>/sessions/ - Legacy row migration input:
~/.openclaw/agents/<agentId>/sessions/sessions.json
Store maintenance and disk controls
session.maintenance controls automatic maintenance for SQLite session rows, SQLite transcript rows, archive artifacts, and trajectory sidecars:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
| Key | Default | Notes |
|---|---|---|
mode |
"enforce" |
or "warn" (report only, no mutation) |
pruneAfter |
"30d" |
stale-entry age cutoff |
maxEntries |
500 |
cap on session entries |
resetArchiveRetention |
keep (no age cutoff) | age cutoff for *.reset.*/*.deleted.* transcript archives; a duration opts into deletion |
maxDiskBytes |
10gb |
per-agent sessions disk budget; false disables |
highWaterBytes |
80% of maxDiskBytes |
target after budget cleanup |
openclaw sessions cleanup --dry-run
openclaw sessions cleanup --enforce
Downgrading After The SQLite Flip
Restore archived legacy transcript artifacts before running an older file-backed OpenClaw version:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
openclaw doctor --session-sqlite restore --session-sqlite-all-agents
Cron sessions and run logs
Isolated cron runs create their own session entries/transcripts with dedicated retention:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
cron.sessionRetention(default"24h") prunes old isolated cron run sessions from the store;falsedisables.- Run history keeps the newest 2000 terminal rows per cron job. Lost rows retain their 24-hour cleanup window.
Session keys (sessionKey)
A sessionKey identifies which conversation bucket you are in (routing + isolation). Canonical rules: /concepts/session.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
| Pattern | Example |
|---|---|
| Main/direct chat (per agent) | agent:<agentId>:<mainKey> (default main) |
| Group | agent:<agentId>:<channel>:group:<id> |
| Room/channel (Discord/Slack) | agent:<agentId>:<channel>:channel:<id> or ...:room:<id> |
| Cron | cron:<job.id> |
| Webhook | hook:<uuid> (unless overridden) |
Session ids (sessionId)
Each sessionKey points at a current sessionId (the SQLite transcript identity that continues the conversation). Decision logic lives in initSessionState() in src/auto-reply/reply/session.ts.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- Reset (
/new,/reset) creates a newsessionIdfor thatsessionKey. - No automatic reset is the default. The current
sessionIdcontinues while compaction keeps the active model context bounded. - Daily reset (
session.reset.mode: "daily") creates a newsessionIdon the next message after the configured local-hour boundary (session.reset.atHour, default4). - Idle expiry (
session.reset.mode: "idle"withsession.reset.idleMinutes, or legacysession.idleMinutes) creates a newsessionIdwhen a message arrives after the idle window. If daily and idle are both configured, whichever expires first wins. - Control UI reconnect resume preserves the currently visible session for one reconnect send when the Gateway receives the matching
sessionIdfrom an operator UI client. This is a one-shot signal; ordinary stale sends still create a newsessionId. - System events (heartbeat, cron wakeups, exec notifications, gateway bookkeeping) may mutate the session row but never extend daily/idle reset freshness. Reset rollover discards queued system-event notices for the previous session before the fresh prompt is built.
- Parent fork policy uses OpenClaw's active branch when creating a thread or subagent fork. If that branch is too large (over a fixed internal cap, currently 100K tokens), OpenClaw starts the child with isolated context instead of failing or inheriting unusable history. Sizing is automatic and not configurable; legacy
session.parentForkMaxTokensconfig is removed byopenclaw doctor --fix. - Operator forks:
sessions.create { parentSessionKey, fork: true }creates a new session whose transcript branches from the parent's current state (same fork machinery as subagent spawns, including the size cap above). The fork is refused while the parent has an active run, inherits the parent's model selection unless one is passed explicitly, and marks the childforkedFromParentwith fresh token counters.
Session store schema
The runtime store keeps SessionEntry values in per-agent SQLite. The value type is SessionEntry in src/config/sessions.ts. Key fields (not exhaustive):
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
sessionId: current transcript id used to address SQLite transcript rowssessionStartedAt: start timestamp for the currentsessionId; daily reset freshness uses this. Legacy rows may derive it from the JSONL session header.lastInteractionAt: last real user/channel interaction timestamp; idle reset freshness uses this so heartbeat, cron, and exec events do not keep sessions alive. Legacy rows without this field fall back to the recovered session start time.updatedAt: last store-row mutation timestamp, used for listing/pruning/bookkeeping - not the daily/idle freshness authority.archivedAt: optional archive timestamp. Archived sessions stay in the store with their transcript intact and are excluded from normal active listings.pinnedAt: optional pin timestamp. Active pinned sessions sort ahead of unpinned sessions; archiving a session clears its pin.- Codex thread interop: both fields follow the Codex thread-management shape - the
archived/pinnedbooleans on the wire are always derived from the timestamp and stamped server-side, matching Codexthreads.archived_atsemantics and camelCase serialization. OpenClaw timestamps are epoch milliseconds while Codex uses epoch seconds, so bridges convert at thecodexplugin seam. Codex has no pin API yet (thread/archive/thread/unarchiveonly); pinned state stays OpenClaw-side until one exists, at which point the matching shape lets bound sessions round-trip pin state mechanically. - Codex supervision lists only non-archived native threads. A Gateway-local
idleornotLoadedactivity-unknown thread can be archived through nativethread/archiveonly after the operator explicitly confirms that no other Codex process owns it; the plugin performs a fresh process-local status read first, and the thread then disappears from the catalog. That read cannot prove that another App Server process is not using the thread. OpenClaw refuses to archive active and error rows, and paired-node archive is unavailable until the node bridge can own the full streamed thread lifecycle. Unarchiving in a native Codex client makes the thread eligible to appear again. lastReadAt/markedUnreadAt: read-state timestamps stamped server-side bysessions.patch { unread }-unread: falserecords a read (setslastReadAt, clearsmarkedUnreadAt);unread: truemarks the session unread until the next read. Session rows expose a derivedunreadboolean: explicitly marked unread, or read before the latest activity. Sessions never marked read stayunread: false, so existing installs do not light up on upgrade.lastActivityAt: timestamp of the last completed agent run that counts as unread-worthy activity (user, channel, and cron runs). Heartbeat and internal-event turns, plus metadata patches, do not update it;updatedAtis not an activity signal.sessionFile: legacy marker retained for migration/archive compatibility; active runtime uses SQLite identitychatType:direct | group | roomprovider,subject,room,space,displayName: group/channel labeling metadata- Toggles:
thinkingLevel,verboseLevel,reasoningLevel,elevatedLevel,sendPolicy(per-session override) - Model selection:
providerOverride,modelOverride,authProfileOverride - Token counters (best-effort/provider-dependent):
inputTokens,outputTokens,totalTokens,contextTokens compactionCount: how many times auto-compaction completed for this session keymemoryFlushAt/memoryFlushCompactionCount: timestamp and compaction count of the last pre-compaction memory flush
Transcript event structure
Transcripts are managed by the OpenClaw session accessor and exposed to runtime code through identity-based helpers. The event stream is append-only:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- First entry: session header -
type: "session",id,cwd,timestamp, optionalparentSession. - Then: entries with
id+parentId(tree structure). message: user/assistant/toolResult messagescustom_message: extension-injected message that does enter model context (rendered in the TUI whendisplay: true, hidden entirely whendisplay: false)custom: extension state that does not enter model context (for persisting extension state across reloads)compaction: persisted compaction summary withfirstKeptEntryIdandtokensBeforebranch_summary: persisted summary when navigating a tree branch
Context windows vs tracked tokens
- Model context window: hard cap per model (tokens visible to the model). Comes from the model catalog and can be overridden via config. 2. Session store counters: rolling stats written into the session row (used for
/statusand dashboards).contextTokensis a runtime estimate/reporting value - do not treat it as a strict guarantee.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
Compaction: what it is
Compaction summarizes older conversation into a persisted compaction entry in the transcript and keeps recent messages intact. After compaction, future turns see the compaction summary plus messages after firstKeptEntryId. Compaction is persistent, unlike session pruning - see /concepts/session-pruning.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
Chunk boundaries and tool pairing
When splitting a long transcript into compaction chunks, OpenClaw keeps assistant tool calls paired with their matching toolResult entries:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- If the token-share split would land between a tool call and its result, OpenClaw shifts the boundary to the assistant tool-call message instead of separating the pair.
- If a trailing tool-result block would otherwise push the chunk over target, OpenClaw preserves that pending tool block and keeps the unsummarized tail intact.
- Aborted/error tool-call blocks do not hold a pending split open.
When auto-compaction happens
Two triggers in the embedded OpenClaw agent:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- Preflight local compaction: set
agents.defaults.compaction.maxActiveTranscriptBytes(bytes or a string like"20mb") to trigger local compaction before opening the next run once the active transcript reaches that size. This is a size guard for local reopen cost, not raw archival - normal semantic compaction still runs, and it requirestruncateAfterCompactionso the compacted summary becomes a new successor transcript. - Mid-turn precheck: set
agents.defaults.compaction.midTurnPrecheck.enabled: true(defaultfalse) to add a tool-loop guard. After a tool result is appended and before the next model call, OpenClaw estimates prompt pressure using the same preflight budget logic used at turn start. If context no longer fits, the guard does not compact inline - it raises a structured mid-turn precheck signal, stops the current prompt submission, and lets the outer run loop use the existing recovery path (truncate oversized tool results when that is enough, or trigger the configured compaction mode and retry). Works with bothdefaultandsafeguardcompaction modes, including provider-backed safeguard compaction. Independent ofmaxActiveTranscriptBytes: the byte-size guard runs before a turn opens, mid-turn precheck runs later, after new tool results are appended.
Compaction settings
OpenClaw enforces a built-in reserve for embedded runs and caps it against the active model context window so it cannot consume the whole prompt budget. This keeps small-context local models from entering compaction from the first token while leaving enough headroom for multi-turn housekeeping such as the memory flush.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
{
agents: {
defaults: {
compaction: {
enabled: true,
keepRecentTokens: 20000,
},
},
},
}
Pluggable compaction providers
Plugins register a compaction provider via registerCompactionProvider() on the plugin API. When agents.defaults.compaction.provider is set to a registered provider id, the safeguard extension delegates summarization to that provider instead of the built-in summarizeInStages pipeline.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
provider: id of a registered compaction provider plugin. Leave unset for default LLM summarization. Setting aproviderforcesmode: "safeguard".- Providers receive the same compaction instructions and identifier-preservation policy as the built-in path, and the safeguard still preserves recent-turn and split-turn suffix context after provider output.
- Built-in safeguard summarization re-distills prior summaries with new messages instead of preserving the full previous summary verbatim.
- Safeguard mode enables summary quality audits by default; set
qualityGuard.enabled: falseto skip retry-on-malformed-output behavior. - If the provider fails or returns an empty result, OpenClaw falls back to built-in LLM summarization automatically. Abort/timeout signals the caller explicitly triggered are re-thrown, not swallowed, so cancellation is always respected.
User-visible surfaces
주요 항목:
/statusin any chat sessionopenclaw status(CLI)openclaw sessions/openclaw sessions --json- Gateway logs (
pnpm gateway:watchoropenclaw logs --follow):embedded run auto-compaction start+complete - Verbose mode:
🧹 Auto-compaction completeplus the compaction count
Silent housekeeping (NO_REPLY)
OpenClaw supports "silent" turns for background tasks where the user should not see intermediate output.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- The assistant starts its output with the exact silent token
NO_REPLY/no_replyto mean "do not deliver a reply to the user." OpenClaw strips/suppresses this in the delivery layer. - Exact silent-token suppression is case-insensitive:
NO_REPLYandno_replyboth count when the whole payload is just the silent token. - As of
2026.1.10, OpenClaw also suppresses draft/typing streaming when a partial chunk begins withNO_REPLY, so silent operations do not leak partial output mid-turn. - This is for true background/no-delivery turns only - it is not a shortcut for ordinary actionable user requests.
Pre-compaction memory flush
Before auto-compaction happens, OpenClaw can run a silent agentic turn that writes durable state to disk (for example memory/YYYY-MM-DD.md in the agent workspace) so compaction cannot erase critical context. It monitors session context usage, and once it crosses a soft threshold below the compaction threshold, it sends a silent "write memory now" directive using the exact silent token NO_REPLY / no_reply so the user sees nothing.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- The built-in prompt and system prompt include a
NO_REPLYhint to suppress delivery. - When
modelis set, the flush turn uses that model without inheriting the active session's fallback chain, so local-only housekeeping does not silently fall back to a paid conversation model on failure. - The flush runs once per compaction cycle (tracked in the session row).
- The flush runs only for embedded OpenClaw sessions; CLI backends and heartbeat turns skip it.
- The flush is skipped when the session workspace is read-only (
workspaceAccess: "ro"or"none"). - See Memory for the workspace file layout and write patterns.
| Key | Default | Notes |
|---|---|---|
enabled |
true |
|
model |
unset | exact provider/model override for the flush turn only, for example ollama/qwen3:8b |
softThresholdTokens |
4000 |
gap below the compaction threshold that triggers a flush |
forceFlushTranscriptBytes |
unset (disabled) | force a flush once the transcript file reaches this byte size (or string like "2mb"), even if token counters are stale; 0 disables |
Troubleshooting checklist
주요 항목:
- Session key wrong? Start with /concepts/session and confirm the
sessionKeyin/status. - Store vs transcript mismatch? Confirm the Gateway host and the store path from
openclaw status. - Compaction spam? Check the model's context window (too small forces frequent compaction) and tool-result bloat (tune session pruning).
- Every prompt seems to overflow on a small local model? Confirm the provider reports the correct model context window. OpenClaw can cap the effective reserve only when that window is known.
- Silent turns leaking? Confirm the reply starts with the exact silent token
NO_REPLY(case-insensitive) and you are on a build that includes the streaming-suppression fix (2026.1.10+).
관련 문서
주요 항목:
- Session management
- Session pruning
- Context engine
- Agent config reference
실습 체크리스트
- 공식 문서와 로컬 버전을 대조합니다:
https://docs.openclaw.ai/reference/session-management-compaction - 관련 CLI는
openclaw --help및 하위 명령--help로 옵션을 확인합니다. - 설정 변경 시
openclaw config/openclaw doctor로 유효성을 검사합니다. - Gateway·채널·플러그인 변경 후에는 필요 시 Gateway를 재시작합니다.
자주 쓰는 명령·설정 예시
openclaw sessions cleanup --dry-run
openclaw sessions cleanup --enforce
openclaw doctor --session-sqlite restore --session-sqlite-all-agents
{
agents: {
defaults: {
compaction: {
enabled: true,
keepRecentTokens: 20000,
},
},
},
}
관련 링크
이 가이드는 공식 문서를 한국어 학습용으로 재구성한 것입니다. 옵션 기본값·플래그 이름은 설치 버전에 따라 달라질 수 있습니다.