Create the index with dimensions matching your embedding model's output and an immutable distance metric: npx wrangler vectorize create tutorial-index --dimensions=768 --metric=cosine. Dimensions and metric cannot be changed after creation; use 768 if pairing with @cf/baai/bge-base-en-v1.5.
Create metadata indexes BEFORE inserting vectors so those fields become filterable: npx wrangler vectorize create-metadata-index tutorial-index --property-name=url --type=string. Types: string, number, boolean. Max 10 metadata indexes per Vectorize index.
Add the binding to wrangler.jsonc: {"vectorize":[{"binding":"VECTORIZE","index_name":"tutorial-index"}]}, or wrangler.toml: [[vectorize]] binding = "VECTORIZE" / index_name = "tutorial-index".
Upsert vectors in Worker code: await env.VECTORIZE.upsert([{ id: "1", values: [ ...768 floats... ], metadata: { url: "/products/sku/1", price: 19.99 } }]). Use upsert (not insert) if the same id may be written more than once, since insert() keeps the first-written values.
Respect batch limits: up to 1,000 vectors per Workers-binding call (5,000 via HTTP API), 200,000 vectors per underlying mutation job, 100MB max upload size.
Check ingestion status if results look stale: npx wrangler vectorize info tutorial-index. Allow a few seconds after insert/upsert before new vectors are queryable (eventual consistency).
Deploy: npx wrangler deploy.
Official documentation verified for this route: https://developers.cloudflare.com/vectorize/get-started/intro/ | https://developers.cloudflare.com/vectorize/best-practices/create-indexes/ | https://developers.cloudflare.com/vectorize/best-practices/insert-vectors/ | https://developers.cloudflare.com/vectorize/best-practices/query-vectors/ | https://developers.cloudflare.com/vectorize/reference/metadata-filtering/ | https://developers.cloudflare.com/vectorize/platform/limits/
Known gotchas
Index dimensions and distance metric are immutable once the index is created and must exactly match the output shape of the embedding model used (e.g. 768 for @cf/baai/bge-base-en-v1.5).
Vectors upserted before a metadata index existed on that field are NOT retroactively included in that metadata index, so filtering on them silently returns nothing until the vectors are re-upserted.
Max 10 metadata indexes per Vectorize index; only the first 64 bytes of a string metadata field are indexed for filtering (truncated on a UTF-8 boundary); total metadata per vector is capped at 10KiB; the compact filter JSON must stay under 2048 bytes.
insert() is first-write-wins on duplicate IDs — it neither updates the existing vector nor raises an error. Use upsert() when overwriting an existing id.
topK is capped at 50 when returning values or metadata and 100 when returning neither; a larger request is silently capped rather than rejected.
Account limits scale by plan: up to 10,000,000 vectors per index and up to 50,000 indexes/namespaces on Workers Paid, versus far lower caps on the Free plan.
Give your agent this knowledge — and 16,000+ more routes
One MCP install gives any agent live access to the full route map across 5,800+ domains, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp
Need this verified for your stack — or a route we don't have yet?