AI Data & Training · Practical guide
Enterprise Embedding Models: Selection, Fine-Tuning, Dimensions, and Cost
Choose embedding models by benchmarking on your own labeled corpus, not a public leaderboard. Shortlist one or two API models and one open-weight model, measure hit rate, MRR, and nDCG on representative queries, then set dimensions deliberately — dimension count, quantization, and caching drive retrieval cost at scale more than the per-token price of any provider.
In this guide · 10 steps
- 01The real tension: managed API vs open-weight self-hosting
- 02Benchmarks: use MTEB to shortlist, never to decide
- 03Dimensions: the decision that compounds forever
- 04Open-weight models for on-prem and air-gapped estates
- 05Multilingual retrieval without parallel silos
- 06Domain adaptation: when general-purpose embeddings run out
- 07Measuring embedding quality: hit rate, MRR, nDCG
- 08Cost engineering: caching and the re-embedding budget
- 09Honest objections
- 10The read
The embedding model is the quietest decision in an enterprise RAG stack and one of the most consequential. It fixes your retrieval ceiling, your vector-storage bill, and a surprising amount of your vendor exposure — because unlike a generation model, an embedding model cannot be swapped without re-embedding the entire corpus. So the selection method matters: shortlist against a public benchmark, decide on your own labeled data, and set dimensions and quantization as deliberate cost controls rather than defaults you inherited.
languages covered by the Massive Text Embedding Benchmark (MTEB), which spans 8 embedding task families and 58 datasets, and evaluated 33 models at launch[^arxiv-mteb-2022]
Muennighoff et al., MTEB (arXiv)
smaller embedding sizes at the same ImageNet-1K classification accuracy reported for Matryoshka Representation Learning, the technique behind modern truncatable embeddings[^arxiv-mrl-2022]
Kusupati et al., Matryoshka Representation Learning (arXiv)
pages embedded per dollar with OpenAI's text-embedding-3-small versus text-embedding-3-large — a 6.5x unit-cost gap between the small and large tier of a single provider[^openai-embeddings-guide]
OpenAI embeddings guide
1. The real tension: managed API vs open-weight self-hosting
Most embedding decisions collapse into one structural choice before any benchmark score matters. Managed APIs (OpenAI, Google, Voyage AI, Cohere) give you zero-ops embedding at a metered price, with the model's lifecycle controlled by the vendor. Open-weight models (the BGE family, E5, Sentence-Transformers models) give you a fixed infrastructure cost, full data locality, and version pinning — at the price of owning GPU serving, scaling, and upgrades yourself. Neither is generically cheaper; the crossover depends on corpus size, query volume, and whether your data is allowed to leave your boundary at all.
| Dimension | Managed embedding API | Open-weight self-hosted |
|---|---|---|
| Unit economics | Metered per token/page; scales linearly with volume | Fixed serving cost; marginal cost falls with utilization |
| Data path | Corpus and queries transit the vendor | Everything stays inside your boundary; air-gap possible |
| Model lifecycle | Vendor controls deprecation; re-embedding forced on retirement | You pin the version; re-embed on your own schedule |
| Customization | Limited to parameters the API exposes | Full fine-tuning on domain data is available |
| Operational burden | None beyond quota and cost management | GPU serving, autoscaling, monitoring are yours |
| Procurement posture | Another SaaS DPA and subprocessor review | License review (MIT/Apache-style terms are common) |
A useful signal of how open this market really is: Anthropic ships no embedding model at all. Its embeddings documentation states plainly that "Anthropic does not offer its own embedding model" and walks users through Voyage AI instead, including Voyage's domain-specific models for law, finance, and code[4]. Embeddings are a genuinely multi-vendor layer — treat the choice as a procurement decision with an exit plan, not a default that rides along with your LLM provider.
2. Benchmarks: use MTEB to shortlist, never to decide
The Massive Text Embedding Benchmark is the industry's shared yardstick precisely because embedding quality is task-dependent. MTEB spans 8 task families — retrieval, clustering, classification, and others — across 58 datasets and 112 languages, and its authors' headline finding from benchmarking 33 models is that no single embedding method dominates across all tasks[1]. That finding is the practical warning: a model that tops the aggregate leaderboard can still lose to a cheaper model on your specific retrieval workload.
Vendors quote MTEB numbers for their own models, and those are legitimate shortlisting inputs. OpenAI's own documentation reports an MTEB average of 62.3% for text-embedding-3-small and 64.6% for text-embedding-3-large, against 61.0% for the older text-embedding-ada-002[3]. On the open-weight side, the BGE line's authors report their English models reached state-of-the-art on MTEB at the time of release[5], and Microsoft's E5 was the first model reported to beat the BM25 keyword baseline on the BEIR retrieval benchmark zero-shot, without any labeled data[6]. Read all of these the same way: proof a model belongs on the shortlist, not proof it wins your bake-off.
Distrust point-in-time leaderboard deltas
Aggregate MTEB averages compress eight different task families into one number, and top positions churn as new models ship. A two-point aggregate gap tells you almost nothing about your corpus. The only benchmark that decides a purchase should be your own labeled evaluation set, scored with the metrics below.
| Model | Access | Default dimensions | Max input | Cited fact |
|---|---|---|---|---|
| text-embedding-3-small | API (OpenAI) | 1536 | 8,192 tokens | 62.3% MTEB average; 62,500 pages/$[^openai-embeddings-guide] |
| text-embedding-3-large | API (OpenAI) | 3072 | 8,192 tokens | 64.6% MTEB average; 9,615 pages/$[^openai-embeddings-guide] |
| gemini-embedding-001 | API (Google) | flexible 128–3072 (768/1536/3072 recommended) | 2,048 tokens | Trained with Matryoshka Representation Learning; 100+ languages[^google-gemini-embeddings] |
| voyage-4 family | API (Voyage AI) | 1024 (256/512/2048 options) | 32,000 tokens | Recommended provider in Anthropic's embeddings docs[^anthropic-embeddings] |
| BGE / bge-m3 | Open weights (BAAI) | 1024 | 8,192 tokens | MIT license; dense, sparse, and multi-vector retrieval in one model[^hf-bge-m3] |
| E5 | Open weights (Microsoft) | varies by size | model-dependent | First to beat BM25 zero-shot on BEIR without labeled data[^arxiv-e5-2022] |
3. Dimensions: the decision that compounds forever
Every dimension you keep is paid for on every vector, on every replica, forever. The arithmetic is unforgiving because it is linear: a float32 embedding costs 4 bytes per dimension, so a 1536-dimensional vector is about 6.1 KB and a 3072-dimensional vector about 12.3 KB before any index overhead. Across 100 million chunks, the difference between 3072 and 768 dimensions is roughly 920 GB of raw vector data — repeated in RAM for latency-sensitive ANN indexes, repeated again per replica. Storage and memory sizing for those indexes is covered in depth in /guides/vector-database-operations; the point here is that dimension count is set at embedding time, upstream of everything the vector database can do about it.
Raw vector size by dimension count (float32, KB per vector)
The good news is that the old accuracy-vs-dimensions deadlock has been broken by training technique rather than hardware. OpenAI's embeddings guide states that "developers can shorten embeddings (i.e. remove some numbers from the end of the sequence) without the embedding losing its concept-representing properties," and recommends doing it through the API's native dimensions parameter rather than truncating afterward[3]. Google documents the same property for its Gemini embedding models, which support flexible output dimensionality from 128 to 3072 and are explicitly trained with Matryoshka Representation Learning[7].
Matryoshka embeddings: one vector, many budgets
Matryoshka Representation Learning (MRL) is the research result underneath those vendor features. The technique trains a single embedding so that its leading dimensions form usable coarse representations — the paper describes encodings that "adapt to the computational constraints of downstream tasks" — and reports up to 14x smaller embedding sizes at matching ImageNet-1K classification accuracy, plus up to 14x real-world speedups in large-scale retrieval[2]. In practice this converts the dimensions question from a one-time gamble into a tunable dial: embed once at full width, store truncated prefixes where budget demands, and re-rank shortlists with the full vector when precision matters.
Quantization: int8 and binary as the second lever
Quantization compresses the values rather than the count of dimensions, and it stacks with truncation. Voyage's quantization options, documented in Anthropic's embeddings guide, state the tradeoff cleanly: converting 32-bit floats to 8-bit integers reduces storage, memory, and cost by 4x, and single-bit binary embeddings reduce them by 32x[4]. Binary vectors also swap expensive float math for fast Hamming-distance comparisons. The catch is quantization error: binary embeddings degrade fine-grained ranking, so the standard production pattern is two-stage — retrieve a generous candidate set against the compressed index, then re-rank with full-precision vectors or a reranker. Accept the compression only after measuring recall on your own evaluation set, at your own corpus scale.
4. Open-weight models for on-prem and air-gapped estates
For regulated workloads where the corpus cannot transit a vendor API, the open-weight tier is no longer a compromise. The lineage runs from Sentence-BERT, which made practical sentence embeddings feasible by cutting most-similar-pair search over 10,000 sentences from roughly 65 hours of BERT cross-encoder inference to about 5 seconds with cosine similarity over precomputed embeddings[9], through E5's contrastively pretrained retrievers[6], to the BGE family, whose training recipe and benchmark results are fully published[5]. These are documented, reproducible research artifacts — not vendor black boxes — which materially simplifies model-risk review.
Licensing and capability are both checkable from first-party model cards. BAAI's bge-m3 card, for example, is MIT-licensed and documents a 1024-dimensional model that performs dense, sparse, and multi-vector retrieval in one artifact, over inputs up to 8,192 tokens[8]. The real cost of the open-weight route is operational: you own GPU capacity for embedding backfills, latency SLOs for query-time encoding, and the upgrade treadmill. Budget for the serving platform, not just the model — and remember that the model's permissive license does not exempt you from evaluating it like any other vendor artifact.
Pin the model version like a schema
Embeddings from different model versions are not comparable — mixing them in one index silently corrupts retrieval. Treat the embedding model + version + dimension count as part of your index schema: record it in metadata, and make any change trigger a planned, full re-embedding migration.
5. Multilingual retrieval without parallel silos
Global enterprises used to run one retrieval stack per language. Modern multilingual embedding models collapse that: BGE-M3 is explicitly built for multi-linguality across more than 100 working languages, with dense, sparse, and multi-vector retrieval and inputs from short sentences to 8,192-token documents[10]. On the API side, Google documents 100+ language support for its Gemini embedding models[7]. Cross-lingual alignment means a German query can retrieve the English master policy document directly, without a translation hop.
The governance caveat: quality is not uniform across languages, and aggregate multilingual scores hide the floor. MTEB's 112-language breadth exists precisely because per-language performance varies[1]. Before consolidating on one multilingual model, build a small labeled evaluation set for each language that carries revenue or regulatory weight — a few hundred query-document pairs per language is enough to expose whether your lowest-resource market is being quietly underserved.
6. Domain adaptation: when general-purpose embeddings run out
General-purpose embeddings are trained on broad web corpora, and they blur exactly the distinctions your domain cares about: indemnification versus limitation of liability in contracts, drug names that differ by one morpheme, two functions with identical intent and disjoint tokens. You have three escalating responses. First, try a domain-tuned commercial model — Voyage publishes voyage-law-2 for legal and long-context retrieval, voyage-finance-2 for finance, and voyage-code-3 for code, per Anthropic's embeddings documentation[4]. Second, add a reranker on top of a general retriever, which often recovers most of the gap for a fraction of the effort — /guides/enterprise-retrieval-tuning covers that path. Third, fine-tune an open-weight model on your own relevance data.
Fine-tuning an embedding model is a contrastive-learning exercise, and the tooling descends directly from Sentence-BERT's siamese and triplet network structures, which train the encoder so that semantically related pairs land near each other under cosine similarity[9]. The scarce input is not compute but labels: pairs and triplets of queries with genuinely relevant and genuinely irrelevant documents from your domain. Search logs, support-ticket resolutions, and cross-references in your own document base are the usual sources. Teams that skip curation and fine-tune on synthetic pairs generated by an LLM should treat the result with suspicion until it beats the base model on a human-labeled holdout — otherwise you are optimizing toward the generator's biases, not your users' intent.
Code embeddings are their own domain
Semantic code search is the clearest demonstration that domains break general embeddings, because the vocabulary gap is structural. The CodeSearchNet challenge — built on a corpus of about 6 million functions from open-source code, 2 million of them paired with natural-language documentation, plus roughly 4,000 expert relevance annotations over 99 queries across six programming languages — framed the task as bridging "the language used in code (often abbreviated and highly technical)" and the vaguer natural language of human queries[11]. For an internal developer platform, that means evaluating code-specialized models (voyage-code-3 is one commercially documented option[4]) against your own repositories and query patterns, and enforcing the same index hygiene as any other corpus: language tags in metadata, and re-embedding wired into CI so the index tracks the code.
7. Measuring embedding quality: hit rate, MRR, nDCG
Three standard information-retrieval metrics cover almost every enterprise evaluation, and they answer different questions. Hit rate (recall@k) asks: did at least one relevant document appear in the top k? Mean reciprocal rank (MRR) asks: how high did the first relevant document rank, averaging the reciprocal of that rank across queries? Normalized discounted cumulative gain (nDCG) asks: how good is the whole ranked list, crediting graded relevance and discounting results that appear lower down? None requires special tooling — a few hundred labeled query-document pairs and a spreadsheet are enough to start.
| Metric | What it rewards | Use it when | Blind spot |
|---|---|---|---|
| Hit rate / recall@k | Any relevant document in the top k | Screening models quickly; RAG where the generator reads all k chunks | Ignores ranking order and multiple relevant documents |
| MRR | The first relevant result ranking high | Single-answer lookups; UX where users read top-down | Ignores everything after the first relevant hit |
| nDCG@k | Well-ordered lists with graded relevance | Multi-document synthesis; final model selection | Needs graded relevance labels, which cost annotation effort |
Match the metric to the consumer of the retrieval. If a RAG pipeline stuffs the top 10 chunks into the context window regardless of order, hit rate@10 is the metric that predicts answer quality. If the retrieval feeds a ranked UI or a strict context budget, MRR and nDCG matter more. Evaluate at the k you actually deploy, keep the evaluation set versioned alongside the index schema, and re-run it on every candidate model, dimension setting, and quantization level — the full tuning loop, including rerankers and hybrid retrieval, is the subject of /guides/enterprise-retrieval-tuning.
The benchmark that decides the purchase is the one built from your own queries. Public leaderboards only tell you who deserves a lane in the race.
8. Cost engineering: caching and the re-embedding budget
Embedding spend at scale is dominated by redundant work, and caching is the cheapest fix in the stack. The pattern has two halves. Document-side: precompute embeddings once per chunk, key the cache on a content hash plus the model version and dimension setting, and re-embed only chunks whose hash changed — wired into the same ingestion pipeline that does chunking (see /guides/rag-ingestion-and-chunking). Query-side: cache query embeddings keyed on normalized query text with a TTL; repeated and templated queries are common in enterprise search, and every cache hit is an API call or a GPU batch you did not pay for. Measure your cache hit rate before buying capacity — it is routinely the difference between a linear and a sublinear cost curve.
The second, less visible line item is the re-embedding budget. Model deprecations, dimension changes, and fine-tune refreshes each force a full-corpus backfill, at full metered price on an API or full GPU occupancy on-prem. This is where the unit-price gap compounds: at OpenAI's published rates, the same corpus costs about 6.5x more to embed on text-embedding-3-large than on text-embedding-3-small[3], and that multiplier applies to every future re-embedding, not just the first. Plan at least one full re-embedding per year into the TCO model, and favor providers and dimension strategies that let you shrink storage without re-embedding — Matryoshka truncation is exactly that escape hatch[2].
9. Honest objections
"Embedding choice barely matters — rerankers and better chunking wash it out." Partly true, and worth taking seriously. A strong reranker over a mediocre retriever often beats a strong retriever alone, and chunking quality moves retrieval metrics more than most model swaps. But the retriever sets the candidate ceiling: a reranker cannot rescue a relevant document the embedding model never surfaced. The pragmatic read is to spend your first optimization effort on chunking and reranking, and reserve embedding-model changes for when your evaluation set shows recall — not ranking — is the binding constraint.
"Why not just use the biggest model at full dimensions and be done?" Because the costs are asymmetric. Upgrading a too-small choice later costs one re-embedding run; overpaying on dimensions costs you on every vector, every replica, every month, and the published evidence — OpenAI's own shortening guidance and the MRL results behind it — says much of that width is not buying retrieval quality[3][2]. And "be done" is an illusion regardless: API model retirements mean you will re-embed eventually, whichever model you pick. Optimize for the ability to change your mind cheaply.
"MTEB is gameable, so why trust any benchmark?" Public benchmarks do attract training-data contamination and leaderboard tuning, and MTEB's own authors found no universal winner across its task families[1]. That is an argument against outsourcing the decision to a leaderboard, not against benchmarks. A private, versioned evaluation set drawn from your real queries is immune to leaderboard gaming by construction — which is exactly why it, and not MTEB, should sign off on the purchase.
10. The read
Treat embedding selection as a two-gate decision. Gate one is structural: if data locality, air-gapping, or fine-tuning rights are hard requirements, you are in the open-weight lane (BGE, E5, and their descendants) and the remaining question is serving cost. If not, managed APIs win on operational simplicity, and the shortlist is OpenAI, Google, Voyage, and Cohere. Gate two is empirical: a one-week bake-off on a few hundred labeled queries, scored with hit rate, MRR, and nDCG at your deployed k, across two dimension settings and one quantization level per candidate. Pick the cheapest configuration that clears your quality bar, pin the version like a schema, wire caching and content-hash re-embedding into ingestion, and book an annual re-embedding into the budget. That process is durable even as this year's model names age out — and it converts the embedding layer from an inherited default into a controlled, replaceable component of the stack.
How to apply this
- Write down your structural constraints first: data residency, air-gap, fine-tuning rights, and procurement posture — they decide API vs open-weight before any benchmark.
- Build a labeled evaluation set of 200+ real query-document pairs (per major language, if multilingual) before contacting any vendor.
- Shortlist 3-4 models using published MTEB results and vendor documentation; verify claimed dimensions, context limits, and licenses on primary pages.
- Run the bake-off on your own data with hit rate@k, MRR, and nDCG at the k you deploy — not the k the leaderboard uses.
- Test at least one reduced-dimension (Matryoshka/truncated) and one quantized (int8 or binary) configuration; accept the cheapest that holds recall.
- Model the vector-storage and memory bill at target corpus size before committing to a dimension count; coordinate with your vector-database sizing (/guides/vector-database-operations).
- Pin model + version + dimensions as index-schema metadata; never mix embeddings from different versions in one index.
- Implement content-hash embedding caches on the document side and TTL caches on the query side; track cache hit rate as a first-class cost metric.
- Budget one full corpus re-embedding per year for model refreshes and deprecations; price it at both your primary and fallback provider.
- Escalate to domain-tuned or fine-tuned models only when the evaluation set shows recall, not ranking, is the binding constraint — try a reranker first.
Sources
Every quantitative or attributed claim above is linked to a primary source. Last verified at publication.
- [1]MTEB: Massive Text Embedding BenchmarkarXiv (Muennighoff, Tazi, Magne, Reimers) · · accessed
- [2]Matryoshka Representation LearningarXiv (Kusupati et al.) · · accessed
- [3]Vector embeddings — OpenAI API documentationOpenAI · accessed
- [4]Embeddings — Anthropic documentation (Voyage AI models)Anthropic · accessed
- [5]C-Pack: Packed Resources For General Chinese EmbeddingsarXiv (Xiao, Liu, Zhang, Muennighoff, Lian, Nie) · · accessed
- [6]Text Embeddings by Weakly-Supervised Contrastive Pre-trainingarXiv (Wang et al., Microsoft) · · accessed
- [7]Embeddings — Gemini API documentationGoogle AI for Developers · accessed
- [8]BAAI/bge-m3 model cardBAAI (Hugging Face model card) · accessed
- [9]Sentence-BERT: Sentence Embeddings using Siamese BERT-NetworksarXiv (Reimers, Gurevych) · · accessed
- [10]M3-Embedding: Multi-Linguality, Multi-Functionality, Multi-Granularity Text Embeddings Through Self-Knowledge DistillationarXiv (Chen, Xiao, Zhang, Luo, Lian, Liu) · · accessed
- [11]CodeSearchNet Challenge: Evaluating the State of Semantic Code SearcharXiv (Husain, Wu, Gazit, Allamanis, Brockschmidt) · · accessed