memspine records what each agent saw, did and concluded, separately for every customer. It finds the relevant events in milliseconds, traces each conclusion back to its sources, and erases a customer's data from disk on request. It runs as one binary in your own infrastructure.
One agent session, as memspine stored it: what the customer said, what the agent ran, and what it concluded. The lines at the left tie each conclusion to the events it came from.
| time | kind | id | text | |
|---|---|---|---|---|
| 09:14:02 | turn | 75173310 | Ana: we adopted a greyhound called Pixel last weekend | |
| 09:14:31 | turn | 9509bd23 | Ana: she needs a vet, somewhere open on Saturdays | |
| 09:14:33 | tool_call | 697ea0fa | find_vets(city=Lisbon, open=saturday) -> Clinica Arroios, VetLuz | |
| 09:15:10 | turn | b8533f46 | Ana: book Clinica Arroios for this Saturday at ten | |
| 09:15:12 | tool_call | 740c7d03 | book_vet(Clinica Arroios, 2026-10-10 10:00) -> confirmed A-2291 | |
| 09:15:13 | fact | d53b6b8b | Ana owns a greyhound named Pixel | |
| 09:15:14 | fact | b41bdb35 | Ana prefers Saturday appointments | |
| 09:15:15 | fact | 3dce87e5 | Pixel has a vet appointment at Clinica Arroios on 2026-10-10 at 10:00, booking A-2291 | |
| 09:41:50 | turn | af2d5cc8 | Ana: my number is 912 555 019, text me the day before | |
| 09:41:52 | fact | c3d7a7af | Text Ana the day before the vet appointment |
Ask in words, by meaning, or both. The agent gets back the two events that matter out of the session, ranked.
| time | kind | id | text | recall | |
|---|---|---|---|---|---|
| 09:14:02 | turn | 75173310 | Ana: we adopted a greyhound called Pixel last weekend | ||
| 09:14:31 | turn | 9509bd23 | Ana: she needs a vet, somewhere open on Saturdays | ||
| 09:14:33 | tool_call | 697ea0fa | find_vets(city=Lisbon, open=saturday) -> Clinica Arroios, VetLuz | ||
| 09:15:10 | turn | b8533f46 | Ana: book Clinica Arroios for this Saturday at ten | ||
| 09:15:12 | tool_call | 740c7d03 | book_vet(Clinica Arroios, 2026-10-10 10:00) -> confirmed A-2291 | ||
| 09:15:13 | fact | d53b6b8b | Ana owns a greyhound named Pixel | ||
| 09:15:14 | fact | b41bdb35 | Ana prefers Saturday appointments | ||
| 09:15:15 | fact | 3dce87e5 | Pixel has a vet appointment at Clinica Arroios on 2026-10-10 at 10:00, booking A-2291 | first | |
| 09:41:50 | turn | af2d5cc8 | Ana: my number is 912 555 019, text me the day before | ||
| 09:41:52 | fact | c3d7a7af | Text Ana the day before the vet appointment | second |
$ curl -s localhost:7777/v1/memory/recall -H "$K" -H "$J" \
-d '{"text":"vet appointment booking","k":2}' \
| jq -r '.hits[] | [(.score*1e4|round/1e4), .kind, .event_id[0:8], .text[0:44]] | @tsv'
3.2165 fact 3dce87e5 Pixel has a vet appointment at Clinica Arroi
2.5492 fact c3d7a7af Text Ana the day before the vet appointment
The same question, with its sources. The conclusion comes back together with the customer's instruction and the tool call it was derived from, so a reviewer can see what the agent knew.
| time | kind | id | text | recall | |
|---|---|---|---|---|---|
| 09:14:02 | turn | 75173310 | Ana: we adopted a greyhound called Pixel last weekend | ||
| 09:14:31 | turn | 9509bd23 | Ana: she needs a vet, somewhere open on Saturdays | ||
| 09:14:33 | tool_call | 697ea0fa | find_vets(city=Lisbon, open=saturday) -> Clinica Arroios, VetLuz | ||
| 09:15:10 | turn | b8533f46 | Ana: book Clinica Arroios for this Saturday at ten | its source | |
| 09:15:12 | tool_call | 740c7d03 | book_vet(Clinica Arroios, 2026-10-10 10:00) -> confirmed A-2291 | its source | |
| 09:15:13 | fact | d53b6b8b | Ana owns a greyhound named Pixel | ||
| 09:15:14 | fact | b41bdb35 | Ana prefers Saturday appointments | ||
| 09:15:15 | fact | 3dce87e5 | Pixel has a vet appointment at Clinica Arroios on 2026-10-10 at 10:00, booking A-2291 | answer | |
| 09:41:50 | turn | af2d5cc8 | Ana: my number is 912 555 019, text me the day before | ||
| 09:41:52 | fact | c3d7a7af | Text Ana the day before the vet appointment | answer |
$ curl -s localhost:7777/v1/memory/recall -H "$K" -H "$J" \
-d '{"text":"vet appointment booking","k":2,"hops":1}' \
| jq -r '.hits[] | [.kind, .event_id[0:8], (.via // "-")[0:8], .text[0:52]] | @tsv'
fact 3dce87e5 - Pixel has a vet appointment at Clinica Arroios on 20
fact c3d7a7af - Text Ana the day before the vet appointment
turn b8533f46 3dce87e5 Ana: book Clinica Arroios for this Saturday at ten
tool_call 740c7d03 3dce87e5 book_vet(Clinica Arroios, 2026-10-10 10:00) -> confi
The customer asks for their phone number to be removed. One request deletes the event from every answer and from the files on disk; the search of the data directory that follows finds nothing.
| time | kind | id | text | after | |
|---|---|---|---|---|---|
| 09:14:02 | turn | 75173310 | Ana: we adopted a greyhound called Pixel last weekend | ||
| 09:14:31 | turn | 9509bd23 | Ana: she needs a vet, somewhere open on Saturdays | ||
| 09:14:33 | tool_call | 697ea0fa | find_vets(city=Lisbon, open=saturday) -> Clinica Arroios, VetLuz | ||
| 09:15:10 | turn | b8533f46 | Ana: book Clinica Arroios for this Saturday at ten | ||
| 09:15:12 | tool_call | 740c7d03 | book_vet(Clinica Arroios, 2026-10-10 10:00) -> confirmed A-2291 | ||
| 09:15:13 | fact | d53b6b8b | Ana owns a greyhound named Pixel | ||
| 09:15:14 | fact | b41bdb35 | Ana prefers Saturday appointments | ||
| 09:15:15 | fact | 3dce87e5 | Pixel has a vet appointment at Clinica Arroios on 2026-10-10 at 10:00, booking A-2291 | ||
| 09:41:50 | turn | af2d5cc8 | Ana: my number is 912 555 019, text me the day before | deleted | |
| 09:41:52 | fact | c3d7a7af | Text Ana the day before the vet appointment | kept; its link to the deleted event is gone |
$ grep -rl "912 555 019" data
data/00000000-0000-0000-0000-000000000042/events.ffs.qlog
$ curl -s -X DELETE "localhost:7777/v1/memory/event/$E9?purge=true" -H "$K"; echo
{"deleted":true,"purged":true}
$ grep -rl "912 555 019" data; echo "grep exit $?"
grep exit 1
A real session against memspine 0.2.2, not a mock-up. The full transcript has every request and response.
of the relevant evidence retrieved in the top 20 results on LoCoMo, a public benchmark of long conversations
median time to search a customer's 10,000 stored events
confirmed writes lost when the server is killed; every write is on disk before the reply
default time for a deleted event's bytes to leave the disk
How each figure was measured, and where the numbers are weaker, is in the reference.
When an agent states something, the fact it relied on links to the conversation turns and tool calls it was derived from. One request returns the chain.
Every customer is a separate database with its own keys and limits. A key reads and writes one customer's memory and nothing else.
Forgetting an event removes it from every answer at once and from the files on disk within a minute. The tests check that the bytes are gone.
Retrieval quality is measured on a public benchmark and published with its method, including the question types where it is weakest.
One binary for Linux or macOS, or a container. No other services to run. The server never calls a model and sends nothing anywhere.
A write is on disk before the server replies. Killing the process loses nothing it had confirmed.
Keep each customer's history across sessions. When a case is escalated, show what the agent was told and what it looked up before it answered.
Record every action an agent takes in your systems together with the instruction and the data behind it, so the action can be audited later.
Carry facts, preferences and decisions from one session to the next without replaying whole transcripts into the prompt.
Retrieval is scored on LoCoMo: 1,540 questions over 10 long conversations, counting how much of each question's evidence is among the 20 events returned.
With the client extracting facts and rewriting queries, as the benchmark harness does, memspine retrieves 0.889 of the evidence. Storing raw turns and sending the question as it is, 0.794.
End to end, with a model answering from the retrieved events and a judge marking it under a published rubric, 0.786 of answers were accepted in a June run on an earlier version of the engine. The paper that published the rubric reports 0.669 for its own system with the same answer model and judge.
| evidence recall@20 | with client-side extraction | raw turns |
|---|---|---|
| keyword only | 0.812 | 0.587 |
| embedding only | 0.869 | 0.787 |
| both, fused | 0.889 | 0.794 |
LoCoMo, 10 conversations, 1,536 scored questions, text-embedding-3-small at 384 dimensions.
curl -fsSL https://memspine.com/install.sh | sh
Version 0.2.2 for Linux x86_64 (glibc 2.17 or newer) and macOS arm64. Two binaries in ~/.local/bin, checked against a published checksum, no root.
$ MEMSPINE_BIND=127.0.0.1:7777 MEMSPINE_EMBEDDING_DIM=4 \
~/.local/bin/memspine-server > memspine.log 2>&1 &
$ sleep 1; curl localhost:7777/health
{"service":"memspine-server","status":"ok","version":"0.2.2"}
$ K="Authorization: Bearer 00000000-0000-0000-0000-000000000042"
$ J="Content-Type: application/json"
$ TURN=$(curl -s localhost:7777/v1/memory/event -H "$K" -H "$J" \
-d '{"kind":"turn","embedding":[0.9,0.1,0.2,0.1],
"text":"Ana: we adopted a greyhound called Pixel last weekend"
}' | jq -r .event_id)
$ curl -s localhost:7777/v1/memory/event -H "$K" -H "$J" \
-d '{"kind":"fact","embedding":[0.8,0.2,0.1,0.1],
"text":"Ana owns a dog named Pixel","properties":{
"source_event_ids":["'"$TURN"'"]}}'
{"event_id":"b5ea3003-7681-4632-a015-5ec4fdec7595"}
$ curl -s localhost:7777/v1/memory/recall -H "$K" -H "$J" \
-d '{"text":"which dog does Ana have","k":1,"hops":1}' \
| jq -c '.hits[] | [.kind, .text]'
["fact","Ana owns a dog named Pixel"]
["turn","Ana: we adopted a greyhound called Pixel last weekend"]
Plus 50 in the Python and TypeScript SDK suites. Every change runs them, the linters and a container that is started and written through.
Before 0.2.2, two rounds of reviewers went looking for defects. A finding counted only once a second reviewer reproduced it, and each one is in the changelog.
The command above is run on Ubuntu, AlmaLinux 8 and macOS, and the installed binaries store, recall and delete an event.
memspine is built by ERP.AI. If you want memory, audit and deletion under your agents without building them yourself, talk to us.