Skip to content

Core concepts

Memory indexes

A memory index is a key like any other. One key holds one index, one index holds many records, and the mode fixed at creation decides which retrieval structures exist inside it.

A key like any other

Memory is a native type, not a service bolted on the side. That means the generic keyspace commands work on it the day you create one: TYPE answers memory, and DEL, EXPIRE, TTL, RENAME, COPY, KEYS, SCAN, and DBSIZE all behave exactly as they do for a hash.

await db.memory.create("user:123", { mode: "HYBRID", dim: 3 });
console.log(await db.type("user:123"));
await db.expire("user:123", 3600);
await db.copy("user:123", "user:123:backup");

The namespace you would otherwise configure is just the key. user:123, session:abc, and agent:support:tickets are three indexes, isolated from one another, discoverable with SCAN.

Modes

One implementation exposes three logical structures. The mode is set at MEM.CREATE and cannot change afterwards, because it decides what gets built as records arrive.

ModeText indexedVector storedMEM.SEARCHMEM.VSEARCHMEM.QUERY
SEARCHYesNoYesErrorKeyword only
VECTORStored, not indexedYesErrorYesVector only
HYBRIDYesYesYesYesFused

HYBRID is the default and the one to reach for. Pick SEARCH when you have no embedding pipeline, and VECTOR when the text is not worth an inverted index, for instance when records are already summarised into vectors elsewhere.

Records

Every record carries the same fields:

FieldTypeNotes
idbytesSupplied with ID, or assigned by the server as a counter
textbytesBinary safe: spaces, newlines, and NUL bytes are all fine
vectorfloat32[dim]Optional; normalised at insert when the metric is cosine
metaflat string pairsOrdered, small, scanned linearly; not JSON
importancefloat 0.0–1.0Defaults to 0.5
created_at / updated_attimestampSet by the server, readable in filters
expire_attimestampOptional per-record TTL, independent of the key's

Ids

Pass ID to control the identity of a record, which makes writes idempotent and lets you update in place. Omit it and Klyro assigns a monotonically increasing id and returns it.

klyro
MEM.ADD user:123 ID pref:db TEXT "Prefers PostgreSQL." FVEC 4 0.1 0.9 0.2 0.4
$6
pref:db

# NX writes only if absent, XX only if present
MEM.ADD user:123 ID pref:db TEXT "Prefers SQLite now." FVEC 4 0.2 0.7 0.1 0.5 XX
$6
pref:db

Metadata

Metadata is flat string pairs, deliberately not JSON. Filtering wants comparable scalars, and values that parse as a number compare numerically while everything else compares as bytes. Set and remove fields after the fact with MEM.SETMETA and MEM.DELMETA.

Importance

Importance is a number between 0 and 1 that you assign when writing. It is the lever for the difference between “the user stated a preference” and “the user said hello”. It contributes to the fused score with its own weight, 0.05 by default.

Per-record TTL

Records expire on their own clock, separate from the key that holds them, so a session memory can lapse without the index going with it.

klyro
MEM.ADD session:abc TEXT "Currently comparing the Pro and Team plans." \
  FVEC 4 0.3 0.4 0.5 0.6 TTL 1800
$1
1

MEM.EXPIRE session:abc 1 3600
:1

# 0 seconds clears the deadline
MEM.EXPIRE session:abc 1 0
:1

Inspecting an index

klyro
MEM.INFO user:123
 1) "mode"          2) "HYBRID"
 3) "dim"           4) (integer) 384
 5) "metric"        6) "COSINE"
 7) "weights"       8) 1) "keyword"   2) "0.35"
                         3) "vector"    4) "0.5"
                         5) "recency"   6) "0.1"
                         7) "importance" 8) "0.05"
 9) "halflife"     10) (integer) 604800
11) "records"      12) (integer) 128
13) "vectors"      14) (integer) 128
15) "terms"        16) (integer) 1904
17) "avg_doc_len"  18) "11.4"
19) "bytes"        20) (integer) 421376

MEM.CARD user:123
:128

MEM.SCAN user:123 0 COUNT 100 FILTER type EQ preference
1) "0"
2) 1) "1"
   2) "pref:db"

MEM.SCAN pages through ids with a resumable cursor and accepts the same filters as a query, which makes it the right tool for audits, exports, and bulk deletes.