Vector search on object storage

A self-hosted, multi-tenant hybrid search engine for teams that want vector and full-text retrieval on object storage. LanceDB provides the search layer; a tiered RAM + NVMe cache keeps hot traffic fast while inactive namespaces retain near-zero idle cost.

72 µs
Warm query latency (repeated query)
25x
ANN index speedup on cold queries
0
Object-storage requests per cache hit
3
Search modes: vector, FTS, hybrid

How it works

Firn stores every namespace under its own object-storage prefix using LanceDB as the storage engine. A tiered cache powered by foyer sits in front of the backend, serving repeated queries from RAM or NVMe in microseconds instead of milliseconds. Single-vector queries can also opt into semantic caching, where a near-duplicate query may reuse a previous top-k result when its vector clears your cosine-similarity threshold. Writes automatically invalidate both cache layers for the affected namespace, because the cache key carries the Lance table version and every committed write advances it.

The result: your data lives cheaply on object storage, but hot and near-duplicate queries can feel local. The /metrics endpoint shows exactly how many backend requests the exact and semantic cache layers are saving you.

Firn runs against AWS S3, MinIO, Cloudflare R2, Tigris, DigitalOcean Spaces, or native Google Cloud Storage. Switching backends is an environment-variable change; see the backend configuration recipes. The local quickstart uses a published Docker image and MinIO, so there is no Rust build step.

Production hardening includes optional bearer-token authentication, read/write and admin scope separation, rate limiting, Prometheus metrics, and background operation tracking. See configuration and deployment.

Documentation

Who Firn is for

Firn is designed for self-hosted and BYO-cloud search: multi-tenant SaaS products, private RAG systems, and teams replacing an always-on OpenSearch, Elasticsearch, Vespa, or custom vector-search service where idle cost and operational weight matter.

It is not a hosted SaaS product and it does not try to replace every search platform. OpenSearch and Elasticsearch have broader operational ecosystems; Vespa has deeper ranking and real-time serving capabilities. Firn's focus is a smaller, deployable service with explicit object-storage economics, hybrid retrieval, and namespace isolation.

Start in minutes

git clone https://github.com/gordonmurray/firnflow
cd firnflow
docker compose up -d
curl http://localhost:3000/health

Then follow the quickstart to insert vectors, run hybrid search, and verify cache savings. For embedded Python use, install firn from PyPI.

Current scope
Firn is pre-1.0 and currently assumes one authoritative server process per bucket. The Arrow import route is insert-only, and per-row deletion and arbitrary user-defined metadata columns are not yet part of the API. See the README for the full limitations and storage trade-offs.

Performance on real AWS S3

Benchmarked with 100,000 vectors at 1536 dimensions (OpenAI embedding size) against eu-west-1 S3.

PhasePathp50 latency
Linear scanCold (S3)25.14 s
Linear scanWarm (cache)66 µs
IVF_PQ indexedCold (S3)979 ms
IVF_PQ indexedWarm (cache)72 µs

Without an index, each cache miss costs 25 seconds. With IVF_PQ, that drops to under 1 second. For repeated queries the cache serves the stored result without re-running the search, bringing latency to microseconds regardless of index type.

Key technologies