If you ask a database whether two strings are equal, it compares the bytes. If the bytes match, equal. If not, not equal. Synonyms, paraphrases, near-misses, things that are obviously about the same topic but use different words: invisible.
That works for some questions. "Find the row where id = 12345" is a byte-comparison question, and a B-tree finds it in microseconds. But "find documents about renewable energy" is not a byte-comparison question. The word "renewable" might not appear; the document might be about wind farms, solar arrays, or hydroelectric dams. Keyword search misses these unless someone has written down every synonym in advance.
Embeddings exist to make those questions answerable.

The trick
You take each item, run it through a model, and out comes a list of numbers. Maybe 384 numbers, maybe 1536, maybe 768; the count depends on the model. That list is the item's embedding.
The numbers are coordinates. They place the item somewhere in a high-dimensional space. The geometry of the space is set up so that items with similar meaning land near each other, and items with different meaning land far apart. "Wind farms in Iowa" lands near "Solar power in California" because both are about renewable energy. "Wind farms in Iowa" lands far from "Marble countertops" because those are about different things, even though "in" appears in both.
Searching for documents about renewable energy is now a geometry question: which items are nearest to the embedding of the phrase "renewable energy"? That's something a vector database can do quickly, even with millions of items.

Where the numbers come from
A neural network. Specifically, one that was trained on a huge corpus of text (or images, or code, or whatever modality you care about) with an objective something like: "given two inputs, produce embeddings that are close together if they're related, and far apart if they're not."
The training data does the work. If you feed a model billions of pages of Wikipedia and StackOverflow and arXiv papers and Reddit threads, it learns that "wind farm" and "solar array" appear in similar contexts and should produce similar embeddings, even though the surface words have nothing in common. The model is just learning patterns of co-occurrence at massive scale, but the result behaves remarkably like a model of meaning.
You don't have to train one yourself. There are good open models you can download and run on a laptop CPU (all-MiniLM-L6-v2 is one); there are paid hosted models from OpenAI and Cohere and others; there are domain-specific models trained on legal documents, biomedical literature, code repositories. They differ in size, speed, cost, dimensionality, and quality on your particular data.
For the longer, no-math story of how a model comes to know what words mean in the first place — the training intuition behind all of this — see How a computer learns what words mean.
What "near" means
Once everything is embedded, "find similar items" becomes "find nearby vectors." But there's more than one way to measure distance.
The most common one for text embeddings is cosine similarity. It looks at the angle between two vectors, ignoring how long either one is. Two vectors pointing in the same direction have cosine similarity 1.0; two perpendicular vectors have 0.0; two pointing in opposite directions have -1.0. (Vector Panda's API normalizes the score to fall in [0, 1] for ease of reading.)
There are other metrics. Euclidean distance treats vectors as points and measures the literal straight-line distance between them. Dot product measures angle and magnitude together; it's similar to cosine but doesn't normalize. Most modern text models produce normalized vectors and assume cosine, so cosine is the default basically everywhere. If you're using a model that recommends a different metric, the model card will tell you.
The important thing is that all three are doing the same kind of work: turning "are these two things meaningfully related" into a single number you can sort by.

Why dimensionality matters
A 384-dimensional embedding is a list of 384 floats. A 1536-dimensional embedding is a list of 1536 floats. Both fit in memory; both can be queried quickly; both encode meaning. So why do bigger models produce bigger vectors?
More dimensions give the model more axes along which to express meaning. With 384 numbers, the model has 384 ways to differentiate items. With 1536, four times as many. The result tends to be a more nuanced model: it can distinguish "wind farms in Iowa" from "wind farms in Texas" more reliably than a smaller model can.
It's not free. More dimensions means more bytes per row (a 1536-dim float32 vector is 6 KB; ten million of them is 60 GB). It means more arithmetic per query, so latency goes up. It means more memory pressure on the hot path. The right dimensionality is the smallest one that gives you the result quality you need; bigger isn't automatically better.

How to pick a model
Start with the question of where it runs. Local models (sentence-transformers and friends) cost nothing per query and don't send your data anywhere; they're typically smaller and a touch lower quality. Hosted models (OpenAI, Cohere, Voyage) have stronger results on most benchmarks but charge per token and require sending text over the wire.
Then think about your domain. General-purpose models work fine for most things. If you're searching legal contracts or medical records or source code, a domain-specific model will usually beat a general one by a noticeable margin. The Massive Text Embedding Benchmark (MTEB) leaderboard at huggingface.co/spaces/mteb/leaderboard ranks dozens of models on standard tasks and is a reasonable starting point.
Then iterate. Pick a model that looks plausible, embed a small slice of your data, run a handful of representative queries, and look at the top-k results yourself. If they're sensible, you're done. If they're not, switch models. The setup cost is low and the quality difference between a well-chosen model and a default one can be large.
Closing
The reason vector search works at all is that someone trained a model that turns the squishy notion of "meaning" into a list of numbers. That's a remarkable thing, and it took a couple of decades of research to get right, but the result is straightforward to use: hand the model your text, get a vector back, store the vector, and compare new vectors against it later.
Vector Panda is the storage and comparison layer. The model is yours to choose. The two pieces are decoupled on purpose: as embedding models get better (and they do, every few months), you can swap to a new one without touching the database, and your existing pipeline keeps working with whatever vectors you point it at.
