AI & ML — ADVANCED
Vector Databases in Production: Quantization & Metadata Filtering Code
Two things separate a toy vector search from a production one: how you shrink a billion vectors down to something that fits in memory, and how you make sure a filter condition actually changes which results come back — not just which ones get relabeled afterward.
The Quick Answer
Product quantization can shrink a vector from 512 bytes down to 8 bytes — a real, verified 64× compression ratio — by replacing each vector with a small set of learned codes instead of its raw floating-point values, trading a controlled amount of recall for a massive memory reduction. Separately, metadata filtering has to be applied together with the similarity search, not as an afterthought — otherwise the single most similar vector can silently vanish from your results because it failed a filter condition that was checked too late.
Product Quantization, Worked
Take a 128-dimensional embedding stored as float32 — 4 bytes per dimension, 512 bytes total. Product quantization splits that vector into smaller sub-vectors, and replaces each sub-vector with the ID of its closest match in a small, pre-learned codebook — an 8-bit code, 1 byte, per sub-vector.
# Original vector: 128 dimensions, float32 (4 bytes each)
original_bytes = 128 * 4
print(original_bytes)
# 512
# Product-quantized: split into 8 sub-vectors, each replaced by a single
# 8-bit code (1 byte) pointing into a pre-learned codebook
compressed_bytes = 8 * 1
print(compressed_bytes)
# 8
compression_ratio = original_bytes / compressed_bytes
reduction_pct = (1 - compressed_bytes / original_bytes) * 100
print(f"{compression_ratio}x compression, {reduction_pct:.1f}% reduction")
# 64.0x compression, 98.4% reductionThis isn’t a hypothetical number — Pinecone’s own published benchmark on the SIFT1M dataset (1 million 128-dimensional vectors) measured an uncompressed index at 256 MB shrinking to 6.5 MB with product quantization — a 98.4% reduction, matching the math above exactly.
Source: Pinecone, “Product Quantization: Compressing High-Dimensional Vectors by 97%”
Compression level is a dial, not a single setting — try the options below and watch storage size and recall move together.
Metadata Filtering, With Code
A real vector database query almost always combines a similarity search with a metadata filter. Here’s the actual pattern (using Pinecone’s Python client syntax, one of the most common in production):
response = index.query(
vector=query_embedding,
top_k=5,
filter={
"genre": {"$eq": "action"},
"year": {"$gte": 2020},
},
include_metadata=True,
)The filter dictionary and the query vector are sent together, in the same call — the database applies both conditions as part of one search, not as two separate steps you glue together yourself. Here’s why that matters, worked out on 3 candidate documents:
documents = [
{"id": "doc-1", "genre": "action", "year": 2019, "score": 0.91},
{"id": "doc-2", "genre": "action", "year": 2023, "score": 0.87},
{"id": "doc-3", "genre": "drama", "year": 2024, "score": 0.95}, # highest similarity!
]
def passes_filter(doc):
return doc["genre"] == "action" and doc["year"] >= 2020
matches = [doc for doc in documents if passes_filter(doc)]
print(matches)
# [{'id': 'doc-2', 'genre': 'action', 'year': 2023, 'score': 0.87}]“doc-3” has the highest raw similarity score (0.95) of all three — it would win a plain, unfiltered search outright. But it’s a drama, not action, so it never appears in the final result at all. This is exactly the scenario the pre-filter vs. post-filter decision from the Intermediate level is actually managing: get the strategy wrong at scale, and you either waste time scanning documents that were always going to be filtered out, or you risk running an ANN search whose entire top-k candidate pool fails the filter, returning far fewer results than requested.
Fun Fact
Scalar quantization’s 4x compression (float32 to int8) sounds modest next to product quantization’s 64x — but it’s usually the safer default in production, precisely because it loses far less recall for a much smaller (but still real) memory win.
Test Yourself
In the worked product quantization example, what is the compression ratio going from 512 bytes to 8 bytes per vector?
What does scalar quantization (float32 to int8) achieve?
In the metadata filtering code example, why does the highest-similarity document sometimes NOT appear in the final results?
What is the general trade-off shown in the quantization trade-off demo?
Why would a production system choose product quantization over storing full-precision vectors?