What Is a Vector Database?

QdrantWeaviateVector Search

"Vector database" is one of those terms that sounds more complicated than it is. It keeps showing up in conversations about AI, LLMs, and RAG pipelines, which makes it feel like a new, exotic thing. It's not. The concept is straightforward, and once you see what's actually happening, you'll know exactly when you need one and when you don't.

Contents

What's a Vector?

A vector is an array of numbers. That's it. In the context of databases, a vector represents the meaning of something: a sentence, an image, an audio clip.

Here's how it works. You take a piece of text and run it through an embedding model (a machine learning model trained to understand language). The model outputs an array of floating-point numbers, usually hundreds or thousands of them. This array is the vector, also called an embedding.

The key property: text with similar meaning produces similar numbers. "The cat sat on the mat" and "A kitten was resting on the rug" produce vectors that are close together, even though they share almost no words. "Stock market quarterly earnings report" produces a vector that's far away from both.

Think of it like coordinates. If you plot "cat on mat" and "kitten on rug" on a map, they'd be neighbors. "Stock market report" would be in a different zip code. Except instead of two dimensions (x, y), these maps have hundreds of dimensions. You can't visualize it, but the math works the same way. Closeness means similarity.

A real embedding from all-MiniLM-L6-v2 (a popular lightweight model) is 384 numbers long and looks something like this:

text
[0.0231, -0.0891, 0.0412, 0.1102, -0.0334, ... 379 more numbers]

You don't read these numbers. You don't need to understand what each one means. You just need to know that similar text produces similar arrays, and a vector database can find those similarities fast.

What Does a Vector Database Do?

A vector database stores millions of these vectors and finds the closest ones to any query vector in milliseconds. That's the whole job.

When you search a traditional database, you write WHERE title = 'Alien' or WHERE description LIKE '%space%'. Exact matches, keyword matches. A vector database does something different: you give it a vector (the embedding of your search query), and it returns the vectors that are closest to it by distance. This is called nearest-neighbor search.

The "database" part is mostly about indexing. Comparing your query vector against every stored vector one by one would be slow at scale. Vector databases use specialized index structures (like HNSW graphs) that make approximate nearest-neighbor lookups fast, even over millions of vectors. You trade a tiny bit of precision for orders-of-magnitude speed.

So the workflow is:

  1. Generate an embedding for each piece of content you want to search (documents, products, images)
  2. Store those embeddings in a vector database
  3. When a user searches, generate an embedding for their query
  4. Ask the database: "which stored vectors are closest to this one?"
  5. Return the corresponding content

That's it. The embedding model understands meaning. The database stores vectors and finds nearby points fast.

When You Need One

RAG pipelines. You have a knowledge base (docs, support tickets, internal wikis) and you want an LLM to answer questions about it. You embed all your documents, store the vectors, and when a user asks a question, you find the most relevant documents and feed them to the LLM as context. This is Retrieval-Augmented Generation, and it's the most common reason people reach for a vector database right now.

Semantic search. A user searches for "climate change" and you want to return articles about "global warming," "rising sea levels," and "carbon emissions" even though none of those articles contain the exact phrase "climate change." Keyword search can't do this. Vector search can, because the embeddings for all of these concepts are close together.

Recommendations. "Show me products similar to this one." Embed your product catalog, find the vectors closest to the product the user is looking at, and you have recommendations without building a collaborative filtering pipeline.

Image and audio similarity. Anything that can be converted into an embedding can be searched. Image embedding models turn photos into vectors. Audio models do the same for sound. A reverse image search is just nearest-neighbor lookup on image embeddings.

When You Don't

If keyword search works fine. If your users search for product names, order IDs, or exact phrases, a traditional search engine like Meilisearch or even SQL LIKE queries will be simpler and more predictable. Don't add complexity you don't need.

If your data is structured. "Find all orders from the last 30 days where the total exceeds $500." That's SQL. A vector database can't help here. Vectors encode meaning, not structured relationships.

If you don't have an embedding pipeline. Vector databases don't generate vectors for you (with one exception: Weaviate's built-in vectorizer modules). You need an embedding model, either a hosted API like OpenAI or a local model. If you're not ready to set that up, you're not ready for a vector database.

If it's just trending. Don't add a vector database to your stack because you saw it in a blog post (ironic, I know). Add it when you have a concrete search or similarity problem that keyword matching can't solve. You'll know when you hit that wall.

The Options We Support

We support two vector databases in SpinDB and Layerbase Cloud: Qdrant and Weaviate. They take different approaches.

Qdrant

Qdrant is the bring-your-own-vectors engine. You generate embeddings however you want (OpenAI, Cohere, a local model), hand them to Qdrant, and it stores and searches them. Written in Rust, single binary, low memory footprint. Schemaless payloads: attach any JSON metadata to your vectors without defining a schema first.

Pick Qdrant when you already have an embedding pipeline and you want a fast, focused vector store with minimal setup.

Getting Started with Qdrant walks through building a full semantic movie search.

Weaviate

Weaviate overlaps with Qdrant, but it puts more of the search pipeline inside the database: built-in vectorizer modules (insert plain text, Weaviate generates embeddings for you), typed schemas, GraphQL, and hybrid search with a tunable alpha parameter. Qdrant can also support hybrid retrieval with dense and sparse vectors, but Weaviate makes the integrated path more direct.

Pick Weaviate when you want the database to handle embeddings, or when your users need both keyword matching and semantic search.

Getting Started with Weaviate covers hybrid search and schema design. Qdrant vs Weaviate runs the same queries through both engines side by side if you're deciding between them.

Try It: Spin Up Qdrant and Search

This takes about two minutes. Install SpinDB, start a Qdrant instance, insert three vectors, and query for the nearest one. (What is SpinDB?)

bash
npm i -g spindb
spindb create qdrant1 -e qdrant --start

Verify it's running:

bash
spindb url qdrant1
text
http://127.0.0.1:6333

Now create a quick project:

bash
mkdir vector-demo && cd vector-demo
pnpm init
pnpm add @qdrant/js-client-rest @xenova/transformers
pnpm add -D tsx typescript

Create demo.ts:

typescript
import { QdrantClient } from '@qdrant/js-client-rest'
import { pipeline } from '@xenova/transformers'

const client = new QdrantClient({ url: 'http://localhost:6333' })
const embedder = await pipeline(
  'feature-extraction',
  'Xenova/all-MiniLM-L6-v2',
)

async function embed(text: string): Promise<number[]> {
  const out = await embedder(text, { pooling: 'mean', normalize: true })
  return Array.from(out.data as Float32Array)
}

// Create a collection
await client.createCollection('docs', {
  vectors: { size: 384, distance: 'Cosine' },
})

// Insert three documents
const docs = [
  'How to reset your password',
  'Configuring two-factor authentication',
  'Billing FAQ and payment methods',
]

await client.upsert('docs', {
  wait: true,
  points: await Promise.all(
    docs.map(async (text, i) => ({
      id: i,
      vector: await embed(text),
      payload: { text },
    })),
  ),
})

// Search for the nearest match
const query = 'I forgot my login credentials'
const [queryVector] = [await embed(query)]
const { points } = await client.query('docs', {
  query: queryVector,
  limit: 3,
  with_payload: true,
})

console.log(`Query: "${query}"\n`)
for (const point of points) {
  const p = point.payload as Record<string, unknown>
  console.log(`  ${point.score?.toFixed(3)}  ${p.text}`)
}

Run it:

bash
npx tsx demo.ts
text
Query: "I forgot my login credentials"

  0.582  How to reset your password
  0.401  Configuring two-factor authentication
  0.187  Billing FAQ and payment methods

"I forgot my login credentials" shares zero words with "How to reset your password," but the embedding model knows they mean the same thing. That's vector search in 30 lines.

Wrapping Up

A vector database stores arrays of numbers that represent meaning and finds the closest matches fast. If your search problem is about meaning rather than exact words, that's when you need one. If keyword search is working fine, keep using it.

To manage your local instance:

bash
spindb stop qdrant1    # Stop the server
spindb start qdrant1   # Start it again
spindb list            # See all your database instances

SpinDB manages 20+ engines from one CLI, so Qdrant can sit next to PostgreSQL, Redis, or whatever else your stack needs. Layerbase Desktop wraps the same thing in a GUI on macOS, and Layerbase Cloud is there if you want managed instances.

Something not working?