anomalyco / anomalyco/opencode
event table grows unbounded (64GB of a 73GB DB in 8 days), eventually making POST /session time out
@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
opencodeprocesses 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
- New sessions fail to start. The server process launches and binds its port correctly, and
/global/healthanswers, butPOST /sessiontimes out. From the outside this looks like a port or networking fault, which sent us down the wrong path for a while. - A second, later variant: a session is created successfully, then the process becomes unresponsive before consuming its first message.
- The database becomes too slow to introspect. A simple
SELECT type, count(*) FROM event GROUP BY typeexceeded 120 seconds and had to be abandoned. - 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
eventtable looks append-only with no TTL, cap or rotation. - No maintenance command.
opencode dbexposes only an interactive shell andpath. There is noprune,compactorvacuum. - 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
- Do not persist per-chunk streaming deltas at all, or coalesce them.
message.part.updatedappears to be a live progress notification. The final state is already durable inpart. 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. - 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.
- Add
opencode db pruneandopencode db compactso operators have a supported way to recover without deleting the whole database and losing history. - Fail loudly rather than hanging. A
POST /sessiontimeout 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.