Skip to content

[Bug]: Whole-UI lag during chat + O(n²) checkpoint file growth #482

Description

@Direct-Launch

What happened?

Environment

  • Smart Second Brain: v2.0.5
  • Obsidian: [fill in — Help → About], Windows 10/11 (Electron)
  • Model: deepseek-v4-pro:cloud via Ollama (a reasoning model)
  • Vault: ~6,500 markdown notes; embedding index disabled (lexical + direct reads)

Summary

Two related issues make S2B chat unusable on a real-world vault after sustained use:

  1. The whole Obsidian UI freezes/stutters for the entire duration of an assistant response (not just the chat pane), and recovers the instant streaming ends.
  2. .chat files grow O(n²) and reach hundreds of MB — one reached 535 MB uncompressed (89 MB gzipped) — which is what makes issue 1 catastrophic and drives 5–9 GB renderer RAM swings + OOM crashes.

Issue 1 — per-token full re-render + forced synchronous layout

During streaming, S2B appears to re-render the message (and read layout) on every token, forcing a full style+layout recalculation of the thread each frame. This blocks the renderer's main thread, so the entire app (editor, sidebars, other windows) stutters while a response streams.

Evidence — Chrome DevTools performance trace (10 s of an active session):

Signal Cost Note
plugin:smart-second-brain JS self-time 7,357 ms #1 plugin by ~150× (next plugin = 49 ms)
UpdateLayoutTree (style/layout recalc) 3,146 ms dominant render-pipeline cost
get offsetParent ×2 + serviceScriptedAnimations ~700 ms reading layout while mutating DOM = layout thrashing
dataview / tasknotes / metadataCache 9 / 25 ms vault work is negligible — this is pure rendering

Suggested fix: render streamed tokens incrementally/append-only instead of re-rendering the whole message per chunk; never read layout (offsetParent, scrollHeight, etc.) synchronously inside the token loop — batch any layout reads via requestAnimationFrame and separate reads from writes to avoid forced reflow. Consider throttling markdown re-parse to e.g. every N ms rather than per token.

Issue 2 — O(n²) checkpoint storage

.chat files are gzip'd LangGraph checkpoint stores. Each checkpoint under checkpoints{} stores a full copy of the conversation state (channel_values.messages). A long agentic session with many tool calls accumulates hundreds of checkpoints, each holding the full growing message set — so file size grows with the square of the conversation, and each large tool output is retained in full.

Evidence:

  • gzip -l on one chat: 92,977,311 → 535,298,992 bytes (535 MB uncompressed).
  • 10 of ~40 chats exceeded 20 MB on disk; several 50–90 MB.
  • Opening such a chat parses the full structure into JS objects → 5–9 GB renderer RAM oscillation per second and OOM crashes.
  • The actual conversation content is tiny: extracting only the latest checkpoint's messages (resolving the messageTable {$msg:N} refs) and truncating tool outputs yields ~11–60 KB transcripts — a ~1000× reduction. So the bloat is entirely redundant checkpoint state + retained raw tool outputs.

Suggested fix: store checkpoint deltas rather than full snapshots; and/or prune/cap historical checkpoints (keep last-N or last-viewed); and/or stop persisting full raw tool outputs in the checkpoint (store a reference or a truncated preview). A per-thread size guard with a warning would also prevent the pathological case.

Repro

  1. Open a chat with a reasoning model; run a long agentic task with many tool calls (reading several large notes).
  2. Watch the .chat file size grow into tens/hundreds of MB.
  3. Reopen that chat and send another message → the whole Obsidian UI stutters for the full response; renderer RAM swings multi-GB.

Impact

On a mature vault, every S2B session degrades the entire app and eventually crashes Obsidian (renderer OOM). Workarounds (archiving giant .chat files, CSS contain/content-visibility on the chat view, collapsing the thinking panel) reduce but do not remove it, because the per-token re-render and full-state checkpointing are internal.

Console output


Plugin version

2.0.5

Platform

Windows

Provider and model (if relevant)

deepseek-v4-pro:cloud` via Ollama (a reasoning model)

Obsidian debug info

SYSTEM INFO:
	Obsidian version: 1.13.7
	Installer version: 1.12.7
	Operating system: Windows 11 Home 10.0.26200
	Login status: logged in
	Language: en-GB
	Catalyst license: none
	Insider build toggle: off
	Live preview: on
	Base theme: adapt to system
	Community theme: Minimal 9.0.2
	Snippets enabled: 3
	Restricted mode: off
	Plugins installed: 28
	Plugins enabled: 15
		1: Templater v2.25.0
		2: MCP Connector v2.4.0
		3: Git v2.39.0
		4: Claudian v2.2.5
		5: Data Files Editor v1.3.0
		6: Iconize v2.14.7
		7: Dataview v0.5.68
		8: Minimal Theme Settings v9.0.0
		9: Homepage v4.4.4
		10: TaskNotes v4.12.5
		11: Style Settings v1.0.9
		12: Charts v3.9.0
		13: Smart Second Brain v2.0.5
		14: S2B Shell v1.0.0
		15: Cadence v0.15.0

RECOMMENDATIONS:
	Custom theme and snippets: for cosmetic issues, please first try updating your theme and disabling your snippets. If still not fixed, please try to make the issue happen in the Sandbox Vault or disable community theme and snippets.
	Community plugins: for bugs, please first try updating all your plugins to latest. If still not fixed, please try to make the issue happen in the Sandbox Vault or disable community plugins.

Activity

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

    bugSomething isn't working

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions