---
title: "11 — Vectorize: Vector Search at the Edge"
uid: vectorize
tags: ["similarity-search", "rag", "cloudflare", "roadmap:cloudflare", "vectorize", "vector-database", "embeddings"]
excerpt: "Vectorize answers one question — which stored vectors are nearest to this query — and that single primitive makes semantic search and RAG work."
date: 2026-08-13T03:28:17+0000
source: https://www.aveshina.my.id/en/blog/vectorize
---

"A vector database for Workers, I guess" was my Vectorize summary, and it buried the primitive underneath. The model that surfaced it: **Vectorize is an index of high-dimensional vectors that answers "which stored vectors are nearest to this query vector?" — and that single question is the primitive that makes semantic search, recommendations, and retrieval-augmented generation work.** [1] The vector database isn't the interesting part; the _embedding_ that produces the vectors is, and Vectorize is the layer that stores and searches them.

The framing that landed is the pipeline shape. Vectors don't appear from nowhere — they're the output of an embedding model, which turns text (or images, or audio) into a fixed-length array of floats where semantic similarity maps to geometric proximity [2]. Two pieces of text with similar meaning produce vectors that are close together in the embedding space. Vectorize's job is to store those vectors and, given a query vector, quickly return the stored vectors that are nearest to it. Workers AI does the embedding; Vectorize does the search.

```figure
<svg viewBox="0 0 740 280" xmlns="http://www.w3.org/2000/svg" class="my-6 w-full max-w-2xl" role="img" aria-label="The vector search pipeline. Left: source text is embedded by a Workers AI model into a vector. Middle: the vector lands in Vectorize's index alongside other stored vectors. Right: at query time, the query is embedded the same way, and Vectorize returns the nearest stored vectors — the semantic matches.">
  <defs>
    <marker id="varrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto">
      <path d="M0,0 L10,5 L0,10 z" fill="#64748b"/>
    </marker>
  </defs>
  <g font-family="ui-sans-serif, system-ui, sans-serif" text-rendering="geometricPrecision">

    <!-- stage 1: embed -->
    <rect x="20" y="100" width="120" height="60" rx="8" fill="#e0e7ff" stroke="#6366f1" stroke-width="1.5"/>
    <text x="80" y="124" font-size="11" font-weight="700" fill="#1e1b4b" text-anchor="middle">source text</text>
    <text x="80" y="142" font-size="9" fill="#475569" text-anchor="middle">"how do I deploy?"</text>

    <rect x="180" y="100" width="120" height="60" rx="8" fill="#dcfce7" stroke="#16a34a" stroke-width="1.5"/>
    <text x="240" y="122" font-size="11" font-weight="700" fill="#052e16" text-anchor="middle">Workers AI</text>
    <text x="240" y="138" font-size="9" fill="#052e16" text-anchor="middle">embedding model</text>
    <text x="240" y="152" font-size="9" fill="#052e16" text-anchor="middle">→ vector</text>

    <path d="M140,130 L178,130" fill="none" stroke="#64748b" stroke-width="1.5" marker-end="url(#varrow)"/>

    <!-- stage 2: index -->
    <rect x="340" y="60" width="160" height="160" rx="8" fill="#fef9c3" stroke="#ca8a04" stroke-width="1.5"/>
    <text x="420" y="82" font-size="11" font-weight="700" fill="#422006" text-anchor="middle">Vectorize index</text>

    <circle cx="380" cy="120" r="4" fill="#16a34a"/>
    <circle cx="410" cy="140" r="4" fill="#16a34a"/>
    <circle cx="395" cy="165" r="4" fill="#16a34a"/>
    <circle cx="440" cy="120" r="4" fill="#16a34a"/>
    <circle cx="460" cy="170" r="4" fill="#16a34a"/>
    <circle cx="470" cy="195" r="4" fill="#16a34a"/>

    <!-- query vector -->
    <circle cx="425" cy="150" r="7" fill="#dc2626" stroke="#7f1d1d" stroke-width="2"/>
    <text x="425" y="40" font-size="10" font-weight="700" fill="#dc2626" text-anchor="middle">query vector</text>

    <!-- nearest neighbors halo -->
    <circle cx="425" cy="150" r="35" fill="none" stroke="#dc2626" stroke-width="1" stroke-dasharray="3,2" opacity="0.5"/>

    <path d="M300,130 L338,130" fill="none" stroke="#64748b" stroke-width="1.5" marker-end="url(#varrow)"/>

    <!-- stage 3: results -->
    <rect x="540" y="100" width="160" height="60" rx="8" fill="#fce7f3" stroke="#db2777" stroke-width="1.5"/>
    <text x="620" y="120" font-size="11" font-weight="700" fill="#500724" text-anchor="middle">nearest vectors</text>
    <text x="620" y="138" font-size="9" fill="#500724" text-anchor="middle">→ semantic matches</text>
    <text x="620" y="152" font-size="9" fill="#500724" text-anchor="middle">"deploying a Worker"</text>

    <path d="M500,130 L538,130" fill="none" stroke="#64748b" stroke-width="1.5" marker-end="url(#varrow)"/>

    <text x="370" y="250" font-size="11" font-weight="700" fill="#1e1b4b" text-anchor="middle">embed once at index time · embed the query at search time · Vectorize finds the nearest</text>
    <text x="370" y="268" font-size="10" font-style="italic" fill="#64748b" text-anchor="middle">same embedding model for both — that's why the geometry means something</text>
  </g>
</svg>
```

## Vector embeddings

The non-negotiable prerequisite is understanding what an embedding actually _is_ [2]. An embedding model maps a piece of content — a sentence, a paragraph, an image — to a fixed-length vector (often 768 or 1536 floats). The model is trained so that content with similar meaning lands at nearby points in that vector space. "How do I deploy?" and "What's the deployment process?" produce vectors that are nearly on top of each other; "How do I deploy?" and "Recipe for pancakes" produce vectors that are far apart.

The critical implication: the embedding model is a shared coordinate system. Every vector in my index has to come from the _same_ model, because proximity only means something within one model's space. Mixing embeddings from different models produces a broken index.

## Similarity search

Vectorize answers the nearest-neighbor question: given a query vector, return the stored vectors closest to it, ranked by distance [3]. The distance metric (cosine similarity is the common default) measures how "similar" two vectors are. The result is a ranked list of stored items, each with a similarity score.

The mechanics that matter for me as a user:

- **Indexing is offline-ish.** I embed my corpus (documents, product descriptions, support articles) once and insert the vectors into the index, each with an identifier pointing back to the source content.
- **Querying is two-step.** At search time, I embed the query with the same model, then ask Vectorize for the nearest vectors. The identifiers come back, and I fetch the actual content from wherever it lives (D1, R2, KV).
- **The index is approximate, not exact.** Vectorize (like most vector databases at scale) uses approximate nearest neighbor (ANN) algorithms, which trade a tiny amount of recall for large speed gains. For most use cases the approximation is invisible; for exact-match requirements, it's a known trade.

## AI-powered search

The full pipeline that makes Vectorize useful in practice — the reference calls it "AI-powered search" — has four steps [4]:

1. **Embed the corpus.** Run every piece of searchable content through a Workers AI embedding model, store the resulting vectors in Vectorize alongside an ID pointing back to the source.
2. **Store the source content.** Keep the actual documents in D1, R2, or KV, keyed by the same ID. Vectorize holds the vectors; something else holds the text.
3. **Embed the query.** When a user searches, run their query through the same embedding model.
4. **Search and return.** Ask Vectorize for the nearest vectors to the query, take the IDs, fetch the source content, return it as results.

The payoff is search that understands meaning, not just keywords. A query of "deployment problems" finds documents about "build failures during publish" because the embeddings capture the semantic relationship, even with zero shared words. This is the basis of semantic search and of retrieval-augmented generation (RAG) — where the retrieved chunks become context for an LLM's answer.

## Where Vectorize fits

The decision rule:

- **Use Vectorize** for: semantic search over a corpus, "find similar items" recommendations, deduplication of near-identical content, RAG context retrieval.
- **Don't use Vectorize** for: exact-key lookup (that's KV), structured relational queries (that's D1), or anything that doesn't reduce to "find nearby vectors."

A common mistake is reaching for a vector database when a simpler tool would do. If the search is keyword-based and the corpus is small, full-text search in D1 (SQLite's FTS) may be enough. Vectorize earns its complexity when meaning-based retrieval is the actual requirement.

## How I use this

The pattern I keep: pick one embedding model and stick with it for the life of the index, embed the corpus as a batch job (a scheduled Worker or a one-off script), store the source content in D1 keyed by the same IDs, and at query time embed the query with the same model and fetch the top-K matches' source from D1. The index is a routing layer that tells me _which_ records to read; it's never the source of truth for the content itself. When I'm tempted to treat Vectorize as a general database, that's the signal to step back — it's a search index, and it's at its best when its job is precisely that.

## References

[1] Cloudflare, "Introduction to Vectorize — Cloudflare Docs," Cloudflare Docs, 2024. [Online]. Available: [https://developers.cloudflare.com/vectorize/get-started/intro/](https://developers.cloudflare.com/vectorize/get-started/intro/)

[2] Cloudflare, "Vector database — Cloudflare Docs," Cloudflare Docs, 2024. [Online]. Available: [https://developers.cloudflare.com/vectorize/reference/what-is-a-vector-database/](https://developers.cloudflare.com/vectorize/reference/what-is-a-vector-database/)

[3] Cloudflare, "Cloudflare Vectorize," Cloudflare Docs, 2024. [Online]. Available: [https://developers.cloudflare.com/vectorize/](https://developers.cloudflare.com/vectorize/)

[4] C. Tehio, "How to use Cloudflare Workers AI for building an AI-powered search," dev.to, 2024. [Online]. Available: [https://dev.to/charlestehio/how-to-use-cloudflare-workers-ai-for-building-an-ai-powered-search-bar-51jn](https://dev.to/charlestehio/how-to-use-cloudflare-workers-ai-for-building-an-ai-powered-search-bar-51jn)

```quiz
Q: What does Vectorize store and search?
- Plain text documents, indexed by keyword
- High-dimensional vectors (embeddings), searched by nearest-neighbor proximity
- SQL tables of structured records
correct: 1
explain: Vectorize is a vector index. It stores vectors produced by an embedding model and answers "which stored vectors are nearest to this query vector?" — the primitive behind semantic search and RAG.

Q: Why must every vector in an index come from the same embedding model?
- For licensing reasons — different models have different licenses
- Because proximity only means something within one model's coordinate space; mixing models produces a broken index
- For storage efficiency — uniform vectors compress better
correct: 1
explain: An embedding model defines a shared space where similar content lands nearby. If vectors come from different models, their coordinates aren't comparable, and "nearest" stops meaning anything useful.

Q: At query time, what are the two steps for a semantic search?
- Embed the query with the same model, then ask Vectorize for the nearest vectors
- Run a SQL SELECT against the index, then fetch the vectors
- Fetch all vectors and sort them client-side
correct: 0
explain: Embed the query with the same embedding model used at index time, then ask Vectorize for the nearest stored vectors. The IDs that come back let you fetch the actual source content from D1/R2/KV.

Q: Vectorize uses approximate nearest neighbor (ANN) search. What does that mean?
- It returns exact matches only, missing similar items
- It trades a tiny amount of recall for large speed gains — for most use cases the approximation is invisible
- It can only search approximately, so results are unreliable
correct: 1
explain: Exact nearest-neighbor over millions of vectors is too slow. ANN algorithms get most of the right answers in a fraction of the time. For typical search/recommendation use cases, the small recall loss is invisible.

Q: You need exact-key lookup of a value by ID. Do you reach for Vectorize?
- Yes — Vectorize is a general-purpose database
- No — exact-key lookup is KV's job; Vectorize is for meaning-based nearest-neighbor search
- Yes, but only after embedding the key
correct: 1
explain: A common mistake is using a vector database when a simpler tool fits. Exact-key lookup is KV's sweet spot. Vectorize earns its complexity only when "find nearby vectors" is the actual requirement.
```
