polarmem
polarmem
Local-first memory engine for AI agents. Your agent's entire long-term memory in one small file — embeddings stored in polar-quantized form.
Why polarmem
Private by default — a single SQLite file on your disk, local ONNX embeddings, no cloud calls, no API keys.
Compact — polar quantization packs each embedding into a fraction of its float32 size while keeping recall close to exact search (see benchmark below).
Human-like recall — results are ranked by semantic similarity × recency × usage frequency, the same mix that makes a memory feel "top of mind." Outdated facts are superseded, not deleted, so history stays intact.
Benchmark
Recall@10 on synthetic clustered data (dim 384, 5000 vectors, 20 clusters).
Reproduce with benchmarks/bench_quantization.py
(relative link — if it 404s, e.g. on PyPI, run the script from a clone):
python benchmarks/bench_quantization.pyMethod | Bytes/vector | Recall@10 |
float32 (exact) | 1536 | 1.000 |
int8 | 384 | 0.983 |
binary (sign) | 48 | 0.427 |
polar 8/8 | 388 | 0.987 |
polar 8/4 | 292 | 0.947 |
polar 4/4 | 196 | 0.865 |
Polar 8/8 matches int8's footprint with slightly better recall. Polar 8/4
and 4/4 open up intermediate size/quality points that int8 and binary
simply don't offer — useful when you want to shrink storage further
without falling off the binary cliff (recall collapses to 0.427 there).
angle_bits/radius_bits are a tunable knob on PolarMem and
PolarQuantizer (default 8/8; 8/4 is a good default if you want tighter
storage and can accept a small recall hit).
Honest positioning
Polar quantization follows the approach in "PolarQuant: Leveraging Polar Transformation for Efficient Key Cache Quantization" (arXiv:2502.00527, arXiv preprint). The recall scoring mechanics are inspired by "Generative Agents: Interactive Simulacra of Human Behavior" (Park et al., 2023, arXiv:2304.03442). polarmem's contribution is packaging this into a persistent, local-first memory product for AI agents — not inventing the underlying quantization or scoring techniques.
Install
pip install polarmemNot yet published to PyPI. Until then, install from source:
git clone <this-repo>
cd polarmem
pip install -e .Contributing? This is a src-layout package, so pip install -e . alone
won't put polarmem on the test runner's path with dev tooling — run
pip install -e .[dev] before pytest.
Connect to Claude Code
Add polarmem as an MCP server:
{
"mcpServers": {
"polarmem": {
"command": "polarmem-mcp",
"env": { "POLARMEM_DB": "C:/Users/you/.polarmem/memory.db" }
}
}
}This exposes six tools: remember, recall, forget, supersede,
stats, and digest. Call digest once at the start of a session to
prime the agent's context with its most relevant memories.
Python API
from polarmem import PolarMem
with PolarMem("project.mem") as mem:
result = mem.remember("The staging DB migrated to us-east-1 on 2026-03-01")
print(result["conflicts"]) # candidate memories this may contradict
hits = mem.recall("where is the staging database")
for h in hits:
print(h["score"], h["text"])
mem.forget(hits[0]["id"])
print(mem.stats())CLI
polarmem remember "text to store" # store a fact
polarmem recall "query" [--limit N] # search memory
polarmem stats # count, db size, quantization settings
polarmem viz [--out FILE] # render the polar memory map to HTML
polarmem export PATH # dump memory to diffable JSONL
polarmem import PATH # load memory from JSONLConfigure with environment variables: POLARMEM_DB (db path, defaults to
~/.polarmem/memory.db) and POLARMEM_EMBEDDER (set to hash to use the
offline test embedder instead of the local ONNX model).
Team memory via git
Embeddings aren't exported — only text and metadata — so the JSONL is small, diffable, and independent of any particular model or bit-depth:
polarmem export mem.jsonl # dump your memory
git add mem.jsonl && git commit -m "share memory" # commit + push
git pull # teammate pulls
polarmem import mem.jsonl # teammate re-embeds locally; conflicts: first import winsPolar map
polarmem viz renders a self-contained HTML page: angle encodes the
memory's meaning cluster (2D projection of the embedding space), radius
encodes age, and point size encodes how often the memory has been
recalled. Useful for eyeballing what an agent actually remembers.
How it works
Text is embedded locally (bge-small, 384 dimensions, ONNX via fastembed — no network calls after the first model download).
The embedding is passed through a random rotation, then split into 2D pairs and converted to polar coordinates (angle, radius) per pair.
Angles and radii are quantized to 4 or 8 bits each and packed into a compact blob stored in SQLite.
The rotation matrix is persisted alongside the database — QR decomposition isn't guaranteed bit-identical across BLAS builds, so re-deriving it from a seed wouldn't reliably decode old blobs.
Recall is two-stage: a fast angular scan over decoded vectors narrows to a candidate pool, then similarity × recency × frequency reranks that pool for the final results.
Limitations
The default embedding model is English-optimized (bge-small-en-v1.5).
One PolarMem instance should own a db file at a time — it assumes exclusive access, not a lock. Concurrent instances against the same file are not supported; they tolerate deletes, but adds made by another instance become visible only after reopen.
Tested up to roughly 104 memories per db; larger scales are untested.
Not yet published to PyPI — install from source.