Skip to main content
December 2025 Update: Comprehensive guide to embeddings including model selection, dimensionality, fine-tuning, and production patterns.

What Are Embeddings?

If LLMs are the brain, embeddings are the language it uses to think about similarity. An embedding converts a chunk of text into a list of numbers (a vector) where similar meanings end up close together in number-space. It is like plotting cities on a map: New York and Boston end up near each other, while Tokyo is far away. Except instead of geographic coordinates, you have 1536 dimensions capturing meaning, topic, tone, and intent. Embeddings convert text into dense numerical vectors that capture semantic meaning:

Embedding Models Comparison

Choosing an embedding model is a three-way trade-off between quality, cost, and speed. OpenAI’s text-embedding-3-small is the default choice for most teams — it is cheap, fast, and good enough. Move to text-embedding-3-large when you need higher accuracy (legal, medical). Go open-source with BGE or MiniLM when cost is critical at scale (millions of documents) or you cannot send data to an external API. The table below gives the concrete numbers.

Getting Embeddings

OpenAI Embeddings

Dimensionality Reduction

This is one of the most underused features of OpenAI’s embedding models. You can request a 256-dimensional embedding instead of the full 1536, and OpenAI applies Matryoshka Representation Learning to give you a smaller vector that retains most of the quality. The practical impact is huge: 256 dimensions instead of 1536 means 6x less storage in your vector database, 6x faster similarity search, and cheaper pgvector indexes — all for a quality drop that is often less than 5% on retrieval benchmarks. OpenAI’s text-embedding-3 models support native dimension reduction:

Open Source Embeddings

Open-source embedding models run on your own hardware, which means zero API costs and no data leaving your network. The trade-off is that you need to manage the infrastructure: GPU for fast inference (or accept slower CPU speeds), model loading, and batching. For teams processing millions of documents, the math usually favors self-hosted: embedding 1M chunks costs ~20withOpenAIbuteffectively20 with OpenAI but effectively 0 with a local model (after the one-time GPU cost).

Similarity Metrics

Similarity metrics answer the question “how close are these two vectors?” Different metrics measure “closeness” differently, and picking the wrong one can silently degrade your search quality. The rule of thumb: use cosine similarity unless you have a specific reason not to. It is magnitude-invariant (a long document and a short document about the same topic will still be similar), which is exactly what you want for text.

Cosine Similarity

Other Metrics


Building a Similarity Search Engine


Hybrid Search: Embeddings + Keywords

Here is a scenario that pure embedding search fails at: a user asks “error code E-4021” and the most similar embeddings are about generic error handling rather than the specific error code. That is because embeddings capture meaning, not exact strings. Keyword search (BM25) handles this perfectly — it matches the literal text “E-4021.” Hybrid search combines both approaches: semantic similarity for understanding intent, keyword matching for precision. In practice, hybrid search outperforms either approach alone for 80-90% of real-world retrieval tasks. The alpha parameter controls the blend: 0.7 means 70% semantic weight and 30% keyword weight. Start there, then tune based on your query patterns. If users frequently search for specific identifiers, product names, or codes, lower alpha (more keyword weight). If queries are natural-language questions, raise it. Combine semantic search with keyword matching:

Embedding Optimization

The difference between a hobby project and a production embedding pipeline is how you handle scale. Embedding 100 documents is trivial. Embedding 1 million documents means dealing with rate limits, batching to reduce HTTP overhead, and caching to avoid re-embedding documents that haven’t changed. The patterns below address each of these concerns.

Batching and Rate Limiting

Caching Embeddings

Embeddings are deterministic: the same text with the same model always produces the same vector. This makes them perfect for caching. If a user re-uploads a document or you re-index your knowledge base, a cache prevents paying for the same embedding twice. The file-based cache below works for development and small datasets. For production, swap in Redis or a database-backed cache for concurrent access and TTL management.

Fine-Tuning Embeddings

When off-the-shelf embeddings aren’t cutting it — medical jargon isn’t matching synonyms, legal terms aren’t clustering correctly, or your domain-specific acronyms are treated as noise — fine-tuning adapts the model to your vocabulary and similarity relationships. The approach below uses contrastive learning: you provide pairs of texts with similarity scores, and the model adjusts its internal weights so that your domain’s notion of “similar” is reflected in the embedding space. Even 500-1000 labeled pairs can produce meaningful improvements. For domain-specific applications, fine-tune embedding models:

Embedding Model Selection Framework

Choosing an embedding model is a three-way trade-off. This decision table covers the most common scenarios. Decision flowchart:
  1. Can your data leave your network? If no, self-host BGE-large or E5-large.
  2. If yes, is your budget under $50/month for embeddings? Use text-embedding-3-small with reduced dimensions (256 or 512).
  3. If budget is flexible, is retrieval accuracy critical (legal, medical, compliance)? Use text-embedding-3-large.
  4. Are you embedding in multiple languages? Use Cohere multilingual or BGE-m3 (open-source multilingual).

Similarity Search Edge Cases

Queries and documents at different abstraction levels. A user asks “how do I make my app faster?” but the relevant document chunk says “optimize database query performance by adding indexes.” The semantic gap between the high-level question and the specific answer reduces similarity scores. Mitigation: generate hypothetical questions for each chunk at indexing time (HyDE approach), or index at multiple granularity levels. Short queries against long chunks. A 3-word query like “refund policy” produces a sparse embedding that matches poorly against 500-word chunks. The chunk’s embedding is an average of many topics, diluting the signal. Either use shorter chunks for short-query use cases, or apply query expansion (“refund policy” becomes “what is the refund and return policy for customers who want their money back”). Embedding model version mismatches. You embedded 1M documents with text-embedding-ada-002, then switched to text-embedding-3-small for new documents. These models produce vectors in different embedding spaces — cosine similarity between them is meaningless. Every vector in your database must come from the same model. Model changes require full re-indexing. Near-duplicate detection thresholds. Two documents are 95% identical except for a date. Their cosine similarity will be 0.98+. But a 0.95 threshold intended for semantic caching will also match “what is our return policy?” with “what is our shipping policy?” — similar structure, completely different intent. Tune your threshold on your actual data: plot similarity distributions for true matches vs. false matches and pick the threshold that minimizes overlap. Embedding normalization assumptions. OpenAI models return normalized vectors (unit length), so dot product equals cosine similarity. Some open-source models (older sentence-transformers) do NOT normalize by default. If you skip normalization and use dot product, longer documents get artificially higher scores. Always check normalize_embeddings=True when using sentence-transformers, or normalize manually.

Key Takeaways

Choose the Right Model

Balance quality, speed, and cost for your use case

Normalize Your Vectors

Pre-normalize for faster similarity search

Hybrid Search Works

Combine semantic + keyword for best results

Cache Everything

Embeddings are deterministic - cache aggressively

What’s Next

AI Streaming

Master streaming responses for real-time AI applications