#10801: fix: eagerly initialize QMD memory backend on gateway startup
gateway
stale
Cluster:
Memory Management Enhancements
## Problem
QMD memory backend is lazily initialized (only when `memory_search`/`memory_get` is first called). After gateway restarts (config reloads, deploys), the `QmdMemoryManager` instance and its periodic update/embed timer are lost. If no memory tool is used after restart, embeddings go stale silently.
## Solution
Add eager initialization of the memory backend on gateway startup. When `memory.backend === 'qmd'`, create the `QmdMemoryManager` and start its periodic timer immediately on boot.
## Changes
- **New file** `src/gateway/server-startup-memory.ts`: `startMemoryBackend()` function that:
- Resolves configured memory backend from config
- If QMD is configured, calls `getMemorySearchManager()` for the default agent
- Wraps in try/catch so QMD failures don't block gateway startup
- Logs initialization status
- **Updated** `src/gateway/server.impl.ts`: Call `startMemoryBackend()` after sidecars start (preserves existing lazy init for tool calls)
- **Tests** `src/gateway/server-startup-memory.test.ts`: Verify memory backend initialization logic
## Impact
- QMD embeddings stay fresh after every gateway restart
- No impact on existing lazy init behavior for memory tools
- QMD init failures logged but don't prevent gateway startup
Fixes #10797
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
- Adds a gateway boot hook (`startGatewayMemoryBackendOnBoot`) to eagerly initialize QMD memory when configured, so periodic update/embed timers are armed after restarts.
- Updates `getMemorySearchManager` to dedupe concurrent QMD initialization via an in-flight promise cache, and improves QMD boot-update behavior to not block interval retries.
- Extends memory backend resolver with a clarifying note and adds targeted Vitest coverage for boot init behavior, QMD init deduping, and timer arming on boot-update failure.
<h3>Confidence Score: 3/5</h3>
- This PR is directionally correct but has lifecycle/dedup edge cases that could cause incorrect logging or duplicate background work.
- Core change (eager QMD init on boot) matches intent and tests cover key paths, but the fire-and-forget boot init isn’t tied into restart/close lifecycle and the new `backend` field is optional, which can misclassify successful QMD init as fallback. There’s also a small robustness issue around clearing the in-flight cache on synchronous construction failures.
- src/gateway/server.impl.ts, src/gateway/server-startup-memory.ts, src/memory/search-manager.ts
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#9149: Fix: Allow QMD backend to work without OpenAI auth
by vishaltandale00 · 2026-02-04
80.7%
#17657: fix: clear QMD manager cache on in-process restart (SIGUSR1)
by IrriVisionTechnologies · 2026-02-16
80.4%
#11179: fix(memory): replace confusing "No API key" errors in memory tools ...
by liuxiaopai-ai · 2026-02-07
77.5%
#21471: fix: check QMD backend before memory search config
by lbo728 · 2026-02-20
75.9%
#11364: fix(memory/qmd): prevent cascading failure when query fails or retu...
by blazerui · 2026-02-07
74.8%
#20125: fix(doctor): skip memorySearch provider check when using QMD backend
by brandonwise · 2026-02-18
74.5%
#9624: fix(memory): resolve QMD search returning empty results [AI-assisted]
by kowshik24 · 2026-02-05
73.9%
#22937: fix: remove legacy unsuffixed QMD collections on upgrade
by sud0n1m-ziggy · 2026-02-21
73.5%
#6060: feat(onboarding): add Memory Optimization step to onboarding wizard
by GodsBoy · 2026-02-01
73.5%
#10591: feat(hooks): add session-start-memory bundled hook
by morningstar-daemon · 2026-02-06
73.2%