$ memista
v0.1.x — experimental — GPL-3.0

A lightweight vector search library for Rust.

memista pairs SQLite for metadata with USearch (HNSW) for similarity search, behind a three-endpoint Actix-web API. Embed the crate, or run the bundled binary as a standalone server. One process, two files on disk.

$ cargo add memista
nearest-neighbour search
$ curl -X POST http://localhost:8083/v1/search \
  -H "Content-Type: application/json" \
  -d '{
    "database_id": "my_app",
    "query": [0.1, 0.2],
    "limit": 5
  }'

// → ranked chunk ids, text, metadata, distance
{
  "results": [
    { "chunk_id": 42, "text": "Hello world", "distance": 0.03 }
  ]
}

What is memista?

memista is a vector search library for Rust. It packages approximate nearest-neighbour search into a single crate: USearch for the index, SQLite for the chunk text and metadata, and Actix-web for a small HTTP layer. Embed it, or run the bundled binary. No separate database to operate.

the index

USearch 2.19.x, HNSW graphs, SIMD via simsimd. Inner-product metric, F32.

the metadata

SQLite table chunks_<id> holds text + metadata. Open it in sqlite3.

the surface

Three endpoints — insert, search, drop — on 127.0.0.1:8083.

the shape

One process. A .db and a .usearch file per partition. That's it.

The problems memista solves

Not every project that needs vector search needs a vector database.

📦

A vector DB is too much machine

the problem

Your app needs retrieval over a few thousand chunks. Standing up a separate vector database — a container, a cluster, a thing to monitor and back up — is disproportionate.

memista's take

memista is a crate. It compiles into your binary, or runs as one small server. A partition is two files you can copy.

When you don't need a vector DB →
🔩

Bolting an index onto SQLite by hand

the problem

You already keep chunk text and metadata in SQLite. Adding ANN search means wiring an index crate, mapping row ids to vector keys, and keeping the two in sync yourself.

memista's take

memista does exactly that wiring: SQLite row id becomes the USearch key on insert, and search hydrates text back from SQLite. You call three endpoints.

How the pieces fit →
💾

Persistence you can't inspect

the problem

Opaque stores make debugging retrieval painful. When a result looks wrong, you want to open the data, not file a support ticket.

memista's take

Metadata is plain SQLite; the index is a <id>.usearch file. Inspect with sqlite3, back up with cp, reason about it on disk.

Persistence & the .usearch file →
🦀

Retrieval that fights your language

the problem

A Rust agent, CLI, or desktop app shouldn't have to shell out to a Python service just to do similarity search.

memista's take

memista is Rust end to end (1.56+). Pull in create_app and AppState and mount the handlers inside your own Actix binary.

Embed as a library →

Insert over HTTP, or embed the crate

The same handlers, two ways to run them. Pick the shape that fits your app.

Standalone server — POST /v1/insert
# Insert chunks: embedding + text + metadata
curl -X POST http://localhost:8083/v1/insert \
  -H "Content-Type: application/json" \
  -d '{
    "database_id": "my_app",
    "chunks": [{
      "embedding": [0.1, 0.2],
      "text": "Hello world",
      "metadata": "{\"source\": \"readme\"}"
    }]
  }'
Embedded library — create_app()
// Mount memista's handlers in your own Actix binary
use memista::{AppState, Config, create_app};
use async_sqlite::{PoolBuilder, JournalMode};
use std::sync::Arc;

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let config = Config::from_env().expect("config");
    let db_pool = PoolBuilder::new()
        .path(&config.database_path)
        .journal_mode(JournalMode::Wal)
        .open().await?;
    let state = Arc::new(AppState { db_pool });

    HttpServer::new(move || create_app(state.clone()))
        .bind((config.server_host.as_str(), config.server_port))?
        .run().await
}

Note: embedding dimensions are hardcoded to 2 in the stock crate — a demo default you edit in IndexOptions::dimensions before shipping. How to change it →

Two well-known pieces, wired together

memista doesn't reinvent the index or the store — it makes them work as one small library.

The whole API surface

Three endpoints on 127.0.0.1:8083. Plus browsable OpenAPI docs at /swagger, /redoc, /rapidoc, /scalar.

POST /v1/insert

Add chunks (embedding + text + metadata) to a partition. Returns the assigned chunk ids.

POST /v1/search

k-nearest-neighbour query against a partition. Returns ranked chunks with text, metadata, and distance.

DELETE /v1/drop

Drop a partition — its SQLite table and its .usearch index file.

Rust 1.56+
minimum supported toolchain
USearch 2.19
HNSW index backend, SIMD via simsimd
~100k
vectors tested (per project README)
3
HTTP endpoints — the whole surface

Honest numbers only. memista is experimental (v0.1.x); we don't publish recall or latency benchmarks we haven't earned.

Ship retrieval in a Rust binary

memista is open source (GPL-3.0). Add the crate, run the server, insert some vectors, and query. No cluster to operate.

Part of Skelf Research

memista is one of a family of small, honest infrastructure tools.

Explore Skelf Research →