mirror of
https://github.com/twentyhq/twenty
synced 2026-04-21 13:37:22 +00:00
https://sonarly.com/issue/27119?type=bug Chrome tab crashes with OOM (error code 5) because the Jotai atom family cache (`atomCache` Map) never evicts entries, and each AI chat message is stored three times (thread-level atom, per-message atom via structuredClone, Apollo InMemoryCache), causing unbounded heap growth during long conversations, rapid workspace switching, or Settings page navigation. Fix: Three changes that address the two largest memory growth vectors in the AI chat module: 1. **Added `evictFamilyKey` to `ComponentFamilyState`** (`ComponentFamilyState.ts` type + `createAtomComponentFamilyState.ts` implementation): Exposes `atomCache.delete()` so consumers can remove atoms they no longer need. This is the missing primitive — the atomCache Map previously had no way to remove entries. 2. **Evict per-message atoms on thread switch** (`AgentChatStreamingPartsDiffSyncEffect.tsx`): Tracks message IDs seen during diff sync in a ref. When `currentAIChatThread` changes, the cleanup effect fires and calls `evictFamilyKey` for every tracked message ID, removing those atoms from the cache. This prevents the biggest accumulation vector: hundreds of per-message atoms (keyed by UUID) holding large ExtendedUIMessage payloads that were never released. 3. **Remove `structuredClone` from `useUpdateStreamingPartsWithDiff.ts`**: The deep clone was creating a full copy of every message object before storing it in the per-message atom. Since `isDeeplyEqual` already gates updates (preventing unnecessary writes), and the message reference from the thread-level atom is stable within a render cycle, the clone is unnecessary. Removing it eliminates one full copy of every message in memory. Together these changes bound per-message atom memory to the current thread's messages (instead of all threads ever viewed), and halve the per-message memory footprint by eliminating deep clones. **Not addressed in this PR** (requires separate, wider-scoped changes): - Apollo InMemoryCache eviction — needs typePolicies configuration in the shared Apollo factory - Thread-level family state atoms (10 per thread) — small scalar values, low priority |
||
|---|---|---|
| .. | ||
| create-twenty-app | ||
| twenty-apps | ||
| twenty-cli | ||
| twenty-client-sdk | ||
| twenty-companion | ||
| twenty-docker | ||
| twenty-docs | ||
| twenty-e2e-testing | ||
| twenty-emails | ||
| twenty-front | ||
| twenty-front-component-renderer | ||
| twenty-oxlint-rules | ||
| twenty-sdk | ||
| twenty-server | ||
| twenty-shared | ||
| twenty-ui | ||
| twenty-utils | ||
| twenty-website | ||
| twenty-website-new | ||
| twenty-zapier | ||