Quickstart
Get Firn running locally in under two minutes. All you need is Docker.
Prerequisites
- Docker and Docker Compose V2
1. Clone and start the stack
This launches MinIO (local S3) and the Firn API server together.
git clone https://github.com/gordonmurray/firnflow
cd firnflow
docker compose up --build
Once you see listening on 0.0.0.0:3000, the API is ready. MinIO is available at localhost:9000 (API) and localhost:9001 (console, credentials: minioadmin / minioadmin).
2. Check health
curl http://localhost:3000/health
Expected response:
ok
3. Upsert vectors
Insert a few vectors into the demo namespace. Firn auto-detects the vector dimension from the first upsert.
curl -X POST http://localhost:3000/ns/demo/upsert \
-H 'Content-Type: application/json' \
-d '{
"rows": [
{"id": 1, "vector": [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]},
{"id": 2, "vector": [0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]},
{"id": 3, "vector": [0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0]}
]
}'
Response:
{"upserted": 3}
4. Query for nearest neighbours
Search the demo namespace for the 2 closest vectors.
curl -X POST http://localhost:3000/ns/demo/query \
-H 'Content-Type: application/json' \
-d '{"vector": [1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], "k": 2}'
Response (first query hits S3, populates the cache):
{
"query_id": "a1b2c3d4",
"results": [
{"id": 1, "score": 0.01, "vector": [1.0, 0.0, ...], "text": null},
{"id": 2, "score": 0.99, "vector": [0.0, 1.0, ...], "text": null}
]
}
/metrics.
5. Add text for full-text search
Upsert rows with both vectors and text, then build an FTS index.
# Upsert with text
curl -X POST http://localhost:3000/ns/articles/upsert \
-H 'Content-Type: application/json' \
-d '{
"rows": [
{"id": 1, "vector": [1.0, 0.0, 0.0, 0.0], "text": "Introduction to vector databases"},
{"id": 2, "vector": [0.0, 1.0, 0.0, 0.0], "text": "Full-text search with BM25 scoring"},
{"id": 3, "vector": [0.0, 0.0, 1.0, 0.0], "text": "Hybrid search combines vector and text"}
]
}'
# Build the FTS index (async, returns 202)
curl -X POST http://localhost:3000/ns/articles/fts-index
Then run a text search:
curl -X POST http://localhost:3000/ns/articles/query \
-H 'Content-Type: application/json' \
-d '{"text": "vector databases", "k": 2}'
Or a hybrid search (vector + text together):
curl -X POST http://localhost:3000/ns/articles/query \
-H 'Content-Type: application/json' \
-d '{
"vector": [0.9, 0.1, 0.0, 0.0],
"text": "vector databases",
"k": 2
}'
6. Check the metrics
See exactly how many S3 requests Firn has saved you.
curl -s http://localhost:3000/metrics | grep firnflow
Key lines to look for:
firnflow_cache_hits_total{namespace="demo"} 1
firnflow_cache_misses_total{namespace="demo"} 1
firnflow_s3_requests_total{namespace="demo",operation="query"} 1
The cache miss count stays at 1 no matter how many times you repeat the same query. Every subsequent hit is free.
Next steps
- API reference - all nine endpoints with full request and response schemas
- Configuration - tune cache sizes, connect to AWS S3, and set up different storage backends
- Deployment - run Firn in production with Docker or on Kubernetes
- Monitoring - Prometheus metrics, PromQL examples, and alerting rules