In-memory search, next to your code.

kurn is an in-memory search engine for fast fuzzy and exact retrieval over application-owned collections. Product names, customers, domains, denylists — whatever short-string collection your application owns. Run it as a sidecar or embed the Go library; declared analyzers and typed payload filters shape retrieval, atomic refresh lands a new collection at once, and every answer carries the exact data and configuration version that produced it.

installGo 1.26+
go install github.com/kurn-dev/kurn/cmd/kurnd@latest
Read the source

Five minutes from install to a matching answer — see the docs.
Closed-source embedding needs a commercial licence — ops@kurn.it.

What it does

Fuzzy and exact retrieval
IDF-weighted character n-grams for typo-tolerant short-string search, plus microsecond exact membership and optional parent-domain fallback — one engine, selected per collection.
Typed filters before top-K
Declare payload paths once, then narrow retrieval with type-exact equality or bounded IN sets. Unknown names and malformed expressions fail closed; filtering never changes similarity scores.
Atomic, versioned refresh
Build a disposable artifact from your system of record and publish it to every instance. Candidates and their complete content-and-configuration version come from the same atomic snapshot.
A compact operating model
Application-owned short-string collections stay resident on one node. Run independent replicas for availability or throughput; kurn does not shard collections or coordinate a search cluster.
how well does it actually match? — measured, 5 Aug 2026 open
five lists · 148,837 entries · 191,166 keys

RECALL      40 real entries per list, name mangled, must still be found
  exact                   100%     median score 100
  drop a letter          99.5%                   90
  swap two letters       95.5%                   79
  doubled letter          100%                   90
  dropped vowels         94.0%                   84
  reversed name order     100%                  100
  first + last name only 98.5%                  100
  phonetic (ph→f, ck→k)  98.5%                  100

PRECISION   60 invented names, asked of each list separately
  threshold 0.60          5.7%     matched anything   (1.7% eu … 11.7% csl)
  threshold 0.50         25.7%
  threshold 0.45         40.7%

LATENCY     one name, adding lists
  leie                  83,639 entries      p50 0.22 ms
  + sdn + un            91,848              p50 0.36 ms
  + csl                117,769              p50 0.56 ms
  + eu                 148,837              p50 0.64 ms   p95 1.67 ms

THROUGHPUT  4 vCPU, every query against all five lists
  1 client                                   1,208 queries/s
  8 clients                                  5,034 queries/s

MEMORY      all five lists resident                128 MB

One session on one idle 4 vCPU server, over loopback, against the five public lists built from the publishers' own files with the mappings in the repo. Latency is the median of three runs and moves about ±15% between them. Reversed order scores 100 because the person-name analyzer sorts tokens before matching, not because the grams ignore order; the false-positive column is why 0.6 is the default threshold and not 0.45, and why its spread across lists is shown — a denser corpus produces more false matches.

Calibrate on your own labels. Sweep caller-chosen n-gram thresholds over one immutable collection snapshot to compare truth-ID recall, misses, returned-candidate burden, and truth rank.