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:
- 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.
.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
- Open a chat with a reasoning model; run a long agentic task with many tool calls (reading several large notes).
- Watch the
.chat file size grow into tens/hundreds of MB.
- 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.
What happened?
Environment
[fill in — Help → About], Windows 10/11 (Electron)deepseek-v4-pro:cloudvia Ollama (a reasoning model)Summary
Two related issues make S2B chat unusable on a real-world vault after sustained use:
.chatfiles 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):
plugin:smart-second-brainJS self-timeUpdateLayoutTree(style/layout recalc)get offsetParent×2 +serviceScriptedAnimationsSuggested 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 viarequestAnimationFrameand 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
.chatfiles are gzip'd LangGraph checkpoint stores. Each checkpoint undercheckpoints{}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 -lon one chat: 92,977,311 → 535,298,992 bytes (535 MB uncompressed).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
.chatfile size grow into tens/hundreds of MB.Impact
On a mature vault, every S2B session degrades the entire app and eventually crashes Obsidian (renderer OOM). Workarounds (archiving giant
.chatfiles, CSScontain/content-visibilityon 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