Embedding Models Explained (2026): MTEB, Dimensions, Cost and Rerankers
Most embedding models I see in production were chosen the same way: someone opened the MTEB leaderboard, sorted by average, and picked the highest thing with an API. That works, in the sense that search returns results. The trouble shows up later, when queries containing error codes, product SKUs and config keys come back worse than the old keyword search did. This post explains what embedding models actually are, how to choose one in 2026 without being fooled by the leaderboard, what dimensions and Matryoshka truncation cost you in storage, how open and API models compare on price, where rerankers fit, and the unglamorous question of when you have to re-embed everything.
What is an embedding model?
An embedding model turns a piece of text (or an image, or audio) into a fixed-length list of numbers, a vector, such that texts with similar meaning end up close together. "Database refuses connections" and "Postgres is not accepting clients" share almost no words, but a decent model puts them near each other. You compare vectors with cosine similarity or dot product, and a vector index (HNSW in pgvector, or a dedicated vector database) finds the nearest neighbours quickly.
Three things follow from that definition and drive every decision later:
- The vector space is private to the model. Vectors from model A cannot be compared with vectors from model B. Google states this plainly for its own two models:
gemini-embedding-001andgemini-embedding-2have incompatible embedding spaces, so upgrading means re-embedding all existing data. - Queries and documents must go through the same model, often with different prefixes or task types. Many models are trained with an instruction such as "query:" versus "passage:", and dropping it quietly costs recall.
- The model has an input limit. Anything beyond it is truncated or rejected, which is why chunking strategy and model choice are one decision, not two.
Is the MTEB leaderboard reliable for choosing a model?
MTEB is the standard public benchmark for text embeddings, and its multilingual successor, MMTEB, covers hundreds of tasks across many languages. It is useful for a shortlist. It is a poor tool for a final decision, for three reasons.
First, the average hides the task you care about. The headline number blends classification, clustering, semantic similarity, retrieval and more. If you are building search or RAG, only the retrieval columns matter, and rankings on that subset differ from the overall order.
Second, public test sets leak into training data. The MTEB maintainers said as much when they launched RTEB on 1 October 2025: a retrieval-only benchmark scored by nDCG@10 that keeps some datasets private, evaluated by the maintainers, precisely so that a big gap between open and private scores exposes overfitting. They describe the problem as "teaching to the test", which is a polite way of saying some top scores are memorised.
Third, nobody's benchmark is your corpus. Your documents have internal acronyms, ticket numbers, code, and a query distribution written by tired people at 2 a.m. A model that tops a Wikipedia-heavy retrieval set can lose to a cheaper model on that.
So I use the leaderboard to pick three or four candidates within my price and licence constraints, then run them against 100 to 300 real queries with labelled relevant documents, measured by recall@10 or nDCG@10. That evaluation set is the most valuable artefact in the whole project, and it is what makes swapping models later a measured decision instead of a vibe. If you have never built one, the RAG evaluation patterns in why RAG fails in production apply directly.
Open vs API embedding models in 2026
The API side has consolidated around a few providers with clear price sheets. The open side has caught up on quality, and the strongest open families are now Apache-2.0 licensed. Here is what the main options look like, with prices checked on 10 November 2026:
| Model | Type | Default dims | Max input | Price per 1M tokens | Source |
|---|---|---|---|---|---|
| text-embedding-3-small | OpenAI API | 1,536 | 8,192 | $0.02 | OpenAI pricing, guide |
| text-embedding-3-large | OpenAI API | 3,072 | 8,192 | $0.13 | same |
| voyage-4-lite | Voyage API | 1,024 | 32,000 | $0.02 (200M free) | Voyage pricing, docs |
| voyage-4 | Voyage API | 1,024 | 32,000 | $0.06 (200M free) | same |
| voyage-4-large | Voyage API | 1,024 | 32,000 | $0.12 (200M free) | same |
| gemini-embedding-001 | Google API, text | 3,072 | 2,048 | $0.15 ($0.075 batch) | Gemini pricing, docs |
| gemini-embedding-2 | Google API, multimodal | 3,072 | 8,192 | $0.20 ($0.10 batch) | same |
| embed-v5.0-pro / -fast | Cohere API, multimodal | 2,048 | 128k | not checked | Cohere models |
| Qwen3-Embedding 0.6B / 4B / 8B | Open weights, Apache-2.0 | 1,024 / 2,560 / 4,096 | 32k | your GPU | model card |
| BGE-M3 | Open weights, MIT | 1,024 | 8,192 | your GPU | model card |
A few details in that table matter more than the price column. Voyage says all embeddings from its 4 series are compatible with each other, so you can embed documents with voyage-4-large and queries with the cheaper voyage-4-lite. Gemini's 2,048-token limit on gemini-embedding-001 is small if you like large chunks. Qwen3-Embedding-8B reported 70.58 on the MTEB multilingual board and first place as of 5 June 2025, according to its model card, which is old enough that newer entries have since been submitted; treat any "number one" claim as a snapshot.
Open weights win when you need data to stay inside your network, when you embed billions of tokens continuously, or when you want to pin a model forever without worrying about an API deprecation. APIs win on operational simplicity: no GPU pool to keep warm, no batching service, no model server upgrades.
Embedding dimensions, Matryoshka and the pgvector limit
More dimensions usually means slightly better quality and linearly more storage, memory and distance computation. In pgvector a vector takes 4 * dimensions + 8 bytes, a halfvec takes 2 * dimensions + 8, and a binary bit vector takes dimensions / 8 + 8. At 3,072 dimensions that is 12,296 bytes per row as float32, before any index. Ten million chunks is roughly 123 GB of raw vectors, and the HNSW graph wants to sit in memory on top of that.
Matryoshka Representation Learning is the trick that made this negotiable. A Matryoshka-trained model packs the most important information into the first dimensions, so you can truncate a 3,072-dimensional vector to 1,024 or 256 and still get a usable embedding. OpenAI exposes this as a dimensions parameter and says that text-embedding-3-large shortened to 256 dimensions still outperforms the old text-embedding-ada-002 at 1,536 on MTEB. Gemini supports 128 to 3,072 and recommends 768, 1,536 or 3,072. Voyage 4 offers 256, 512, 1,024 and 2,048. Qwen3-Embedding-8B accepts anything from 32 to 4,096.
The catch is normalisation. If you truncate a vector yourself, it is no longer unit length, and cosine and dot product stop agreeing. OpenAI tells you to renormalise after manual shortening; Google says gemini-embedding-001 needs manual normalisation for anything other than 3,072, while gemini-embedding-2 normalises for you. Asking the API for fewer dimensions avoids the issue entirely.
Then there is the index ceiling, which surprises people on day one. pgvector's HNSW and IVFFlat indexes support up to 2,000 dimensions for vector, 4,000 for halfvec and 64,000 for bit. The defaults of text-embedding-3-large and both Gemini models (3,072) do not fit a vector index, and Qwen3-Embedding-8B at 4,096 does not even fit halfvec. Your options are to request fewer dimensions, index a halfvec expression, or binary-quantise for a first pass and rescore with the full vectors:
-- pgvector 0.8.x: store full 3,072-dim vectors, index a half-precision copy.
-- Tested shape on PostgreSQL 18.4 with pgvector 0.8.2 locally; current release is 0.8.7.
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE chunks (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
body text NOT NULL,
embedding vector(3072) NOT NULL -- e.g. gemini-embedding-001 default
);
-- vector(3072) is over the 2,000-dim HNSW limit, so index it as halfvec (limit 4,000)
CREATE INDEX chunks_embedding_hnsw
ON chunks USING hnsw ((embedding::halfvec(3072)) halfvec_cosine_ops)
WITH (m = 16, ef_construction = 64); -- pgvector defaults, stated explicitly
-- The query must use the same expression or the index is ignored
SELECT id, body
FROM chunks
ORDER BY embedding::halfvec(3072) <=> $1::halfvec(3072)
LIMIT 10;
If you would rather not manage this at all, ask the API for 1,024 or 1,536 dimensions and store a plain vector. My working assumption, until my own eval set says otherwise, is that the quality lost from 3,072 to 1,536 dimensions is smaller than the quality lost to a bad chunking strategy. For index tuning past this point, see tuning pgvector HNSW.
How much does embedding cost, really?
Embedding is the cheapest line in most AI bills, and it is easy to show why. Take ten million chunks of 500 tokens, five billion tokens in total. At $0.02 per million tokens for text-embedding-3-small that is $100 for the whole corpus. On text-embedding-3-large it is $650. On gemini-embedding-001 at the standard rate it is $750, or $375 through batch. Voyage takes 200 million tokens off the top and gives 33 percent off for batch jobs.
The money is elsewhere. It is in the vector storage and RAM covered above, in re-embedding when you change models or chunking, in the reranker you will probably add, and in the LLM tokens the retrieved chunks feed into. Pick the embedding model on retrieval quality for your eval set and on operational fit, then worry about its price. For how those LLM tokens add up, see LLM token pricing explained.
Multilingual embeddings and the keyword problem
If your users write in more than one language, check two things: that the model was trained multilingually (Qwen3-Embedding claims over 100 languages including programming languages, BGE-M3 is built for it, and the main API models handle the major languages), and that your evaluation set contains queries in each language you serve.
The more common gap is not language but vocabulary. Dense embeddings are good at meaning and bad at exact strings: error codes, version numbers, part numbers, function names, rare surnames. A query for ERR_CONNECTION_REFUSED or pg_hba.conf wants a lexical match, and the embedding model may decide a vaguely related paragraph about networking is close enough. This is why I rarely ship pure vector search. Hybrid search, which runs a keyword query and a vector query and fuses the two rankings, fixes most of it at almost no cost. I wrote the full Postgres version, with tsvector, pgvector HNSW and reciprocal rank fusion in one SQL function, as a companion guide: how to build hybrid search in Postgres.
Rerankers: when the embedding model is not enough
A reranker is a cross-encoder. Instead of encoding the query and document separately, it reads them together and outputs a relevance score. That is much more accurate and much more expensive, so you only run it on the top 20 to 100 candidates your first-stage retrieval returns, then keep the best five or ten.
Options in 2026 include Cohere's rerank-v5.0-pro and rerank-v5.0-fast with a 32k context, Voyage's rerank-3 at $0.05 per million tokens and rerank-3-lite at $0.02, and open models such as the Apache-2.0 Qwen3-Reranker family and bge-reranker-v2-m3. Note how rerankers are billed: Voyage counts query tokens multiplied by the number of documents, plus all document tokens, so reranking 100 long chunks per query costs far more than embedding the query did.
In my experience the order of returns is: fix chunking, add hybrid retrieval, add a reranker, and only then consider a more expensive embedding model. A reranker on top of a cheap embedding often beats an expensive embedding alone, and it is easier to swap because it holds no stored state.
When do you need to re-embed?
Re-embedding means recomputing every stored vector. You need it when:
- You change the model, including a new version from the same vendor. Different model, different space. Gemini's own docs make this explicit for its 001 to 2 move.
- You change dimensions or truncation, unless you stored the full vector and truncate at query time with a Matryoshka model.
- You change chunking or the text you embed (adding titles, headings or metadata to each chunk is a common, worthwhile change).
- The vendor retires the model. OpenAI still lists
text-embedding-ada-002at $0.10, but every API model eventually goes. Open weights you host yourself never disappear, which is a real argument for them.
You do not need to re-embed for a new pgvector version, an index rebuild, or HNSW parameter changes; those rebuild the index from the same vectors.
Treat it like a schema migration. Store a model and model_version column next to each embedding, write new vectors to a new column or table, backfill in batches, run your eval set against both, switch reads with a flag, then drop the old column. It is expand and contract, the same discipline as zero-downtime database migrations, and it turns "we are stuck on this model" into a Tuesday afternoon job.
FAQ
What is the best embedding model in 2026?
There is no single best. On public leaderboards, both Gemini Embedding and Qwen3-Embedding-8B have claimed first place on the MTEB multilingual board in 2025, according to their vendors. The best model for you is whichever of three or four shortlisted candidates scores highest on recall@10 for your own labelled queries at a price and licence you accept.
How many dimensions should my embeddings have?
For most RAG and search workloads, 768 to 1,536 dimensions is the practical range. If your model supports Matryoshka truncation, request the smaller size from the API and test the quality drop on your eval set. Remember pgvector indexes vector only up to 2,000 dimensions, so 3,072-dimensional defaults need halfvec indexing or truncation.
Do I need a reranker if I use a good embedding model?
Not always, but it is usually the cheapest quality gain after hybrid search. A cross-encoder reranker over the top 50 candidates often fixes ordering errors that no bi-encoder can, because it reads the query and document together. Measure it on your eval set and watch the added latency.
Can I mix embeddings from different models in one index?
No. Each model has its own vector space, and distances between vectors from different models are meaningless. The one documented exception is a vendor that explicitly designs a shared space, as Voyage does across its 4 series.
This quarter, if I were starting a search or RAG project, I would build the labelled query set first, shortlist one cheap API model, one premium API model and one open model, run all three through a hybrid Postgres setup with a reranker toggle, and store the model name next to every vector from day one. The model will change. The eval set and the migration path are what you keep.
Related: Vector Databases in 2026: Do You Need One, or Is pgvector Enough?, How to Build a RAG Pipeline With Postgres and pgvector (2026) and RAG vs Long Context vs Fine-Tuning in 2026: 1M Tokens Isn't Free.
Spot an error or something out of date? Email me and I will fix it and log it on the corrections page.
I'm Ajay Kumar — I build and operate PandaStack, an open-source Firecracker microVM cloud for AI agents, and write about the infrastructure and tooling around it.
Need this kind of infrastructure work? See what I do or email hello@ajayk.sh.
Related
API Gateways Compared 2026: Kong vs APISIX vs Envoy Gateway vs Traefik
Kong vs Apache APISIX vs Envoy Gateway vs Traefik vs Tyk vs AWS API Gateway in 2026: current versions, Gateway API conformance numbers, licensing changes like Kong's frozen OSS line, AI gateway features and what the performance claims really measure.
11 minNov 10, 2026How to Build RAG With Amazon Bedrock Knowledge Bases (2026 Guide)
Step-by-step 2026 guide to RAG on Amazon Bedrock Knowledge Bases: S3 data source, Titan Text Embeddings V2, S3 Vectors vs OpenSearch Serverless vs Aurora pgvector, ingestion sync, RetrieveAndGenerate with boto3, IAM, real costs and fixes for common errors.
14 minNov 10, 2026Bedrock vs Azure Foundry vs Vertex AI (2026): Models, Pricing, Agents
Amazon Bedrock vs Microsoft Foundry (Azure OpenAI) vs Google Vertex AI, now Gemini Enterprise Agent Platform, compared for 2026: model catalogs, Flex and Priority tiers, provisioned throughput terms, data residency, agent runtimes and guardrails.
12 min