Best Embedding Models in 2026: Open Source vs Closed Source
Compare the best open-weight and closed embedding models on licensing, retrieval evidence, cost, privacy and lock-in, with clear picks for RAG, search and on-device apps.
On this page 11 sections
- 01Open source, open weight and closed: what the labels mean
- 02The models at a glance
- 03Open-weight models worth shortlisting
- 04What the benchmarks actually show
- 05Cost: when self-hosting pays off
- 06Privacy, control and lock-in
- 07Running an open model
- 08How to choose
- 09Common mistakes to avoid
- 10Frequently asked questions
- 11A practical implementation path
An embedding model turns text, images or other inputs into vectors so that software can search by meaning. The first decision is who runs that model: a vendor behind an API, or you, using weights you can download.
My default advice is to start with a closed API unless you have a concrete reason not to. An API gets you to a working retrieval evaluation quickly, and embedding bills are usually small. Move to an open-weight model when data control, a very large volume, offline use or long-term stability justifies running inference yourself.
For a quick shortlist:
- Most new RAG projects: a closed API. Start with Voyage
voyage-4, and read my Cohere, Google, Voyage and OpenAI comparison for the details. - Self-hosted default for commercial use: Qwen3-Embedding-4B, or Qwen3-Embedding-0.6B on smaller hardware. Both are Apache 2.0.
- Dense and keyword-style retrieval from one self-hosted model: BGE-M3 (MIT).
- Self-hosted retrieval without instruction prefixes: Perplexity
pplx-embed-v1(MIT), which also led the most transparent open-model test I found. - Phones, laptops and offline apps:
voyage-4-nano(Apache 2.0) or EmbeddingGemma if the Gemma terms suit you. - Research or non-commercial work: Jina Embeddings v5 is worth testing, but its CC BY-NC 4.0 licence requires a separate agreement for commercial use.
These picks are my judgement from published specifications and benchmarks. I did not run a new benchmark for this guide, and no published result can replace a test on your own documents. Specifications and prices come from official documentation and model cards checked in November 2026.
Open source, open weight and closed: what the labels mean
Most “open-source embedding models” are more accurately called open-weight models. You can download and run the trained model, but you may not get the training data or everything needed to reproduce it.
| Label | What you get | Typical examples |
|---|---|---|
| Permissive open weight | Weights you can run and usually use commercially under a licence such as MIT or Apache 2.0 | Qwen3-Embedding, BGE-M3, pplx-embed-v1 |
| Restricted open weight | Downloadable weights with additional terms or non-commercial limits | EmbeddingGemma, Jina Embeddings v4 and v5 |
| Closed model | Access through an API or a vendor-managed deployment; the weights are not available to download | OpenAI, Gemini, Cohere Embed 5, voyage-4-large |
Two boundaries are less clear than they look:
- An open model does not have to be self-hosted. Inference providers host many open models, so you can use one through an API and keep the option to run it yourself later.
- A closed model does not always run on shared infrastructure. Cohere offers dedicated Model Vault and private deployments, which matters when the requirement is about isolation rather than access to the weights.
One vendor also spans the divide: Voyage keeps its larger models closed but publishes voyage-4-nano under Apache 2.0.
Always read the licence on the exact model you plan to ship. EmbeddingGemma is gated behind Google's Gemma terms. The Jina Embeddings v4 card says it was first labelled CC BY-NC in error and actually falls under the Qwen Research License. Jina's v5 text model asks commercial users to contact the company.
The models at a glance
Open-weight models
| Model | Licence | Size | Max tokens | Dimensions | Best fit |
|---|---|---|---|---|---|
| Qwen3-Embedding-8B | Apache 2.0 | 8B parameters | 32K | 32 to 4,096 | Highest-quality self-hosted candidate |
| Qwen3-Embedding-4B | Apache 2.0 | 4B | 32K | 32 to 2,560 | Balanced self-hosted default |
| Qwen3-Embedding-0.6B | Apache 2.0 | 0.6B | 32K | 32 to 1,024 | Smaller GPUs |
| Harrier OSS v1 27B | MIT | 27B | 32,768 | 5,376 | Offline quality work with serious hardware |
| pplx-embed-v1 4B | MIT | 4B | 32K | Up to 2,560 | Retrieval with no prefix handling |
| pplx-embed-v1 0.6B | MIT | 0.6B | 32K | Up to 1,024 | The same, on smaller hardware |
| BGE-M3 | MIT | Not stated on card | 8,192 | 1,024 | Dense, sparse and multi-vector retrieval |
| voyage-4-nano | Apache 2.0 | 340M | 32K | 256 to 2,048 | Small model with long context |
| EmbeddingGemma | Gemma terms | 300M | 2,048 | 128 to 768 | On-device apps |
| Nomic Embed Text v2 | Apache 2.0 | 475M total, 305M active | 512 | 256 to 768 | Lightweight multilingual text |
| Jina v5 Text Small | CC BY-NC 4.0 | 677M | 32,768 | 32 to 1,024 | Non-commercial work |
| Jina v5 Omni Small | CC BY-NC 4.0 | About 1.74B | 32,768 | 32 to 1,024 | Non-commercial multimodal work |
| all-MiniLM-L6-v2 | Apache 2.0 | 22.7M | 256 | 384 | Prototypes and short English text |
Closed API models
| Model | Price per 1M text tokens | Max tokens | Maximum dimensions | Inputs |
|---|---|---|---|---|
OpenAI text-embedding-3-small | $0.02 | 8,192 | 1,536 | Text |
OpenAI text-embedding-3-large | $0.13 | 8,192 | 3,072 | Text |
Voyage voyage-4-lite | $0.02 | 32,000 | 2,048 | Text |
Voyage voyage-4 | $0.06 | 32,000 | 2,048 | Text |
Voyage voyage-4-large | $0.12 | 32,000 | 2,048 | Text |
Cohere embed-v5.0-fast | $0.08 | 128K | 2,048 | Text, images, mixed |
Cohere embed-v5.0-pro | $0.12 | 128K | 2,048 | Text, images, mixed |
Google gemini-embedding-2 | $0.20 | 8,192 | 3,072 | Text, images, audio, video, PDF |
A long token limit does not remove the need for chunking. A vector for a whole document blends everything in it, so retrieval precision can suffer. Long limits are most useful for keeping larger, coherent passages intact.
Open-weight models worth shortlisting
Qwen3-Embedding
Qwen3 is the first open family I would test for commercial RAG. It combines an Apache 2.0 licence, a 32K-token limit, more than 100 languages and three sizes. Its model card reports a mean score of 75.22 on MTEB English v2 for the 8B model and 70.58 on MTEB Multilingual.
Two practical details matter. Queries need an instruction prefix while documents do not, and the 8B model's weights alone come to about 16 GB at the card's BF16 precision. That figure is simple arithmetic from the parameter count, so measure real serving memory on your own hardware. The 4B and 0.6B models are much easier to run.
BGE-M3
BGE-M3 is older, but it still has a distinct advantage: one model produces dense, sparse and multi-vector representations. That can simplify hybrid search when you want to self-host everything. It also needs no query instruction.
Do not assume that a newer, larger model will beat it. In a Bengali agricultural retrieval study, BGE-M3 reached a Recall@10 of 0.408 while Qwen3-Embedding-8B reached 0.241.
Perplexity pplx-embed-v1
The pplx-embed-v1 models are appealing because you can index text without maintaining an instruction prefix. They also posted the strongest results in AIMultiple's open-model benchmark, discussed below.
Watch one detail: they natively produce unnormalized int8 embeddings, and the model card tells you to compare them with cosine similarity. A dot-product index configured out of habit would not follow that guidance.
Harrier OSS v1
Microsoft's Harrier 27B reports an MTEB v2 score of 74.3, but at 27B parameters and 5,376 dimensions it is expensive to serve and store. The weights alone come to about 54 GB at BF16. I would test it for offline or batch-heavy work, or test its smaller variants. The same card reports 69.0 for the 0.6B version and 66.5 for the 270M version.
Small and on-device models
voyage-4-nano is the permissive small model I would try first, because it offers 32K-token context and built-in int8 and binary output precision. EmbeddingGemma is designed for phones and laptops and reports 69.67 on MTEB English v2 at 768 dimensions, but it has a 2,048-token limit, gated access and custom terms.
Nomic Embed Text v2 is permissive and multilingual, but its 512-token limit means smaller chunks, and it requires trust_remote_code=True. Keep all-MiniLM-L6-v2 for demos, tests and short English text.
What the benchmarks actually show
No single independent benchmark settles this. MTEB is the common public reference, but the scores above are self-reported on model cards, and vendor numbers can come from different benchmark versions. Compare a model's own sizes and settings on one card, not numbers across unrelated tables. I could not read current scores from the client-rendered MTEB leaderboard when checking, so verify them there.
The closest direct comparison I found comes from Techsy, using about 120 hand-labelled queries on 10,000 private product and support documents:
| Model | Type | Recall@10 | nDCG@10 |
|---|---|---|---|
voyage-4-large (1,024) | Closed | 0.89 | 0.81 |
| Gemini Embedding 001 (3,072) | Closed | 0.88 | 0.80 |
| Qwen3-Embedding-8B | Open weight | 0.87 | 0.79 |
text-embedding-3-large (3,072) | Closed | 0.86 | 0.78 |
text-embedding-3-large (1,024) | Closed | 0.83 | 0.75 |
| BGE-M3 (1,024) | Open weight | 0.82 | 0.74 |
nomic-embed-text (768) | Open weight | 0.76 | 0.69 |
The test is not reproducible and the sample is small. The ranges in the chart are my own approximation from the query count, roughly ±0.06 near the top, so the gaps between the leading models are not meaningful. The useful conclusion is narrower: on this corpus, an open-weight model was competitive with closed APIs.
AIMultiple's benchmark is more transparent, with 200 questions across finance, legal, technical support and medical corpora, confidence intervals and significance testing:
| Model | nDCG@10 | 95% interval | Recall@10 |
|---|---|---|---|
| PPLX Embed v1 4B | 0.741 | 0.700 to 0.782 | 90.46% |
| PPLX Embed v1 0.6B | 0.698 | 0.651 to 0.744 | 86.71% |
| Multilingual E5 Large | 0.628 | 0.578 to 0.680 | 79.38% |
| BGE Large EN v1.5 | 0.624 | 0.572 to 0.676 | 78.21% |
| BGE-M3 (dense only) | 0.614 | 0.562 to 0.666 | 79.50% |
It has limits too. Its questions were selected so that BM25 scored zero, about 85% of retrieved pairs were never judged, and all of it is English. The rows I could read did not include Qwen3, so it does not tell you how pplx-embed-v1 compares with that family.
Rankings also flip by domain and language. The Bengali study mentioned above ranked Gemini Embedding 001 (0.464) and BGE-M3 (0.408) well above Qwen3-Embedding-8B (0.241), and BM25 beat every dense model there at 0.506. The same paper shows how much configuration matters: using a sentence-similarity task type instead of retrieval query and document types cut Gemini's Recall@10 from 0.464 to 0.063.
That result is a warning about benchmark reading in general. A wrong prefix or task setting can cost more than choosing the “wrong” model.
Cost: when self-hosting pays off
API costs scale with tokens. Self-hosting costs scale with how long your machines stay on. Those are different shapes, so compare them on your actual workload.
Here is a simple calculation using an assumed GPU cost of $1 per hour. That price is a placeholder, not a quote.
| API price per 1M tokens | Tokens a month needed to match one always-on GPU ($730) |
|---|---|
| $0.02 | 36.5 billion |
| $0.06 | About 12.2 billion |
| $0.12 | About 6.1 billion |
Now compare that to a corpus of one million 400-token chunks, which is 400 million tokens. Embedding it once costs $48 at $0.12 per million tokens. If your own GPU sustains an assumed 80,000 tokens per second, the same job takes about 1.4 hours, or around $1.40 of GPU time.
Together, those numbers show the usual pattern:
- Large offline backfills can be far cheaper on your own or rented GPUs.
- Live query traffic is often cheaper through an API, because a production endpoint needs capacity ready at all times, usually with redundancy.
- Engineering time frequently decides the matter. Serving, autoscaling, monitoring, upgrades and on-call work rarely appear in a per-token comparison.
Measure throughput on your own hardware before relying on this. It varies a lot by model, chunk length, precision and batch size. For the wider budget, see my RAG development cost guide and RAG cost calculator.
Privacy, control and lock-in
| Concern | Closed API | Self-hosted open weight |
|---|---|---|
| Data location | Sent to a vendor unless you buy a private deployment | Stays in your environment |
| Data use | Depends on vendor, plan and settings | Under your control |
| Time to first result | Minutes | Hours to days for a production-grade service |
| Model changes | Vendor can retire models | You pin the weights you tested |
| Tuning | Mostly limited to vendor options | You can fine-tune where the licence permits |
| Operations | Vendor handles serving and scaling | You handle GPUs, scaling and failures |
| Compliance work | Vendor review and contracts | Your own infrastructure controls |
Retirement is a real operational concern. Cohere retired its v2 embedding models on 4 April 2026, and Google lists an earliest shutdown of 14 May 2028 for gemini-embedding-001. If a provider retires your model, you must re-embed your corpus before you can keep embedding new queries consistently.
Open weights reduce that dependency but do not remove lock-in. Every embedding model locks you in to its own vector space. Vectors from different models are not comparable, so switching means re-embedding either way. The practical protection is to keep your source text and record the model and preprocessing version with every vector.
Vendor data terms differ more than most comparisons suggest. Some use your data for training unless you opt out, and free tiers can differ from paid ones. The vendor comparison covers the details.
Running an open model
Sentence Transformers is the simplest way to try most of these models. This example uses Qwen3-Embedding-4B and shortens its output to 1,024 dimensions:
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("Qwen/Qwen3-Embedding-4B", truncate_dim=1024)
documents = ["To reset your password, open account settings and choose Security."]
queries = ["How can I reset my password?"]
# The instruction prefix is applied to queries only.
document_vectors = model.encode(documents, normalize_embeddings=True)
query_vectors = model.encode(queries, prompt_name="query", normalize_embeddings=True)
print(query_vectors @ document_vectors.T)Model-specific rules are easy to miss, so check each card before you test it:
| Model | What to do |
|---|---|
| Qwen3-Embedding, Harrier | Add an instruction to queries; leave documents alone |
| Nomic Embed Text v2 | Add search_query: or search_document: |
| EmbeddingGemma | Use its query and document prompts; do not use float16 |
| multilingual-e5-large | Add query: or passage: |
BGE-M3, pplx-embed-v1 | No instruction prefix needed |
For production, put the model behind a dedicated inference service such as Text Embeddings Inference rather than loading it inside each application process. Batch requests, set maximum lengths deliberately and track GPU memory under realistic load.
How to choose
Work through these questions in order and stop at the first one that decides it:
- Must the data stay in your environment, or must it work offline? Choose an open-weight model. If the requirement is only isolation, also price a private deployment from a closed vendor.
- Are you embedding on a device? Test
voyage-4-nanoand EmbeddingGemma. - Do you need images, audio or video? Start with a closed multimodal API. Open options exist, but check the licence: both Jina v5 Omni's non-commercial terms and Jina v4's Qwen Research License can rule them out.
- Do you process many billions of tokens each month, or need frequent large backfills? Calculate self-hosting costs using measured throughput.
- Do you need one self-hosted model for hybrid search? Test BGE-M3.
- None of the above? Start with a closed API, then keep Qwen3-Embedding-4B or
pplx-embed-v1in your evaluation as a self-hosted benchmark.
Then evaluate three or four candidates on real queries. My RAG evaluation guide explains how to build that test set.
Common mistakes to avoid
- Treating “open” as a licence. Check the terms for each exact model and version.
- Trusting one leaderboard. A public average can hide your language, domain and query style.
- Comparing family names. “Nomic”, “Gemini” and “Qwen” each cover different models with different abilities.
- Skipping required prefixes. Follow the card and test with the exact prompt format you will ship.
- Using a sentence-similarity model for retrieval. The Bengali study found paraphrase-focused MPNet and MiniLM models nearly useless, with Recall@10 below 0.01.
- Comparing API price with GPU rental alone. Include redundancy, idle capacity and engineering time.
- Choosing the largest dimension by default. Higher dimensions increase storage and memory costs. Test a smaller size before paying for more.
- Ignoring keyword search. BM25 beat dense retrieval in both a financial study and the Bengali study. Include it in your baseline.
- Keeping no path to re-embed. Store the source text, chunk metadata and model version so that you can migrate later.
Frequently asked questions
Are open-source embedding models as good as closed models?
On some workloads, yes. In Techsy's small test, Qwen3-Embedding-8B scored 0.87 for Recall@10 against 0.89 for the best closed API, and that gap is within the likely noise. Vendor-run tests favour closed models more strongly, and results differ a lot by domain. Test on your data.
What is the best open-source embedding model for RAG?
For commercial use, I would start with Qwen3-Embedding-4B, then add pplx-embed-v1 and BGE-M3 to the same evaluation. Those three cover different strengths and all have permissive licences.
Which embedding model is best for local use on a laptop?
Test voyage-4-nano and EmbeddingGemma first. Use all-MiniLM-L6-v2 if you only need a fast prototype on short English text.
Can I use Jina Embeddings v5 commercially?
The two v5 model cards I checked use CC BY-NC 4.0 and ask commercial users to contact Jina. Get that agreement before shipping them in a commercial product.
Is self-hosting cheaper than an API?
Sometimes. It is often cheaper for large batch jobs, and less often for modest live traffic once you pay for always-on capacity and operations. Calculate it using measured throughput rather than a rule of thumb.
Do I have to re-embed everything if I change models?
Yes. Vectors from different models cannot be meaningfully compared, unless a vendor documents that specific models share a space. Build the new index separately, evaluate it, then switch traffic.
A practical implementation path
Start with a small labelled query set and a keyword baseline. Compare one closed API, one permissive open-weight model and a hybrid configuration before choosing infrastructure. Use the vector database guide to plan storage, and keep each model version with its vectors from day one.
If you want this built properly, I develop custom RAG systems with model evaluation, ingestion, access rules and source citations. Tell me about your documents and requirements.
