Skip to content

Perf: session bootstrap/compaction becomes very slow after ~50 rounds of conversation #50063

Closed as not planned

Description

Summary

After roughly 50 rounds of conversation, resuming / bootstrapping an existing session becomes noticeably slow — session load, restore, and compaction latency all balloon, and the degradation feels super-linear in transcript size.

Environment

  • opencode (anomalyco/opencode), local CLI, Windows 11
  • Long-lived sessions (50+ rounds), resuming from disk

Expected vs Actual

  • Expected: load/resume time stays roughly proportional to transcript size; compaction runs in the background without blocking interaction.
  • Actual: at ~50 rounds, resuming the session takes a long time; larger transcripts make load/compaction markedly slower.

Suggested areas to investigate

  • Full-file transcript parsing on every resume (no incremental/streamed load)
  • Compaction running synchronously in the interactive/init path instead of backgrounded
  • No lazy hydration of large snapshots -> every resume re-parses the whole session

Acceptance criteria for a fix

  • Session resume time scales near-linearly (or better) with transcript size
  • Compaction is backgrounded / non-blocking
  • No functional regression in session fidelity after compaction

Additional context

Long agent sessions are the main use case for this tool; this is a day-one DX pain point for anyone running long-lived conversations. Happy to provide a profile or minimal repro transcript on request.

Activity

  1. liudongyan13701205717-source commented on Oct 1, 2026

    @liudongyan13701205717-source
    Author

    This was generated by AI during triage.

    Adding measured corpus data so this is reproducible rather than anecdotal — from my local OpenCode DB (Windows 11, 1.5 GB opencode.db):

    sessions 293 | messages 20645 | parts 81551
    
    sessions by user-turn count:
      1-10    275
      11-25     6
      26-50     4
      51-100    4
      101+       3      (max 799 turns)
    

    Two observations that seem relevant:

    1. The ≥50-turn regime is real and populated here (11 of 292 sessions, worst case 799 turns), but it is a small minority — so a fix targets a long tail, and per-session regressions there would affect few users. Relevant when prioritising.
    2. Volume is dominated by part rows (81,551 rows vs 20,645 messages — roughly 4 parts per message), not by message count. If resume cost scales with rows scanned rather than with turns, the part table is where I would look first: re-parsing 81k rows per resume is a plausible source of super-linear behaviour.

    I am not asserting a cause — I have only counted rows, I have not profiled resume or compaction latency. What I can offer:

    • Run a controlled benchmark (resume wall-clock vs turn count) against this corpus and post the numbers.
    • Provide a per-table size breakdown or an anonymised transcript if that helps reproduction.

    Query used, for anyone else who wants to reproduce:

    SELECT CASE WHEN c <= 10 THEN '1-10' WHEN c <= 25 THEN '11-25'
                WHEN c <= 50 THEN '26-50' WHEN c <= 100 THEN '51-100'
                ELSE '101+' END AS bucket,
           COUNT(*) AS sessions
    FROM (SELECT session_id, COUNT(*) AS c
          FROM message
          WHERE json_extract(data, '$.role') = 'user'
          GROUP BY session_id)
    GROUP BY bucket
    ORDER BY bucket;

    One caveat that cost me time and may help others: the sqlite3 CLI is not present by default on Windows, so the above needs Python's sqlite3 module unless you already have the binary on PATH.

  2. Dante-dan commented on Oct 1, 2026

    @Dante-dan
    Contributor

    The per-session counts and the controlled benchmark you offered would help distinguish history loading from compaction. One concrete place to investigate in the legacy CLI path is filterCompactedEffect: it collects and hydrates every 50-message page before discarding history before the completed compaction boundary. That is a possible source of unnecessary work for repeatedly compacted sessions, but it does not establish the cause of your slowdown or a super-linear threshold. The newer SessionHistory bounds context reads using the latest compaction sequence, so the installed version matters.

    Could you include opencode --version with the benchmark you offered? On the same machine/project/configuration, a short session, one around 50 turns, and a longer one would be useful. For each, please include turns/messages/parts, time from resume to ready for input, whether it is a cold or warm run, and compaction time separately when compaction actually runs. That should tell us which path to profile before changing history loading or compaction scheduling; no raw database or conversation contents are needed.

    I ran the repository's existing per-file profiler on the compaction, message conversion, and pagination tests; all three passed. Those results validate existing behavior coverage only, not your Windows resume latency.

  3. liudongyan13701205717-source commented on Oct 4, 2026

    @liudongyan13701205717-source
    Author

    Thanks for the pointer to filterCompactedEffect — that's a credible candidate for the repeatedly-compacted-session case specifically. The 50-message-page collect-then-discard pattern is exactly the kind of unnecessary work that doesn't show up until you have 100+ turn sessions that have been compacted several times.

    I'll pull the source around that range and see whether the hydration cost is proportional to history length (which would match the bootstrap-slow pattern) or roughly flat (which would point elsewhere). Adding to my benchmark script so the next data dump includes a per-call breakdown of that function specifically.

  4. opencodejr commented on Oct 28, 2026

    @opencodejr
    Contributor

    Thanks for the report! To look into this we need a few more details:

    • Version: the output of opencode --version, and how you installed OpenCode (npm opencode-ai / @opencode/cli, scoop, binary, etc.).
    • How you resume: e.g. opencode -c, opencode --session <id>, picking it from the session list in the TUI, or something else. Also, which terminal you use on Windows 11.
    • Timings: roughly how long it takes to open the ~50-round session compared with a new one, and where it waits (blank screen, loading the message list, before the first prompt is accepted, ...).
    • Compaction: is the slowness in automatic compaction or in /compact, and how long does it take? Which provider and model are you using? Compaction calls the model, so its speed depends partly on the provider.
    • In your own words, briefly: what you did, what you expected and what you saw. Real measurements help more than guesses about where the cause is.

    If you can, please also attach the profile or minimal repro transcript you offered. Logs from a slow resume would help too.

    You can reply here with the details or edit the issue. If you edit it, please also leave a comment saying you've updated it so we know you're done.

  5. opencodejr commented on Oct 31, 2026

    @opencodejr
    Contributor

    We're closing this for now because we haven't received the details we asked for: your OpenCode version (opencode --version), how you resume the session, rough timings, and the provider and model used for compaction. Without the version we can't tell whether this is v1 or v2, and without the other details we can't reproduce the slowdown.

    If it still happens, please reply here with those details. The profile or minimal repro transcript you offered would help a lot, and we can reopen the issue. Thanks for reporting it!

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions