what an embedding actually is

An embedding model maps a piece of text to a fixed-length vector of floats (commonly 384-3072 dimensions) such that texts with similar meaning end up close together in that vector space, and unrelated texts end up far apart. It's a separate, usually much smaller, model than the LLM you'd chat with — trained specifically so that distance in vector space tracks semantic similarity, not to generate text at all.

from openai import OpenAI
client = OpenAI()

vec = client.embeddings.create(
    model="text-embedding-3-small",
    input="How do I reset my password?"
).data[0].embedding
print(len(vec))   # 1536 floats

cosine similarity

import numpy as np

def cosine_similarity(a, b):
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
# 1.0 = identical direction, 0.0 = unrelated, -1.0 = opposite
Cosine similarity compares direction, not magnitude — which matters because embedding magnitude often correlates with things unrelated to meaning (like text length), so two texts about the same topic at different lengths should still land close together directionally even if their raw vector norms differ.

picking a model and dimensionality

ConsiderationTrade-off
Higher dimensionalityGenerally better recall, but more storage and slower similarity search at scale
General-purpose vs. domain-specific modelDomain-tuned embeddings (e.g. code, legal, medical) usually outperform general models within their domain
Matryoshka/truncatable embeddingsSome newer models let you truncate the vector to fewer dimensions with graceful quality degradation, trading a small accuracy hit for less storage
Never mix vectors from two different embedding models in the same similarity search — their vector spaces aren't aligned, so distances between them are meaningless even if the dimensionality happens to match.

storing and querying at scale

Brute-force cosine similarity against every stored vector is fine up to roughly tens of thousands of vectors; beyond that, an approximate nearest-neighbor index (HNSW is the common default) trades a small amount of recall for orders-of-magnitude faster lookup. PostgreSQL's pgvector extension implements exactly this — see PostgreSQL Extensions (pgvector, PostGIS) if you'd rather not stand up a dedicated vector database.

where to go from here

RAG Architecture — the main consumer of embeddings in an LLM application.
PostgreSQL Extensions (pgvector, PostGIS) — storing and indexing vectors in Postgres.
Chunking & Retrieval Strategies — what you actually embed, and how it's split first.