anomalyco / anomalyco/opencode

event table grows unbounded (64GB of a 73GB DB in 8 days), eventually making POST /session time out

Open
#47,223 1 comment 0 reactions 1 assignee View on GitHub

@nexxeln is already working on this.

Since Sep 4, 2026.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Summary

On a machine running many concurrent opencode sessions, opencode.db grew to 73 GB in about 8 days. 64.4 GB of that is the event table alone.

The actual conversation data is tiny by comparison: part is 2.1 GB and message is 1.7 GB. Essentially all of the growth is the event log.

Environment
  • opencode 1.18.25
  • macOS
  • Database at the default path, ~/.local/share/opencode/opencode.db, journal mode WAL
  • Around 43 concurrent opencode processes sharing the one database (heavy automation, not a typical single-user setup)
Numbers
table size
event 64.4 GB
part 2.1 GB
message 1.7 GB

event held 2,594,731 rows. Sampling the 200,000 most recent:

type count share
message.part.updated.1 126,747 63.4%
message.updated.1 57,558 28.8%
session.updated.1 15,607 7.8%
session.created.1 88 0.04%

So roughly 92% of rows are per-chunk streaming progress events. A row's data payload is typically around 1 KB. Growth measured at roughly 8 GB/day under this load.

Symptoms, in the order they appeared
  1. New sessions fail to start. The server process launches and binds its port correctly, and /global/health answers, but POST /session times out. From the outside this looks like a port or networking fault, which sent us down the wrong path for a while.
  2. A second, later variant: a session is created successfully, then the process becomes unresponsive before consuming its first message.
  3. The database becomes too slow to introspect. A simple SELECT type, count(*) FROM event GROUP BY type exceeded 120 seconds and had to be abandoned.
  4. Disk pressure. At 8 GB/day this is the dominant consumer of free space on the machine.

Notably this is not CPU load related. We saw the same failure at load average 29 and at load average 4.6.

What appears to be missing
  • No retention. The event table looks append-only with no TTL, cap or rotation.
  • No maintenance command. opencode db exposes only an interactive shell and path. There is no prune, compact or vacuum.
  • No configuration option. Nothing in the config appears to control event retention.

The only remedy available to us was to stop everything and delete the database, losing all session history. VACUUM was not practical: it needs roughly the database's own size in free space, and takes an exclusive lock across every attached process.

Suggested fixes, roughly in order of preference
  1. Do not persist per-chunk streaming deltas at all, or coalesce them. message.part.updated appears to be a live progress notification. The final state is already durable in part. If these events exist to drive in-flight subscribers, they may not need to outlive the turn that produced them. This alone would remove the large majority of the growth.
  2. Add a retention policy with a sane default, for example keep events for N days or cap the table at N rows, pruned on startup or on a timer, and make it configurable.
  3. Add opencode db prune and opencode db compact so operators have a supported way to recover without deleting the whole database and losing history.
  4. Fail loudly rather than hanging. A POST /session timeout gives no hint that the cause is database size. A startup warning above some threshold, or a clear error, would have saved us several hours of misdiagnosis.
Why it matters beyond our setup

We hit this quickly because of concurrency, but the growth is driven by tokens streamed rather than by sessions created. Any long-running heavy user should reach the same place eventually, just more slowly, and the first symptom they see will be "cannot create a session" with no indication why.

Happy to provide more detail on the row distribution or timings if useful.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.