- Posted on
- • Artificial Intelligence
Best Vector Databases for Linux
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Best Vector Databases for Linux: Fast, Local, and Bash-Friendly
Your embeddings are ready, your RAG pipeline is underway, and now you need a place to put millions of vectors—locally, fast, and with Linux scripting at the core. Shoving vectors into JSON files won’t cut it; you need a purpose-built vector database that runs well on Linux, plays nicely with Bash, and scales from a laptop to the lab.
This guide helps you choose and quickly stand up the best vector databases for Linux, with copy-paste installs and curl-able examples. You’ll leave with a shortlist, a working instance, and a checklist to benchmark and pick the right fit.
Why vector databases on Linux are worth your time
Performance and control: Local Linux gives you raw IO, predictable latency, and resource control (cgroups, NUMA pinning).
Privacy and cost: Keep embeddings and documents on your own hardware; no egress surprises.
Dev velocity: Bash + containers mean reproducible spins, teardown, and CI-friendly testing.
Versatility: Blend vector search with metadata filtering, hybrid BM25+vector ranking, and transactions where needed.
What “best” means here
We focus on mature, Linux-friendly options you can boot quickly and query with curl or psql:
Qdrant: Rust-based, blazing fast, dead-simple REST.
Weaviate: Schema-first, hybrid search, strong REST/GraphQL.
PostgreSQL + pgvector: If you already love Postgres, get vectors where your data lives.
OpenSearch (k-NN): If you need log/keyword + vector in one cluster.
All four are open source and run great in containers.
Prerequisites: one-time setup on Linux
Choose Podman (rootless-friendly) or Docker. We’ll use Podman in examples.
Install Podman, curl, and jq:
- Debian/Ubuntu
sudo apt update && sudo apt install -y podman curl jq
- Fedora/RHEL/CentOS Stream
sudo dnf install -y podman curl jq
- openSUSE/SLE
sudo zypper refresh && sudo zypper install -y podman curl jq
Optional: install Docker instead (varies by distro)
- Debian/Ubuntu
sudo apt update && sudo apt install -y docker.io
- Fedora
sudo dnf install -y moby-engine
- openSUSE/SLE
sudo zypper install -y docker
Security note: Examples bind to localhost. For remote access, secure with auth, TLS, and firewalls.
1) Qdrant: fast, simple, production-ready REST
When to pick it:
You want speed, a clean REST API, top-tier vector filtering, and easy persistence.
Great for local RAG stores, semantic search over docs, and on-box apps.
Quick start:
podman run -d --name qdrant -p 6333:6333 qdrant/qdrant:latest
Create a collection (3-D demo) and add points:
curl -s -X PUT 'http://localhost:6333/collections/demo' \
-H 'content-type: application/json' \
-d '{ "vectors": { "size": 3, "distance": "Cosine" } }' | jq
curl -s -X PUT 'http://localhost:6333/collections/demo/points?wait=true' \
-H 'content-type: application/json' \
-d '{
"points": [
{"id":1,"vector":[0.1,0.2,0.3],"payload":{"text":"apt cheatsheet"}},
{"id":2,"vector":[0.2,0.1,0.0],"payload":{"text":"dnf tips"}},
{"id":3,"vector":[0.0,0.1,0.2],"payload":{"text":"zypper guide"}}
]
}' | jq
Search by vector:
curl -s -X POST 'http://localhost:6333/collections/demo/points/search' \
-H 'content-type: application/json' \
-d '{ "vector":[0.1,0.18,0.27], "limit": 2, "with_payload": true }' \
| jq '.result[] | {id, score, text: .payload.text}'
Persist data: mount a volume (replace $PWD with your path):
podman rm -f qdrant
podman run -d --name qdrant -p 6333:6333 \
-v $PWD/qdrant_storage:/qdrant/storage \
qdrant/qdrant:latest
2) Weaviate: schema-first with hybrid search options
When to pick it:
- You prefer a schema, GraphQL, hybrid BM25+vector search, and extensibility.
Quick start (no built-in vectorizer, you supply vectors):
podman run -d --name weaviate -p 8080:8080 \
-e AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true \
-e DEFAULT_VECTORIZER_MODULE=none \
-e CLUSTER_HOSTNAME=node1 \
semitechnologies/weaviate:latest
Health check:
curl -s localhost:8080/v1/.well-known/ready && echo
Create a class and insert data with your own vectors:
curl -s -X POST localhost:8080/v1/schema \
-H 'content-type: application/json' \
-d '{
"classes":[
{"class":"Doc","vectorIndexType":"hnsw",
"properties":[{"name":"text","dataType":["text"]}]}
]
}' | jq
curl -s -X POST localhost:8080/v1/objects \
-H 'content-type: application/json' \
-d '{
"class":"Doc",
"properties":{"text":"Linux package managers overview"},
"vector":[0.1,0.2,0.3]
}' | jq
Query with nearVector (GraphQL):
curl -s -X POST localhost:8080/v1/graphql \
-H 'content-type: application/json' \
-d '{
"query":"{ Get { Doc(nearVector:{vector:[0.1,0.18,0.27]}, limit:2) { text _additional { distance } } } }"
}' | jq
Persist data:
podman rm -f weaviate
podman run -d --name weaviate -p 8080:8080 \
-e AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true \
-e DEFAULT_VECTORIZER_MODULE=none \
-e CLUSTER_HOSTNAME=node1 \
-v $PWD/weaviate_data:/var/lib/weaviate \
semitechnologies/weaviate:latest
3) PostgreSQL + pgvector: vectors where your data lives
When to pick it:
You already rely on Postgres for transactions/joins and want vectors without a new service.
Ideal for smaller to mid-scale embeddings or strong relational needs.
Quick start (container with pgvector preinstalled):
podman run -d --name pgvector -e POSTGRES_PASSWORD=secret -p 5432:5432 pgvector/pgvector:pg16
Create extension, table, data, and run a search:
podman exec -i pgvector psql -U postgres -c "
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE items (id bigserial primary key, embedding vector(3), note text);
INSERT INTO items (embedding, note) VALUES
('[0.1,0.2,0.3]', 'apt cheatsheet'),
('[0.2,0.1,0.0]', 'dnf tips'),
('[0.0,0.1,0.2]', 'zypper guide');
SELECT id, note, (embedding <-> '[0.1,0.18,0.27]') AS l2
FROM items
ORDER BY embedding <-> '[0.1,0.18,0.27]' LIMIT 2;"
Optional: install a local psql client
- Debian/Ubuntu
sudo apt install -y postgresql-client
- Fedora/RHEL/CentOS Stream
sudo dnf install -y postgresql
- openSUSE/SLE
sudo zypper install -y postgresql-client
Persist data:
podman rm -f pgvector
podman run -d --name pgvector -e POSTGRES_PASSWORD=secret -p 5432:5432 \
-v $PWD/pg_data:/var/lib/postgresql/data \
pgvector/pgvector:pg16
4) OpenSearch with k-NN: logs, keyword, and vectors together
When to pick it:
- You already use Elasticsearch/OpenSearch for logs/text and want vector search in the same stack.
Quick start (security disabled for local testing only):
podman run -d --name opensearch -p 9200:9200 -p 9600:9600 \
-e "discovery.type=single-node" \
-e "plugins.security.disabled=true" \
-e "OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g" \
opensearchproject/opensearch:2.11.0
Create a k-NN index and load data:
curl -s -X PUT localhost:9200/vectors \
-H 'content-type: application/json' \
-d '{
"settings": {"index.knn": true},
"mappings": {"properties": {
"my_vector": {
"type":"knn_vector",
"dimension":3,
"method":{"name":"hnsw","space_type":"cosinesimil","engine":"nmslib"}
},
"text": {"type":"text"}
}}
}' | jq
curl -s -X POST 'localhost:9200/vectors/_doc/1?refresh=true' \
-H 'content-type: application/json' \
-d '{"text":"apt cheatsheet","my_vector":[0.1,0.2,0.3]}'
curl -s -X POST 'localhost:9200/vectors/_doc/2?refresh=true' \
-H 'content-type: application/json' \
-d '{"text":"dnf tips","my_vector":[0.2,0.1,0.0]}'
curl -s -X POST 'localhost:9200/vectors/_doc/3?refresh=true' \
-H 'content-type: application/json' \
-d '{"text":"zypper guide","my_vector":[0.0,0.1,0.2]}'
k-NN search:
curl -s -X POST 'localhost:9200/vectors/_search' \
-H 'content-type: application/json' \
-d '{
"size":2,
"knn": {"field":"my_vector","query_vector":[0.1,0.18,0.27],"k":2,"num_candidates":3},
"_source":["text"]
}' | jq '.hits.hits[] | {id: ._id, score, text: ._source.text}'
Persist data (mount a volume) and enable security for non-local deployments.
Real-world Linux example: make your notes searchable by meaning
Generate embeddings for your Markdown files with your favorite model (e.g., sentence-transformers).
Store vectors and filenames in Qdrant or Postgres.
Use a Bash function to submit a query vector and open the top hit in $EDITOR.
Sketch:
embed="[0.11,0.19,0.27]" # your query embedding
curl -s -X POST 'http://localhost:6333/collections/notes/points/search' \
-H 'content-type: application/json' \
-d "{ \"vector\": $embed, \"limit\": 5, \"with_payload\": true }" \
| jq -r '.result[].payload.path' | head -1 | xargs -r ${EDITOR:-vim}
Actionable checklist before you decide
1) Match the workload
High QPS with filters? Qdrant/Weaviate.
Strong relational joins/transactions? Postgres + pgvector.
Unified logs + vector? OpenSearch.
2) Choose the right metric
Cosine for normalized embeddings.
Dot/inner product for learned similarity.
L2 for some vision/audio models. Keep it consistent in both DB and model.
3) Tune the index
HNSW M/efConstruction for build speed vs recall.
efSearch/num_candidates for query-time quality/perf.
Use small, representative benchmarks with your vectors.
4) Keep metadata and enable hybrid
Store text, tags, and timestamps for filtering and ranking.
Consider hybrid BM25 + vector rerank in Weaviate/OpenSearch.
5) Test durability and ops
Mount volumes, take snapshots/backups.
Measure memory usage; most vector indexes are RAM-hungry.
Add resource limits (cgroups) and watch IO with iostat/vmstat.
Cleanup
Stop and remove test containers and volumes:
podman rm -f qdrant weaviate pgvector opensearch
rm -rf ./qdrant_storage ./weaviate_data ./pg_data
Conclusion and next step
Pick one and run a one-hour spike:
If you want the simplest and fastest local store, start with Qdrant.
If you like schemas and hybrid search, try Weaviate.
If your data already lives in Postgres, add pgvector.
If you’re centralizing logs and text search, enable OpenSearch k-NN.
Next: wire your embedding generator, import a few thousand vectors, and benchmark with your actual queries. When you’ve got numbers, you’ll have clarity. If you want a follow-up with a Bash-first ingestion and benchmarking script for your chosen database, ask and I’ll share a ready-made template.