memspine

The memory layer for AI agents in production

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.

timekindidtext
09:14:02turn75173310Ana: we adopted a greyhound called Pixel last weekend
09:14:31turn9509bd23Ana: she needs a vet, somewhere open on Saturdays
09:14:33tool_call697ea0fafind_vets(city=Lisbon, open=saturday) -> Clinica Arroios, VetLuz
09:15:10turnb8533f46Ana: book Clinica Arroios for this Saturday at ten
09:15:12tool_call740c7d03book_vet(Clinica Arroios, 2026-10-10 10:00) -> confirmed A-2291
09:15:13factd53b6b8bAna owns a greyhound named Pixel
09:15:14factb41bdb35Ana prefers Saturday appointments
09:15:15fact3dce87e5Pixel has a vet appointment at Clinica Arroios on 2026-10-10 at 10:00, booking A-2291
09:41:50turnaf2d5cc8Ana: my number is 912 555 019, text me the day before
09:41:52factc3d7a7afText 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.

timekindidtextrecall
09:14:02turn75173310Ana: we adopted a greyhound called Pixel last weekend
09:14:31turn9509bd23Ana: she needs a vet, somewhere open on Saturdays
09:14:33tool_call697ea0fafind_vets(city=Lisbon, open=saturday) -> Clinica Arroios, VetLuz
09:15:10turnb8533f46Ana: book Clinica Arroios for this Saturday at ten
09:15:12tool_call740c7d03book_vet(Clinica Arroios, 2026-10-10 10:00) -> confirmed A-2291
09:15:13factd53b6b8bAna owns a greyhound named Pixel
09:15:14factb41bdb35Ana prefers Saturday appointments
09:15:15fact3dce87e5Pixel has a vet appointment at Clinica Arroios on 2026-10-10 at 10:00, booking A-2291first
09:41:50turnaf2d5cc8Ana: my number is 912 555 019, text me the day before
09:41:52factc3d7a7afText Ana the day before the vet appointmentsecond
$ 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.

timekindidtextrecall
09:14:02turn75173310Ana: we adopted a greyhound called Pixel last weekend
09:14:31turn9509bd23Ana: she needs a vet, somewhere open on Saturdays
09:14:33tool_call697ea0fafind_vets(city=Lisbon, open=saturday) -> Clinica Arroios, VetLuz
09:15:10turnb8533f46Ana: book Clinica Arroios for this Saturday at tenits source
09:15:12tool_call740c7d03book_vet(Clinica Arroios, 2026-10-10 10:00) -> confirmed A-2291its source
09:15:13factd53b6b8bAna owns a greyhound named Pixel
09:15:14factb41bdb35Ana prefers Saturday appointments
09:15:15fact3dce87e5Pixel has a vet appointment at Clinica Arroios on 2026-10-10 at 10:00, booking A-2291answer
09:41:50turnaf2d5cc8Ana: my number is 912 555 019, text me the day before
09:41:52factc3d7a7afText Ana the day before the vet appointmentanswer
$ 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.

timekindidtextafter
09:14:02turn75173310Ana: we adopted a greyhound called Pixel last weekend
09:14:31turn9509bd23Ana: she needs a vet, somewhere open on Saturdays
09:14:33tool_call697ea0fafind_vets(city=Lisbon, open=saturday) -> Clinica Arroios, VetLuz
09:15:10turnb8533f46Ana: book Clinica Arroios for this Saturday at ten
09:15:12tool_call740c7d03book_vet(Clinica Arroios, 2026-10-10 10:00) -> confirmed A-2291
09:15:13factd53b6b8bAna owns a greyhound named Pixel
09:15:14factb41bdb35Ana prefers Saturday appointments
09:15:15fact3dce87e5Pixel has a vet appointment at Clinica Arroios on 2026-10-10 at 10:00, booking A-2291
09:41:50turnaf2d5cc8Ana: my number is 912 555 019, text me the day beforedeleted
09:41:52factc3d7a7afText Ana the day before the vet appointmentkept; 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.

0.889

of the relevant evidence retrieved in the top 20 results on LoCoMo, a public benchmark of long conversations

2.8 ms

median time to search a customer's 10,000 stored events

0

confirmed writes lost when the server is killed; every write is on disk before the reply

60 s

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.

What it gives a business

What each operation guarantees ->

An answer you can trace

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.

Each customer kept apart

Every customer is a separate database with its own keys and limits. A key reads and writes one customer's memory and nothing else.

Deletion that reaches the disk

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.

Recall you can check

Retrieval quality is measured on a public benchmark and published with its method, including the question types where it is weakest.

Your infrastructure

One binary for Linux or macOS, or a container. No other services to run. The server never calls a model and sends nothing anywhere.

Nothing confirmed is lost

A write is on disk before the server replies. Killing the process loses nothing it had confirmed.

Where it fits

Customer support agents

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.

Operations agents

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.

Assistants with long-running work

Carry facts, preferences and decisions from one session to the next without replaying whole transcripts into the prompt.

Measured results

Method and caveats ->

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@20with client-side extractionraw turns
keyword only0.8120.587
embedding only0.8690.787
both, fused0.8890.794

LoCoMo, 10 conversations, 1,536 scored questions, text-embedding-3-small at 384 dimensions.

Install

Full quickstart ->
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"]

How it is checked

What has broken, and when ->

162 automated tests

Plus 50 in the Python and TypeScript SDK suites. Every change runs them, the linters and a container that is started and written through.

Independent review

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 installer, after every release

The command above is run on Ubuntu, AlmaLinux 8 and macOS, and the installed binaries store, recall and delete an event.

What it does not do

All limits ->

Running agents for your customers?

memspine is built by ERP.AI. If you want memory, audit and deletion under your agents without building them yourself, talk to us.