Lesson 2 of 3 · Embeddings & Semantic Search

OpenAI Embedding Models

reading12 min

A machine learning engineer at a legal tech startup needed to build a contract similarity engine. She tested three embedding models on 10,000 legal documents. text-embedding-3-small found similar contracts with 89% accuracy. text-embedding-3-large hit 94%. But when she used the dimensions parameter to reduce text-embedding-3-large from 3,072 dimensions to 1,024, accuracy only dropped to 92% while storage costs fell by 67%. That single parameter saved her company $14,000 per year in vector database hosting.

Choosing the right embedding model is a cost-accuracy-speed tradeoff. This lesson covers every option and helps you make the right choice.

3

OpenAI embedding models to choose from -- each with distinct cost-performance characteristics

The Three Models

text-embedding-3-small

The workhorse. 1,536 dimensions by default. The cheapest option and fast enough for real-time applications. This is the model you should start with for most projects.

MTEB benchmark score: 62.3% (average across retrieval, classification, and clustering tasks)

Best for: Most production applications, high-volume processing, applications where cost matters more than maximum accuracy, prototyping and experimentation.

text-embedding-3-large

The premium option. 3,072 dimensions by default -- twice the dimensionality of text-embedding-3-small, capturing more nuanced semantic relationships. Higher accuracy on difficult retrieval tasks where subtle differences in meaning matter.

MTEB benchmark score: 64.6%

Best for: Legal document comparison, medical literature search, academic research, any domain where the difference between "similar" and "nearly identical" matters. Also useful when you need the dimensions parameter to find a custom accuracy-cost tradeoff.

text-embedding-ada-002 (legacy)

The previous generation. 1,536 dimensions, no dimensions parameter for reduction. Still functional but outperformed by text-embedding-3-small at a lower price. No reason to use this for new projects.

MTEB benchmark score: 61.0%

Best for: Nothing new. Only relevant if you have an existing system built on ada-002 and migration is not worth the effort.

The Dimensions Parameter

This is the most powerful and underused feature of the text-embedding-3 models. You can request embeddings with fewer dimensions than the default, and the model produces a compressed vector that retains most of the semantic information.

Python
from openai import OpenAI

client = OpenAI()

# Full 3072 dimensions
full = client.embeddings.create(
    model="text-embedding-3-large",
    input="Contract for sale of residential property"
)
print(len(full.data[0].embedding))  # 3072

# Reduced to 1024 dimensions
reduced = client.embeddings.create(
    model="text-embedding-3-large",
    input="Contract for sale of residential property",
    dimensions=1024
)
print(len(reduced.data[0].embedding))  # 1024

Why does this matter? Smaller vectors mean:

  • Lower storage costs: A vector database storing 1 million 3,072-dimension vectors uses ~12 GB. At 1,024 dimensions, that drops to ~4 GB.
  • Faster search: Comparing shorter vectors requires fewer mathematical operations.
  • Lower memory usage: Smaller vectors fit in RAM, enabling faster indexing.

MTEB Scores: What They Mean

MTEB (Massive Text Embedding Benchmark) evaluates embedding models across dozens of tasks in multiple categories:

Task CategoryWhat It TestsExample
RetrievalFinding relevant documents for a querySearch engines, RAG
ClassificationCategorizing text by topic or sentimentSpam detection, routing
ClusteringGrouping similar texts togetherTopic discovery, deduplication
Semantic similarityRating how similar two texts areDuplicate detection, paraphrase identification
Pair classificationDetermining if two texts have a specific relationshipEntailment, contradiction
Benchmark Scores Are Averages

A model with a higher average MTEB score is not necessarily better for your specific use case. text-embedding-3-small might outperform text-embedding-3-large on certain retrieval tasks while underperforming on clustering. Always benchmark on your actual data with your actual queries. The leaderboard is a starting point, not a verdict.

Token Limits and Pricing

Embedding models have a maximum input length of 8,192 tokens (roughly 6,000 words). Inputs longer than this are silently truncated -- the model processes only the first 8,192 tokens and ignores the rest.

Python
import tiktoken

encoder = tiktoken.encoding_for_model("text-embedding-3-small")
tokens = encoder.encode(your_text)

if len(tokens) > 8192:
    print(f"Warning: text has {len(tokens)} tokens, will be truncated to 8192")
    # Consider chunking the text instead of letting it truncate

Pricing is per token, with batch discounts for large volumes. For cost estimation:

Python
def estimate_embedding_cost(texts, model="text-embedding-3-small"):
    encoder = tiktoken.encoding_for_model(model)
    total_tokens = sum(len(encoder.encode(t)) for t in texts)
    
    # Approximate costs per 1M tokens (check current pricing)
    costs = {
        "text-embedding-3-small": 0.02,
        "text-embedding-3-large": 0.13,
        "text-embedding-ada-002": 0.10
    }
    
    cost = (total_tokens / 1_000_000) * costs[model]
    return {"total_tokens": total_tokens, "estimated_cost": f"${cost:.4f}"}

Measure the Dimensions Tradeoff

beginner
Do

Start with text-embedding-3-small for new projects. Use the dimensions parameter on text-embedding-3-large to find your optimal accuracy-cost point. Benchmark on your actual data before committing to a model.

Don't

Use text-embedding-ada-002 for new projects -- it is outperformed by newer models at lower cost. Assume higher MTEB score means better results for your use case. Let long texts silently truncate -- chunk them explicitly instead.

Concept Card