memory-optimization
Skill19 starsChanged 3 months agoMITView on GitHub
Tune moflo's memory stack for speed, RAM, and index quality. Covers HNSW parameters (M, efConstruction, ef), vector quantization, batch operations, and common bottlenecks. Use when scaling past ~100k entries or when search latency regresses.
In this repository30 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- src/CLAUDE.mdCLAUDE.md
- communeSkill
- connector-builderSkill
- distillSkill
- divineSkill
- eldarSkill
- flflSkill
- flo-simplifySkill
- floSkill
- floSkill
- guidanceSkill
- healerSkill
- luminariumSkill
- meditateSkill
- memory-patternsSkill
- memory-teamSkill
- memory-worktreeSkill
- optimize-learningsSkill
- perf-auditSkill
- publishSkill
- quickenSkill
- reasoningbank-intelligenceSkill
- reset-epicSkill
- spell-builderSkill
- spell-scheduleSkill
- test-gapsSkill
- vector-searchSkill
- verifySkill
- wardSkill
The file
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 0 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 8
When the default moflo memory settings stop being enough — past ~100k entries, or when p95 search latency climbs — these are the levers.
- Very specific: line 112
Don't rebuild the index on every test: Use a module-level singleton + beforeAll.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
MoFlo Memory Optimization
When the default moflo memory settings stop being enough — past ~100k entries, or when p95 search latency climbs — these are the levers.
HNSW Parameters
HNSW has three knobs. They trade build time, query time, memory, and recall.
import { HNSWIndex } from 'moflo/dist/src/cli/memory/index.js';
const index = new HNSWIndex({
dimensions: 1536, // must match your embedding model
maxElements: 1_000_000, // pre-allocated capacity
M: 16, // graph connectivity (default 16)
efConstruction: 200, // build-time search width (default 200)
metric: 'cosine', // 'cosine' | 'l2' | 'ip'
});| Knob | Higher | Lower | When to change |
M | better recall, more RAM (~2×M pointers per point) | less RAM, worse recall | Bump to 32–64 if recall@10 < 0.95; drop to 8 if memory-bound |
efConstruction | better index quality, slower build | faster build, worse queries | 200–400 is sweet spot; only lower in test fixtures |
ef (search-time, passed to search()) | better recall, slower queries | faster queries, worse recall | Start at 2×k, raise until recall plateaus |
Rule of thumb: M and efConstruction are set once. ef is the runtime dial.
Quantization
moflo memory supports scalar quantization (Float32 → Int8) for a ~4× memory reduction with a ~1-2% recall hit. Turn it on when the index doesn't fit comfortably in RAM.
const index = new HNSWIndex({
dimensions: 1536,
maxElements: 5_000_000,
quantization: {
enabled: true,
type: 'scalar', // scalar (Int8) is the supported path
rebuildThreshold: 10_000,
},
});Measure recall before/after on your own query distribution — public benchmarks don't predict your domain.
Batch Operations
Single-entry writes pay the HNSW insert cost per call. For bulk ingest, batch:
const entries: Array<[string, Float32Array]> = buildCorpus();
// Parallelise at the adapter level; don't await sequentially.
await Promise.all(
entries.map(([id, vec]) => index.addPoint(id, vec))
);
// Or via MCP for moflo-native batch into .swarm/memory.db:
await mcp.memory_store(/* … */); // upsert: true + Promise.all is fineFor >10k entries, prefer bin/build-embeddings.mjs / bin/index-all.mjs — they stream in batches with a progress bar and skip unchanged chunks via a hash file.
Caching
MofloDbAdapter has a built-in LRU cache (default 10k entries, 5-min TTL):
import { MofloDbAdapter } from 'moflo/dist/src/cli/memory/index.js';
const store = new MofloDbAdapter({
cacheEnabled: true,
cacheSize: 50_000, // scale with working set, not total corpus
cacheTtl: 10 * 60_000, // 10 minutes
});Cache hits on exact keys bypass HNSW entirely. If your workload is read-heavy and hits a narrow keyspace, this is the cheapest win.
Measuring
npx vitest bench src/cli/memory/benchmarks/vector-search.bench.tsThe bench prints linear vs HNSW times for 1k and 10k vectors. Run it before and after any parameter change — "it felt faster" is not a benchmark.
For production memory stats:
const stats = await mcp.memory_stats({});
// { entryCount, indexSize, cacheHitRate, avgSearchMs, … }Common Bottlenecks
| Symptom | Likely cause | Fix |
| Cold-start of 5s on first search | HNSW loading from disk | Share a single instance via beforeAll in tests; keep the adapter resident in long-running processes |
Search latency climbs linearly with limit | Over-fetching and re-ranking on the hot path | Lower limit; raise threshold to prune |
| Inserts slow past ~100k entries | maxElements too close to entry count → reallocation | Set maxElements to 2× expected corpus |
| High RSS on a small corpus | Vector dimension mismatch with index | Confirm dimensions matches embedder output (OpenAI = 1536, local models vary) |
Anti-Patterns
- Don't rebuild the index on every test. Use a module-level singleton +
beforeAll. HNSW cold-boot is ~5s. - Don't raise
efglobally. Raise it on the specific queries that need recall. Default is fine for 90% of calls. - Don't quantize a small corpus. Below ~500k vectors the RAM saving doesn't justify the recall cost.
- Don't measure in dev mode. The memory stack behaves differently under
NODE_ENV=production; benches should match the target.
See Also
memory-patternsskill — API usage and namespace designvector-searchskill — RAG-specific patterns on top of the optimized indexsrc/cli/memory/benchmarks/— runnable benches for every knob above
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

