At Juiced Wheels a bench tech has a customer's e-bike on the stand and the clock running — and the answer is buried in a parts catalog and a stack of manuals no keyword box can navigate.
Dedicated clusters running 24/7 even with zero traffic.
Vector DB subscription bills for all 30 days, used or not.
Pinecone, ES clusters pin to one region. EU/Asia queries pay 200ms+ tax.
Vector DB + keyword search are separate systems. Four vendors, four bills, glue code to merge.
Pay per request, per query, per GB stored — not per hour.
Workers run within ms of the user, not in us-east-1.
Workers + D1 + Vectorize + KV + R2 in one ecosystem.
V8 isolates start in sub-ms — the shop lights flick on, no warming a cold engine.
Each one cut cost and blast radius by an order of magnitude. V8 isolates are what makes scale-to-zero affordable at edge density.
Full guest OS · hypervisor
Bare-metal era. Pay 24/7 for capacity you may never use.
Shared kernel · namespaced procs
*Then a 500 ms cold start the next time someone shows up.
One process · thousands of tenants
Same V8 sandbox Chrome uses for tabs — battle-tested at billions of executions/day.
Three search engines, three shopping behaviors. The customer's voice picks the station: semantic for symptoms, faceted for browsing with constraints, keyword for exact parts.
Measured engine times, warm queries. †Semantic embed: ~3ms cached / ~200ms cold. ‡Meili is remote-hosted (NYC); warm round-trip adds ~400–700ms — FTS5 + Vectorize are co-located in the worker.
Keywords fail when users describe problems instead of naming parts. "My bike has a flat tire" should match "innertube replacement" — vector search makes this connection.
Workers AI maps each sentence to 768 numbers — coordinates on a "meaning map," where similar meanings land near each other even with zero shared words. embeddinggemma-300m generates them; Vectorize finds the nearest via cosine similarity.
CUSTOMER ASKS
"My bike has a flat tire"
MEANING MAP · NEAREST AISLE WINS
Filtering a big catalog by structured attributes — brand, wheel size, valve type, price, in-stock — with a live count on every option. It's how a tech narrows 84,000 parts down to the 8 that fit, without typing a perfect query.
GROUP BY can handle — plus typo tolerance ("shrader" finds "Schrader"). It's a faceted-search engine with its own hybrid keyword + vector ranking.CUSTOMER ASKS
"Innertube — 26" × 4", Schrader valve"
typo-tolerant · ~28ms engine · fallback to D1 FTS5
Meilisearch ($30/mo) is the only non-Cloudflare piece of this whole stack — today's one platform gap for fast faceting + typo tolerance. If Cloudflare ships a native equivalent, this line drops to $0 and the architecture is 100% first-party.
D1 is Cloudflare's serverless SQLite; FTS5 is its built-in full-text search — co-located with your Worker, no extra service, no extra bill.
CUSTOMER ASKS
"I need part TU1200"
Fat Bike Tube · 26×4 Schrader
BM25 score 8.4 · 7 ms (measured)
When one engine isn't enough, fire all three in parallel and merge by weighted relevance score. The agent never sees three result lists — just one ranked output.
Manuals 2.0× · Docs 1.5× · Parts 0.2×
Most OEM service manuals are scanned images or flattened exports — there's no selectable text layer. OCR (Optical Character Recognition) turns those page images into searchable text. I then inject that text back into the PDF as a hidden layer, so the manual is fully searchable in any viewer while looking identical to the original. You can't chunk what you can't read.
Tech reads at the bench
Most tutorials split documents into fixed-size blocks and embed them as-is — like cutting a manual into unlabeled index cards. You get a match back, but no idea which card it's from.
An orphaned chunk like "torque the bolts to 40 Nm" is useless without knowing it's a Bosch CX mid-drive install vs. a Shimano hub motor teardown.
{ text: "Torque bolts to 40 Nm. Check alignment before tightening...", vector: [0.23, -0.41, ...] }
{ text: "Torque bolts to 40 Nm...", vector: [0.23, -0.41, ...], metadata: { title: "Bosch CX Installation", path: "/guides/bosch-cx-install", tags: ["mid-drive","torque"], category: "installation", source: "manual" } }
Metadata gives chunks a structural home. A 1–2 sentence LLM summary — Anthropic's Contextual Retrieval pattern — adds a sticky note that stays findable even when the page is OCR garbage.
Labor division: LLMs author chunk context; humans author the graph (slides 19–21) — enrich text, don't invent ontology.
Query: "Bosch Drive Unit speed sensor installation"
A Worker is a hotel room — fresh every request, your stuff is gone. A Durable Object is your apartment — same address, same key, your memory is still on the counter.
High-token tool work goes to a near-free model; the premium model only sees the compressed result and writes the answer. Like a shop, the apprentice does the bulk grunt work and the master tech makes the call.
gpt-oss-120bread_manual · get_content_section
· others compress only above the 4K-token budget
Search returns text. Diagnosis needs causality — what supplies what, what cuts what, what symptom traces to which subsystem.
/api/search/unifiedquery_ebike_graphI tried LLM extraction. It hallucinated. I shipped hand-crafted instead — and the agent still queries the graph every diagnostic turn. Here's the trade-off, the anatomy, and the live trace.
I was already running PostHog for product analytics — funnels, retention, session replay. Turning on its LLM observability dropped every AI trace onto that same dashboard: cost, tokens, latency, and tool-routing, per turn.
$0.009. You only see that once it's traced.AI traces land right next to the product analytics I already had.
Gathered with AI search — Brave · Tavily · Firecrawl
OCR'd · ~593K chunks · full-text + vector indexed
Built from Google Deep Research, human-curated
full-text + vector indexed
Nightly refresh from 3 vendor feeds
D1 faceted, Meili-accelerated
Workers + D1 + Vectorize + Meili included
Five hard-won lessons from running this in production — not the order I learned them, but what I'd hand my past self on day one.
Instrument before you optimize with PostHog — you can't tune what you can't measure.
Cheap models do bulk context; a premium model synthesizes. ~10× cheaper per token.
Truth is human work; let the LLM traverse it. 825 profiled nodes beat batch-API extraction.
Tag every chunk: source, section, vehicle class, date. Context disambiguates. 66.7% → 93.3% Top-1.
Live end-to-end tests on every deploy catch what unit mocks never will.
The retrieval primitives you just saw — provisioned for you, fully managed.
~80% of the retrieval pipeline without writing a Worker. It provisions the whole retrieval pipeline you just built:
Same R2 + Workers AI + Vectorize + AI Gateway pipeline.
Started on AI Search? Steps 1–4 (the whole hybrid retrieval pipeline) come provisioned — your real build is the agent + memory + domain graph.
wrangler d1 create my-search-db
CREATE VIRTUAL TABLE ... USING fts5()
wrangler vectorize create my-index \
--dimensions=768 --metric=cosine
@cloudflare/think — streaming, tools, per-user Durable Object memory, crash recovery.Start on AI Search → grow into the primitives as you scale. Same edge, same economics, no rip-and-replace.
This deck runs on reveal.js — here's everything you can do from the keyboard.