Numbered steps and database icons for a practical tutorial on vector databases
Tutorials
Intermediate
9 min read Updated

Vector Databases Explained: A Practical Tutorial (2026)

Master vector databases from first principles. Compare HNSW vs DiskANN indexing, benchmark Qdrant vs pgvector, and build production RAG in Python.

Vector Databases Embeddings RAG AI Infrastructure Semantic Search

Vector databases are specialized storage engines engineered to store, index, and query high-dimensional numerical vectors using geometric similarity search rather than exact relational matching. They form the foundational data retrieval backbone for modern agentic workflows, semantic search, and retrieval-augmented generation.

Traditional relational databases optimize for structured schemas, B-tree lookups, and deterministic equality filters. In contrast, modern AI applications require semantic similarity matching across millions of floating-point representations generated by neural models.

Key Takeaways

  • Vector databases index dense numerical embeddings to execute approximate nearest neighbor search across high-dimensional semantic spaces.
  • HNSW indexing delivers 2ms to 5ms p50 query latencies but requires 10 to 12 GB of RAM per million 1536-dimensional vectors.
  • Modern workloads under 10 million vectors frequently deploy pgvector to maintain ACID compliance within existing PostgreSQL clusters.
  • Massive multi-tenant systems leverage dedicated engines like Qdrant or Pinecone for hardware-accelerated metadata filtering and horizontal sharding.

What Are Vector Databases and How Do Embeddings Work?

A vector database stores numerical arrays called embeddings that capture the conceptual meaning and semantic relationships of raw unstructured text, images, or audio. When machine learning models process text, they project contextual relationships into multi-thousand-dimensional coordinate spaces where semantically related entities cluster together geometrically.

Traditional databases operate on keyword equality and lexical stems. If a user queries for “automobile repair manual,” a keyword index fails to match documents containing “car maintenance handbook” unless complex synonym dictionaries exist. Neural embeddings resolve this lexical gap by assigning proximate coordinate vectors to synonymous concepts.

Engineers building agent systems rely on production RAG code snippets to bridge embedding generation with downstream storage. Standard OpenAI models generate 1536-dimensional arrays, while frontier architectures frequently operate between 768 and 3072 floating-point values per token sequence.

from openai import OpenAI

client = OpenAI()

response = client.embeddings.create(
    model="text-embedding-3-large",
    input="What is a vector database?",
    dimensions=1536
)

embedding = response.data[0].embedding
print(f"Generated dimensions: {len(embedding)}")

This comprehensive vector database tutorial demonstrates how these arrays move from raw model outputs into persistent indexing structures. Understanding this lifecycle enables architects to design resilient retrieval pipelines that scale reliably.

How Approximate Nearest Neighbor Search Operates Under the Hood

Approximate nearest neighbor search trades mathematical perfection for logarithmic query latency, evaluating graph neighborhoods rather than performing exhaustive linear scans across entire datasets. An exact k-nearest neighbor calculation requires computing distance across every stored vector, demanding O(N) comparisons that collapse throughput on large collections.

To maintain sub-10ms response times, vector engines calculate geometric distance using standardized metrics. The three dominant distance functions are cosine similarity, Euclidean distance (L2), and dot product.

Cosine similarity evaluates the angle between two vectors regardless of magnitude, producing scores from -1.0 to 1.0. Euclidean distance computes straight-line distance across dimensional coordinates, where smaller numerical outputs indicate closer semantic proximity. Dot product measures both angle and magnitude, functioning identically to cosine similarity when vectors have a normalized unit length of one.

Engineers seeking an architectural overview of dimensional math can study our vector embeddings guide for deep mathematical foundations. In production vector embeddings semantic search, pre-normalized embeddings enable engines to replace expensive square root calculations with accelerated SIMD matrix operations.

import numpy as np

def cosine_similarity(vector_a: np.ndarray, vector_b: np.ndarray) -> float:
    dot_product = np.dot(vector_a, vector_b)
    norm_a = np.linalg.norm(vector_a)
    norm_b = np.linalg.norm(vector_b)
    return float(dot_product / (norm_a * norm_b))

Production pipelines process millions of comparisons per query. Specialized indexing structures ensure that similarity evaluation touches only a tiny fraction of total records.

Indexing Architecture: HNSW vs IVFPQ vs DiskANN in 2026

Modern vector indexing balances three conflicting engineering variables: query latency, recall accuracy, and memory consumption. Selecting the appropriate algorithm dictates operational costs and scaling boundaries.

The Hierarchical Navigable Small World (HNSW) algorithm serves as the primary standard across contemporary search systems. As documented in the foundational Malkov and Yashunin HNSW Paper on arXiv, HNSW constructs multi-layered geometric graphs where upper layers act as express routing corridors with sparse long-range connections. Lower layers contain dense local clustering graphs that progressively refine nearest candidates.

However, the hnsw indexing algorithm imposes significant memory overhead. For 1,000,000 vectors with 1536 dimensions, raw float32 representations require 6.14 GB of storage. Graph edges, forward pointers, and metadata caches expand the required working memory to 10-12 GB RAM per 1M vectors.

[Layer 2: Sparse Highway]   ● ───────────────> ● ───────────────> ●
                             │                  │                  │
[Layer 1: Medium Routing]    ● ─────> ● ──────> ● ─────> ● ─────> ●
                             │        │         │        │         │
[Layer 0: Dense Base Graph]  ● ──> ● ─┴─> ● ──> ● ─┴─> ● ─┴─> ● ──> ●

Inverted File with Product Quantization (IVFPQ) solves memory constraints by partitioning data into Voronoi cells and compressing vectors into centroid codebooks. IVFPQ slashes RAM consumption by up to 80%, though it incurs a 5% to 12% drop in recall under heavy concurrency.

DiskANN represents the modern enterprise solution for billion-scale datasets. DiskANN stores compressed routing graphs in RAM while keeping full-precision vector data on NVMe SSDs, delivering sub-15ms latencies without multi-terabyte memory clusters.

Vector Database Benchmark Comparison: Qdrant, pgvector, Milvus, and Pinecone

Choosing between dedicated vector engines and integrated relational extensions depends on concurrency targets, dataset size, and operational complexity. Comparing pgvector vs pinecone highlights the trade-off between transactional simplicity and specialized retrieval performance.

Engineering evaluations published in the Qdrant Official Documentation demonstrate that Rust-based native engines sustain 2ms to 4ms p50 latencies during rigorous metadata filtering workloads. Meanwhile, managed platforms outlined in the Pinecone Architecture Documentation decouple indexing compute from underlying cloud object storage to deliver elastic auto-scaling.

Engine Architecture Type p50 Latency (1M Vectors) Memory Footprint Primary Strength Best Production Use Case
Qdrant Native Rust (Self-Hosted/Cloud) 2–4ms Medium (Scalar Quantization) Payload filtering speed High-concurrency agent backends
pgvector PostgreSQL C Extension ~5ms High (In-RAM HNSW graphs) ACID transactional safety Workloads under 10M vectors
Pinecone Serverless Cloud Platform 4–12ms Managed Cloud Zero infrastructure maintenance Rapid RAG application launches
Milvus Distributed Go/C++ Cluster ~4ms High (Distributed nodes) Billion-scale sharding Enterprise-wide vector search
Weaviate Go-based Native Engine ~8ms Medium (Modular storage) Native hybrid BM25 search Multimodal semantic retrieval

Relational databases with vector capabilities provide immense developer velocity. Teams avoid running secondary synchronization pipelines between transactional systems and external vector indices.

Dedicated engines remain essential when application traffic exceeds 3,000 queries per second or requires microsecond-level payload filtering across multi-tenant enterprise accounts.

Step-by-Step Code Implementation with Python and pgvector

Implementing vector search in PostgreSQL requires configuring the extension, defining table schemas with vector column types, and writing cosine distance queries. The open-source pgvector GitHub Repository details installation commands across major Linux distributions and managed cloud providers.

Developers building complete conversational tools can follow our guide to build a RAG chatbot tutorial to connect database queries with generative LLMs. Below is a production-ready implementation demonstrating table creation, indexing, and querying using Python and psycopg3.

import psycopg
from pgvector.psycopg import register_vector

DATABASE_URL = "postgresql://postgres:postgres@localhost:5432/vectordb"

with psycopg.connect(DATABASE_URL) as conn:
    register_vector(conn)
    with conn.cursor() as cur:
        # Enable vector extension and create table
        cur.execute("CREATE EXTENSION IF NOT EXISTS vector;")
        cur.execute("""
            CREATE TABLE IF NOT EXISTS documents (
                id BIGSERIAL PRIMARY KEY,
                content TEXT NOT NULL,
                category VARCHAR(50),
                embedding vector(1536)
            );
        """)
        
        # Build HNSW index with cosine distance
        cur.execute("""
            CREATE INDEX IF NOT EXISTS documents_hnsw_idx 
            ON documents USING hnsw (embedding vector_cosine_ops)
            WITH (m = 16, ef_construction = 64);
        """)
        conn.commit()

def query_similar_documents(query_vector: list, limit: int = 5):
    with psycopg.connect(DATABASE_URL) as conn:
        register_vector(conn)
        with conn.cursor() as cur:
            # Cosine distance operator is <=>
            cur.execute("""
                SELECT id, content, category, 1 - (embedding <=> %s) AS similarity
                FROM documents
                WHERE category = 'technical'
                ORDER BY embedding <=> %s
                LIMIT %s;
            """, (query_vector, query_vector, limit))
            return cur.fetchall()

Setting m = 16 and ef_construction = 64 establishes balanced graph construction parameters. Increasing these values improves recall accuracy during runtime queries while slightly increasing index generation duration.

Production Pitfalls: Memory Thrashing, Quantization Loss, and Metadata Filtering

Deploying rag retrieval augmented generation pipelines at enterprise scale introduces edge-case failure modes that rarely surface during local prototyping. Identifying these bottlenecks early prevents severe system degradations.

Memory thrashing occurs when the collective size of HNSW graphs and metadata pointers exceeds available physical RAM. The operating system begins swapping memory pages to disk, causing query latencies to spike from 5ms to over 800ms. Applying 8-bit scalar quantization compresses vector footprints by 75% with less than 1.5% recall loss, protecting memory limits.

Metadata filtering introduces another common production pitfall known as filter dilution. Post-filtering strategies search the nearest vector graph first and subsequently discard items that fail metadata conditions, frequently yielding empty result sets. Single-stage filtered HNSW graphs evaluate only valid matching nodes, guaranteeing the requested result count.

Systems that balance retrieval volume against context window sizing trade-offs achieve superior response fidelity. Retrieving high-relevance chunks prevents overflowing model context buffers with low-utility conversational noise.

[!TIP] For datasets exceeding 5 million records, implement hybrid search combining BM25 keyword matching with dense vector retrieval using Reciprocal Rank Fusion (RRF). This eliminates semantic blind spots for exact SKU codes, part numbers, and error traces.

Frequently Asked Questions

What is the primary difference between a vector database and a relational database?

Relational databases index structured fields using B-trees for exact equality and range queries. Vector databases index high-dimensional numerical arrays using approximate nearest neighbor graphs to calculate geometric distance.

When should engineering teams choose pgvector over a dedicated vector database?

Teams should adopt pgvector when existing operational infrastructure relies on PostgreSQL and vector collections remain below ten million items. Dedicated engines become necessary when query concurrency exceeds several thousand requests per second or multi-node clustering is required.

How does product quantization reduce vector database RAM consumption?

Product quantization breaks high-dimensional floating-point vectors into smaller sub-vectors and maps each sub-vector to a quantized centroid index. This technique slashes memory footprints by 70% to 85% while retaining over 90% retrieval recall.

Why does cosine similarity give identical results to dot product on normalized vectors?

Cosine similarity calculates the dot product divided by the product of both vector Euclidean lengths. When vectors have a unit length of one, the denominator equals one, making dot product mathematically identical to cosine similarity.

Vector Databases Embeddings RAG AI Infrastructure Semantic Search

Found this helpful? Share it with others.

Raj avatar

Raj

Founder, AI Agents Kit

Raj is the founder of AI Agents Kit, where he writes hands-on guides on AI agents, agent frameworks, Model Context Protocol (MCP), prompt engineering and developer tooling. He builds and tests the tools he covers and focuses on practical, working examples for developers and teams adopting agentic AI.

AI Agents LLMs Prompt Engineering Python TypeScript