AI Engineer Roadmap All lessons Interactive Quiz MernStackDev GitHub

Dot Product

Play the interactive lesson: Dot productRead on GitHub
On this page
  1. Explain it like I'm new
  2. Watch it
  3. How it works
  4. Code example
  5. When to use it / when not to
  6. Common mistakes
  7. Recap
  8. Interview questions
  9. Go deeper

Level: Beginner · Reading time: 6 min · Phase: 1 — RAG Foundations

In one line: The dot product multiplies two vectors element by element and adds the results; a bigger number means the vectors are more aligned and/or longer.

Before you start: Embeddings and Cosine Similarity. You should know that an embedding is a vector (a list of numbers) and what vector length means.

Explain it like I'm new

Imagine scoring a restaurant for a friend. Your friend cares about taste (weight 3), price (weight 1) and distance (weight 2). The restaurant rates 5, 2 and 4. The score is 3·5 + 1·2 + 2·4 = 25. That is a dot product: preferences × features, summed.

In search, the query embedding plays the "preferences" role and each document embedding the "features" role. Dimensions where both are large and positive push the score up. Dimensions with opposite signs pull it down.

The dot product mixes two things: direction (do they point the same way?) and length (how big are the vectors?). Formally, a · b = ‖a‖ × ‖b‖ × cos(angle). So it is cosine similarity multiplied by both lengths.

Words to know:

It is also the cheapest similarity to compute: one multiply and one add per dimension, no square roots. Hardware (CPUs, GPUs) is very fast at it, which is why vector databases love it.

Watch it

Dot product: Multiply matching numbers, then add. A worked example.
Dot product: Multiply matching numbers, then add. A worked example.

It plays on a loop. Read the caption in the box, one step at a time. Want to go at your own pace? Step through it with Previous and Next.

How it works

  1. Pair up the numbers at the same position in both vectors.
  2. Multiply each pair.
  3. Add all the products.
a = [ 1,  2,  3]
b = [ 2,  4,  6]
     --  --  --
      2 + 8 + 18 = 28

Worked examples (all in code/rag_vector_math.py):

The length effect. Query q = [1.0, 0.2], documents d0 = [0.9, 0.1] and d1 = [5.0, 5.0].

After normalizing every vector to length 1, the dot product is cosine similarity. That is why many systems normalize embeddings once at ingest, then use the fast dot product at query time. In FAISS this is called inner product (IP).

Worked example

The repo demo ranks three document vectors for a query. Here is the same idea by hand with q = [1, 0] and documents d0 = [1, 0], d1 = [3, 3], d2 = [0, 1].

  1. q · d0 = 1·1 + 0·0 = 1.
  2. q · d1 = 1·3 + 0·3 = 3.
  3. q · d2 = 1·0 + 0·1 = 0.
  4. Ranking by dot product: d1, d0, d2. d1 wins even though it points 45° away from the query, because it is long.
  5. Cosine would give d0 = 1.0, d1 ≈ 0.707, d2 = 0.0, so d0 wins. Normalize first and dot product agrees with cosine.

This matches the repo's own result: rag_vector_math.py ranks by cosine as [0, 1, 2] but by dot as [1, 0, 2], and prints "dot prefers the long vector [5,5]; cosine ignores length."

Code example

import math

def dot(a, b):
    if len(a) != len(b):
        raise ValueError("vectors must have the same length")
    return sum(x * y for x, y in zip(a, b))

def normalize(a):
    n = math.sqrt(dot(a, a))
    return [x / n for x in a]

q, d0, d1 = [1.0, 0.2], [0.9, 0.1], [5.0, 5.0]
print(dot(q, d0), dot(q, d1))                         # 0.92  6.0   -> d1 "wins"
qn, d0n, d1n = normalize(q), normalize(d0), normalize(d1)
print(round(dot(qn, d0n), 3), round(dot(qn, d1n), 3)) # 0.996 0.832 -> d0 wins (= cosine)

The rank() helper in code/rag_vector_math.py shows rankings by all three metrics.

In real projects (FAISS inner-product index on normalized vectors = cosine search):

import faiss
import numpy as np

xb = np.random.rand(10_000, 384).astype("float32")
faiss.normalize_L2(xb)                     # in place: rows become unit length
index = faiss.IndexFlatIP(384)             # inner product
index.add(xb)
q = np.random.rand(1, 384).astype("float32"); faiss.normalize_L2(q)
scores, ids = index.search(q, 5)           # scores are cosine similarities

When to use it / when not to

Common mistakes

Recap

If you remember only three things:

Interview questions

1. What is the relationship between dot product and cosine similarity? <details><summary>Answer</summary> a · b = ‖a‖ ‖b‖ cos(θ). Cosine is the dot product divided by both lengths, so for unit vectors they are equal. </details>

2. Why do vector databases often prefer dot product? <details><summary>Answer</summary> It is the cheapest similarity (no square roots or divisions) and maps well to fast matrix operations. With normalized embeddings it gives the same ranking as cosine. </details>

3. When can raw dot product give bad search results? <details><summary>Answer</summary> When vectors are not normalized and lengths vary for reasons unrelated to relevance; long vectors score high for many queries regardless of direction. </details>

Go deeper

Prev: Euclidean Distance · Next: HNSW · Back to phase: Phase 1