CURRENT TREND INSIGHT
Best open-source vector database setup for small hobby projects Illustration

Best open-source vector database setup for small hobby projects

Direct Summary:

To optimize vector database setup for small hobby projects, developers build localized index layers (using HNSW or IVF architectures) inside databases like pgvector or ChromaDB. These systems map text embeddings into multi-dimensional coordinates, allowing sub-millisecond similarity lookups.

"Simplicity is the ultimate sophistication."

— Leonardo da Vinci

Key Insights

  • Index Parameters: HNSW indexes offer fast retrieval speeds at scale, but require more memory and setup time compared to flat vector scans.
  • VRAM Caching: Store common query vectors in a local memory cache to bypass model calculation latency for repeated searches.
  • Dimensionality Matching: Ensure search query models output the exact coordinate count (e.g. 384 or 1536 dimensions) matching the database.

Running Postgres with pgvector, or standing up a dedicated server like Qdrant or Weaviate, is overkill for a weekend project — a Discord bot with a few thousand FAQ embeddings, a personal notes search tool, a small RAG demo. For that scale, Chroma is the realistic starting point: it's open-source, runs embedded inside your Python process with no separate database server to install or manage, and its own docs describe it as "the open-source data infrastructure for AI" that "comes with everything you need to get started built-in."

Two Client Modes, and Why the Difference Matters

Chroma ships two local client types, and picking the wrong one is the most common hobby-project mistake:

1. chromadb.Client() — runs entirely in memory. Fast to experiment with, but every embedding you added is gone the moment your script exits.

2. chromadb.PersistentClient(path=...) — per Chroma's own docs, data "will be persisted automatically and loaded on start (if it exists)." This is the one you want for anything you plan to reopen tomorrow.

hobby_vector_store.py
import chromadb

# Data is written to and reloaded from this local folder
client = chromadb.PersistentClient(path="./chroma_db")
collection = client.create_collection(name="my_notes")

# Chroma will embed these with its default model if you don't supply vectors
collection.add(
    ids=["note1", "note2"],
    documents=["Meeting notes about the Q3 roadmap", "Grocery list for the weekend"]
)

results = collection.query(query_texts=["what did we decide about the roadmap?"], n_results=1)
print(results)

Under the hood, Chroma's default persistent backend uses an embedded key-value store and its own HNSW implementation, so it's still doing real approximate-nearest-neighbor search — it's just packaged so a local folder on disk (no Docker container, no separate database process) is enough. This is a different tool for a different job than sqlite-vec, the small, dependency-free SQLite extension covered elsewhere on this site for embedding a vector store into an existing SQL app — Chroma is the faster path when your project is *only* about storing and querying embeddings and you don't already have a SQLite database to extend.

Practical Challenge

Create a PersistentClient pointed at a local folder, add 5 short text notes to a collection, close the script, then reopen it and query the collection to confirm the notes are still there without re-adding them.

Concept Check

Why would a hobby project use chromadb.PersistentClient() instead of chromadb.Client()?
Correct! Per Chroma's own docs, the in-memory client is for quick experimentation, while PersistentClient(path=...) writes to a local folder that's automatically reloaded the next time you start the client.
Incorrect. Try again! Hint: the difference is about where the data lives — in the running process's memory, or on disk in a folder you point the client at.

Sources & Further Reading

  • Chroma — Getting Started — official docs describing Chroma as open-source, embeddable AI data infrastructure, with the basic collection/add/query API used above.
  • Chroma — Clients — official docs on the difference between Client(), PersistentClient(), and HttpClient(), including the exact PersistentClient(path=...) syntax used above.
Previous Guide Dashboard Next Guide