Vector Databases Explained: How AI Stores and Searches Embeddings
Modern AI applications increasingly work with embeddings.
An embedding converts information such as text, images, or audio into a numerical vector that represents useful patterns and semantic relationships.
For example:
"How do I reset my password?"
can be converted into a vector such as:
[0.12, -0.43, 0.71, 0.08, ...]
If an application has thousands or millions of these vectors, it needs an efficient way to store them and find the vectors most similar to a user's query.
This is where vector databases become important.
A vector database is a database system designed to store, index, and search high-dimensional vectors efficiently.
In this article, we will explore:
What vector databases are
Why traditional databases are different
How vectors are stored
Similarity search
Distance metrics
Vector indexes
PostgreSQL with pgvector
Python examples
Semantic search
Metadata filtering
RAG systems
Hybrid search
Vector database architecture
Performance considerations
Practical limitations
What Is a Vector Database?
A vector database stores numerical vectors and provides efficient similarity search.
A simplified record might look like:
Document:
"Python is a programming language."
Embedding:
[0.12, -0.43, 0.71, 0.08, ...]
Instead of searching only for exact words, the database can search for vectors that are close to a query vector.
The basic workflow is:
User Query
↓
Embedding Model
↓
Query Vector
↓
Vector Database
↓
Similarity Search
↓
Relevant Results
This is the foundation of many AI-powered search systems.
Why Do We Need Vector Databases?
Traditional databases are excellent for structured queries.
For example:
SELECT *
FROM products
WHERE category = 'laptop';
This searches for an exact value.
But imagine asking:
"Find products similar to a lightweight computer
for programming."
The database needs to understand semantic relationships.
An embedding model can convert the query into a vector:
Query
↓
Embedding Model
↓
[0.21, -0.14, 0.72, ...]
The vector database then searches for nearby vectors.
This is called vector similarity search.
Traditional Database vs Vector Database
A traditional relational database stores structured information such as:
ID
Name
Price
Category
Date
A vector database stores information such as:
ID
Text
Embedding
Metadata
The two approaches solve different problems.
Traditional Search
"python tutorial"
may look for matching words.
Vector Search
"How can I start learning Python?"
can find content such as:
"Beginner's guide to Python programming"
even though the wording is different.
What Is a Vector?
A vector is simply a sequence of numbers.
For example:
[0.12, 0.45, -0.32]
Real embeddings are usually much larger:
[
0.123,
-0.452,
0.781,
0.091,
...
]
The number of values is called the vector dimension.
For example:
VECTOR(384)
means the vector contains 384 numerical values.
The dimension depends on the embedding model.
How Vector Search Works
Suppose we have three document embeddings:
Document A → [0.1, 0.2, 0.7]
Document B → [0.8, 0.1, 0.1]
Document C → [0.2, 0.3, 0.6]
The user query becomes:
Query → [0.15, 0.25, 0.65]
The vector database compares the query against the stored vectors.
Conceptually:
Query
|
+---- Document A → Similar
|
+---- Document B → Less Similar
|
+---- Document C → Very Similar
The database returns the closest vectors.
Similarity and Distance
Vector databases use mathematical metrics to determine how close vectors are.
Common metrics include:
Cosine similarity
Euclidean distance
Dot product
Manhattan distance in some specialized applications
The appropriate metric depends on the embedding model and use case.
Cosine Similarity
Cosine similarity measures the angle between two vectors.
The formula is:
cosine_similarity(A, B)
=
(A · B) / (||A|| × ||B||)
Conceptually:
Similarity close to 1
↓
Very similar direction
Similarity close to 0
↓
Less similar
Cosine similarity is widely used for text embeddings.
Euclidean Distance
Euclidean distance measures the straight-line distance between vectors.
For two vectors:
A = [a1, a2, a3]
B = [b1, b2, b3]
the distance is:
√((a1-b1)² + (a2-b2)² + (a3-b3)²)
Smaller distance generally means the vectors are closer.
Dot Product
The dot product is:
A · B
For:
A = [1, 2, 3]
B = [4, 5, 6]
we get:
1×4 + 2×5 + 3×6
which equals:
32
Some embedding systems are designed to work efficiently with dot-product similarity.
What Is a Vector Index?
Searching every vector individually becomes expensive when a database contains millions of vectors.
A simple approach would be:
Query
↓
Compare with Vector 1
↓
Compare with Vector 2
↓
Compare with Vector 3
↓
...
↓
Compare with Vector 1,000,000
This is called a brute-force or exact search approach.
It can become expensive at large scale.
Vector indexes improve search performance by organizing vectors so that nearby candidates can be found more efficiently.
Approximate Nearest Neighbor Search
Many vector databases use Approximate Nearest Neighbor (ANN) algorithms.
Instead of guaranteeing an exhaustive comparison against every vector, ANN methods efficiently search for highly similar candidates.
Common indexing approaches include:
HNSW
IVF
Product Quantization
Disk-based ANN techniques
The exact implementation varies between databases.
The trade-off is generally:
More search accuracy
↕
More computation
versus:
Faster search
↕
Potentially approximate results
HNSW
One popular vector indexing technique is Hierarchical Navigable Small World, commonly abbreviated as HNSW.
HNSW organizes vectors into graph-like layers.
Conceptually:
Layer 2
A -------- B
\ /
\ /
\ /
C
Layer 1
A -- B -- C -- D -- E
The search can move through the graph rather than comparing against every vector.
HNSW is widely used for approximate nearest-neighbor search.
Vector Database Architecture
A simplified vector database looks like:
Application
|
↓
Search Request
|
↓
┌────────────────────┐
│ Vector Database │
└────────────────────┘
|
┌────────────┼────────────┐
↓ ↓ ↓
Vector Data Metadata Index
|
↓
Similarity Search
|
↓
Top-K Results
The vector database manages both vector storage and efficient retrieval.
PostgreSQL + pgvector
You do not always need a separate specialized vector database.
PostgreSQL can support vector search through the pgvector extension.
This is especially useful when your application already uses PostgreSQL.
The architecture becomes:
Application
↓
PostgreSQL
├── Normal relational data
├── Metadata
└── Embeddings
This can simplify application architecture.
Creating a Vector Table
With pgvector installed, a table can be created like:
CREATE EXTENSION IF NOT EXISTS vector;
Then:
CREATE TABLE documents (
id BIGSERIAL PRIMARY KEY,
content TEXT NOT NULL,
embedding VECTOR(384)
);
Here:
VECTOR(384)
means that each embedding must contain 384 dimensions.
The dimension must match the embedding model being used.
Insert a Vector
A vector can be stored alongside document content.
INSERT INTO documents (
content,
embedding
)
VALUES (
'Python is a popular programming language.',
'[0.12, -0.43, 0.71, ...]'
);
In production applications, embeddings are normally generated programmatically rather than manually entered.
Generate Embeddings With Python
Install:
pip install sentence-transformers
Then:
from sentence_transformers import SentenceTransformer
model = SentenceTransformer(
"all-MiniLM-L6-v2"
)
text = "Python is a programming language."
embedding = model.encode(text)
print(embedding)
print("Dimensions:", len(embedding))
The generated vector can then be stored in a vector database.
Store Embeddings With Python
For PostgreSQL, you can use a database driver such as psycopg.
Install:
pip install psycopg
A simplified example:
import psycopg
from sentence_transformers import SentenceTransformer
model = SentenceTransformer(
"all-MiniLM-L6-v2"
)
text = "Python is a programming language."
embedding = model.encode(text).tolist()
connection = psycopg.connect(
"postgresql://user:password@localhost/mydb"
)
with connection.cursor() as cursor:
cursor.execute(
"""
INSERT INTO documents (
content,
embedding
)
VALUES (%s, %s)
""",
(text, embedding)
)
connection.commit()
connection.close()
In a real application, use environment variables for database credentials rather than putting passwords directly into source code.
Searching a Vector Database
Suppose the user asks:
How can I learn Python?
The query is converted into an embedding.
Then PostgreSQL can search for nearby vectors.
With pgvector, a query can look conceptually like:
SELECT
id,
content
FROM documents
ORDER BY embedding <=> '[QUERY_VECTOR]'
LIMIT 5;
The <=> operator is used by pgvector for cosine distance.
The exact operator should match the distance metric and index you have chosen.
What Does Top-K Mean?
Vector searches commonly return the top K results.
For example:
LIMIT 5
means:
Return the 5 best matching results.
The workflow is:
Query
↓
Vector Search
↓
Rank Results
↓
Top 5
For example:
1. Python beginner guide
2. Python programming tutorial
3. Introduction to Python
4. Python syntax reference
5. Python development guide
Metadata Filtering
Vector search becomes more useful when combined with metadata.
Imagine storing articles with:
title
category
language
date
embedding
A search can be restricted to a category.
For example:
SELECT
id,
content
FROM documents
WHERE category = 'programming'
ORDER BY embedding <=> '[QUERY_VECTOR]'
LIMIT 5;
This combines:
Metadata Filtering
+
Vector Similarity
Why Metadata Matters
Imagine an e-commerce website containing:
10 million products
A user searches:
"lightweight laptop for programming"
The application could filter by:
category = laptop
price < 1500
availability = true
and then perform semantic vector search among the remaining products.
This can improve both relevance and efficiency.
Semantic Search With a Vector Database
A complete semantic search system looks like:
Documents
↓
Chunking
↓
Embedding Model
↓
Vector Database
↓
Vector Index
↓
User Query
↓
Query Embedding
↓
Similarity Search
↓
Top-K Results
This architecture can power AI search systems.
Vector Databases and RAG
Vector databases are especially important for Retrieval-Augmented Generation, or RAG.
RAG allows an LLM to retrieve relevant information before generating an answer.
The architecture is:
Documents
↓
Chunking
↓
Embeddings
↓
Vector Database
↓
Stored Vectors
User Question
↓
Question Embedding
↓
Vector Search
↓
Relevant Documents
↓
Prompt + Retrieved Context
↓
LLM
↓
Generated Answer
The vector database acts as the retrieval layer.
Example RAG System
Suppose a company has:
Employee Handbook
Product Documentation
Technical Manuals
Support Articles
Company Policies
A user asks:
How many vacation days do employees receive?
The system does not need to send every document to the LLM.
Instead:
Question
↓
Embedding
↓
Vector Search
↓
Vacation Policy
↓
LLM
↓
Answer
This can reduce unnecessary context and improve retrieval.
Chunking Documents
Large documents are usually divided into smaller chunks before creating embeddings.
For example:
Large PDF
↓
Page extraction
↓
Paragraph splitting
↓
Chunk 1
Chunk 2
Chunk 3
...
Each chunk receives an embedding.
A record may contain:
{
"content": "Employees receive 20 days...",
"embedding": [...],
"document_id": 42,
"page": 15
}
Metadata makes it possible to identify where the retrieved information came from.
Example Chunking Code
A simple token-based chunker can be created like this:
def chunk_text(text, chunk_size=500):
words = text.split()
chunks = []
for i in range(
0,
len(words),
chunk_size
):
chunk = " ".join(
words[i:i + chunk_size]
)
chunks.append(chunk)
return chunks
text = """
This is a large document containing
many paragraphs and sections.
"""
chunks = chunk_text(text)
for chunk in chunks:
print(chunk)
print("---")
Production systems often use smarter chunking strategies based on paragraphs, sentences, headings, token counts, or semantic boundaries.
Storing Metadata
A useful vector database record might contain:
id
document_id
title
content
embedding
category
author
page_number
created_at
For example:
document = {
"document_id": 1001,
"title": "Python Tutorial",
"content": "Python is...",
"category": "programming",
"page_number": 5,
"embedding": embedding
}
This information can be returned together with search results.
Vector Search in Python
A simple in-memory vector search can be built before introducing a database.
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
model = SentenceTransformer(
"all-MiniLM-L6-v2"
)
documents = [
"Python is a programming language.",
"FastAPI is a framework for APIs.",
"PostgreSQL is a relational database.",
"React is used for web interfaces."
]
document_embeddings = model.encode(
documents
)
query = "How can I build a Python API?"
query_embedding = model.encode(
[query]
)
scores = cosine_similarity(
query_embedding,
document_embeddings
)[0]
results = sorted(
zip(documents, scores),
key=lambda x: x[1],
reverse=True
)
for document, score in results:
print(
f"{score:.4f} - {document}"
)
This demonstrates the basic idea behind vector database search.
A production database adds persistent storage, indexes, filtering, concurrency, and scalable retrieval.
Exact Search vs Approximate Search
There are two broad approaches to vector search.
Exact Search
Compare the query against every stored vector.
Query
↓
Vector 1
Vector 2
Vector 3
...
Vector N
Advantages:
Exact
Simple
Good for smaller datasets
Disadvantages:
Can become expensive at very large scale
Approximate Search
Use an index to efficiently find likely nearest neighbors.
Query
↓
Vector Index
↓
Candidate Vectors
↓
Top Results
Advantages:
Much faster at large scale
Disadvantages:
Results may be approximate
Index configuration affects performance
Choosing a Vector Database
Popular options include:
PostgreSQL + pgvector
Pinecone
Qdrant
Weaviate
Milvus
Chroma
The best option depends on your project.
For a small application already using PostgreSQL, pgvector can be an attractive choice.
For specialized large-scale vector workloads, dedicated vector databases may provide more specialized capabilities.
PostgreSQL vs Dedicated Vector Database
PostgreSQL + pgvector
Advantages:
Existing PostgreSQL ecosystem
Relational data and vectors in one database
SQL queries
Metadata filtering
Convenient for many applications
Potential limitation:
Very large vector workloads may require specialized architecture and tuning
Dedicated Vector Database
Advantages:
Designed specifically around vector workloads
Specialized indexing and retrieval
Can provide scalable vector-search infrastructure
Potential limitation:
Adds another service to your architecture
May increase operational complexity and cost
There is no universal winner.
Hybrid Search
Vector search is powerful, but keyword search is still useful.
Consider a query containing an exact product code:
"Product ABC-123"
A keyword search may be extremely useful because the exact identifier matters.
A semantic search system may focus more on meaning.
A hybrid search system combines both.
User Query
↓
┌────────┴────────┐
↓ ↓
Keyword Search Vector Search
↓ ↓
└────────┬────────┘
↓
Result Ranking
↓
Final Results
This can provide stronger retrieval for many real-world applications.
Reranking
A vector database may return the top 20 candidate documents.
A reranking model can then evaluate those candidates more carefully.
User Query
↓
Vector Search
↓
Top 20 Candidates
↓
Reranker
↓
Top 5 Results
This two-stage architecture is common in sophisticated search systems.
Vector Database Performance
Performance depends on several factors:
Number of vectors
Vector dimensions
Index type
Distance metric
Hardware
Filtering
Query volume
Database configuration
Number of returned results
For example:
10,000 vectors
may be easy to search with brute force.
But:
100,000,000 vectors
requires much more careful architecture.
Memory Usage
Vectors can consume significant storage.
Suppose you have:
1,000,000 vectors
and each vector has:
1,536 dimensions
If each dimension is stored as a 32-bit floating-point number:
1,536 × 4 bytes
=
6,144 bytes
per vector, ignoring additional index and metadata overhead.
For one million vectors:
≈ 6.14 GB
just for the raw vector values.
Indexes and metadata require additional storage.
This demonstrates why vector storage needs to be planned carefully.
Reducing Vector Storage
Some systems use techniques such as:
Quantization
Lower-precision data types
Product quantization
Dimensionality reduction
These can reduce storage and improve performance.
However, reducing precision or dimensionality can affect retrieval quality.
There is usually a trade-off between:
Storage
Performance
Accuracy
Vector Database Security
Vector databases should be treated like any other production database.
Important considerations include:
Authentication
Authorization
Encryption
Network security
Access control
Tenant isolation
Backup
Monitoring
This becomes especially important when embeddings contain information derived from private documents.
An embedding should not automatically be treated as harmless just because it is represented as numbers.
Multi-Tenant Vector Databases
SaaS applications may have multiple customers.
For example:
Company A
├── Documents
└── Embeddings
Company B
├── Documents
└── Embeddings
A search request from Company A must never accidentally retrieve Company B's data.
Metadata filtering can help:
SELECT *
FROM documents
WHERE tenant_id = 123
ORDER BY embedding <=> '[QUERY_VECTOR]'
LIMIT 5;
Proper authorization must still be enforced at the application and database levels.
Common Vector Database Mistakes
Mistake 1: Using the Wrong Embedding Dimension
If the model produces 384 dimensions:
VECTOR(384)
must be used.
Do not mix vectors from incompatible models without a deliberate strategy.
Mistake 2: Ignoring Metadata
Only storing:
embedding
makes it difficult to understand where results came from.
Store useful metadata such as:
document_id
title
category
page
source
Mistake 3: Poor Chunking
Huge chunks may contain too much unrelated information.
Tiny chunks may lose important context.
Chunk size should be tested against your data and retrieval task.
Mistake 4: Returning Too Many Results
Retrieving 100 irrelevant documents does not necessarily improve an LLM response.
Start with a reasonable top-K value and evaluate retrieval quality.
Mistake 5: Treating Similarity as Truth
A high similarity score means the vectors are close according to the chosen metric.
It does not guarantee that the retrieved content is correct.
Practical Vector Search Project
Let's build a small knowledge-search system.
Install:
pip install sentence-transformers scikit-learn
Create:
vector_search.py
Then:
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
model = SentenceTransformer(
"all-MiniLM-L6-v2"
)
documents = [
{
"title": "Python",
"content": "Python is a popular programming language."
},
{
"title": "FastAPI",
"content": "FastAPI is a framework for building APIs with Python."
},
{
"title": "PostgreSQL",
"content": "PostgreSQL is an open-source relational database."
},
{
"title": "React",
"content": "React is a JavaScript library for building user interfaces."
}
]
texts = [
document["content"]
for document in documents
]
embeddings = model.encode(
texts
)
query = input(
"Enter your question: "
)
query_embedding = model.encode(
[query]
)
scores = cosine_similarity(
query_embedding,
embeddings
)[0]
results = sorted(
zip(documents, scores),
key=lambda x: x[1],
reverse=True
)
print("\nSearch Results:\n")
for document, score in results[:3]:
print(
f"Score: {score:.4f}"
)
print(
f"Title: {document['title']}"
)
print(
f"Content: {document['content']}"
)
print()
Try:
How can I build an API using Python?
The FastAPI document should be among the highest-ranked results.
From Prototype to Production
The previous example stores vectors in memory.
A production system can replace the in-memory list with:
PostgreSQL + pgvector
or another vector database.
The architecture becomes:
Web / Mobile App
↓
Backend
↓
Embedding Model
↓
Vector Database
↙ ↘
Vector Index Metadata
↓
Search Results
↓
LLM
↓
Response
This architecture can scale far beyond a simple Python script.
Complete AI Search Architecture
A production AI knowledge platform might use:
┌───────────────┐
│ Documents │
└───────┬───────┘
↓
Text Parser
↓
Chunking
↓
Embedding Model
↓
┌────────────────┐
│ Vector Database│
└───────┬────────┘
│
│
User → Query → Embedding → Search
↓
Retrieved Chunks
↓
Reranker
↓
Context Builder
↓
LLM
↓
AI Response
This architecture is commonly used for enterprise search, documentation assistants, customer-support systems, and RAG applications.
When Should You Use a Vector Database?
A vector database is useful when your application needs to:
Search by semantic meaning
Store large numbers of embeddings
Find similar documents
Build RAG systems
Build recommendation systems
Search images or multimedia
Cluster related content
Perform similarity matching
You may not need one for a simple application containing only a few hundred vectors.
For small datasets, an in-memory index or a regular database extension may be sufficient.
Final Summary
Vector databases provide the storage and search infrastructure required for many modern AI applications.
The basic process is:
Text
↓
Embedding Model
↓
Vector
↓
Vector Database
↓
Vector Index
↓
Similarity Search
↓
Relevant Results
For RAG:
Documents
↓
Chunking
↓
Embeddings
↓
Vector Database
↓
User Question
↓
Query Embedding
↓
Similarity Search
↓
Relevant Context
↓
LLM
↓
Answer
The most important concepts to remember are:
Vector
↓
Numerical representation of data
Vector Database
↓
Database designed to store and search vectors
Similarity Search
↓
Find vectors close to a query vector
Vector Index
↓
Makes large-scale vector search faster
Metadata
↓
Additional information used for filtering and results
RAG
↓
Retrieval + Context + LLM
Hybrid Search
↓
Keyword Search + Vector Search
Vector databases are an important part of the modern AI stack. They provide the connection between embeddings and useful applications, allowing developers to build semantic search engines, document assistants, recommendation systems, AI knowledge bases, and RAG-powered applications.
Once you understand embeddings, vector similarity, indexing, and retrieval, you have the foundation needed to build many of today's practical AI search systems.
