◉GEMINI LABJP
●ARGON — gemini-4-argon is generally available as of 10/13, aimed at complex coding, agents, math and science●DEEP RES — deep-research-pro-preview-12-2025 shuts down 10/23, 6 days left. Move to deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 is GA (10/06). gemini-3.1-flash-image is deprecated with no shutdown date yet●MCP — One write-up cut an 85,000-token tool result to 310 tokens by wrapping it in an ADK FunctionTool●FLASH — gemini-3.7-flash and 3.5-flash now route automatically to newer Flash models (10/08)●NEW — Stop Re-Reading Every Crash Report: Gre…●ARGON — gemini-4-argon is generally available as of 10/13, aimed at complex coding, agents, math and science●DEEP RES — deep-research-pro-preview-12-2025 shuts down 10/23, 6 days left. Move to deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 is GA (10/06). gemini-3.1-flash-image is deprecated with no shutdown date yet●MCP — One write-up cut an 85,000-token tool result to 310 tokens by wrapping it in an ADK FunctionTool●FLASH — gemini-3.7-flash and 3.5-flash now route automatically to newer Flash models (10/08)●NEW — Stop Re-Reading Every Crash Report: Gre…
Articles/API / SDK
◈ API / SDK/2026-05-10Intermediate

Cutting Gemini Embedding's output_dimensionality from 768 to 256 reduced my vector DB storage to one-third

An indie developer's record of trimming gemini-embedding-001 from 768 to 256 dimensions for an 80,000-row wallpaper recommendation index, with measured numbers on storage, cost, recall trade-offs, an int8 quantization implementation, a CI benchmark gate, and the five-step rollout plan I now use in production.

gemini119embedding10vector-database4matryoshkacost-optimization30

✦ Premium Article

One morning I opened the Cloudflare dashboard and saw that the vector storage I was running for a wallpaper app had grown to roughly three times what I had expected. A single feature — "show me wallpapers similar to this one" — was eating almost 2 GB. The reason was simple: I had been using gemini-embedding-001 at its default 768 dimensions for every row.

I have been building iPhone and Android apps as a solo developer since 2014, and across that lineup of wallpaper, healing, and law-of-attraction apps the cumulative downloads have passed 50 million. The active metadata for the recommendation index is around 80,000 rows. This article is a plain record of what happened when I dropped the embedding's output_dimensionality from 768 to 256: the recall, storage, and cost numbers I observed, the int8 quantization code I now ship, and the staged rollout I use so this kind of change never breaks production.

The morning 80,000 vectors started costing 2 GB

The raw vectors alone work out to roughly 80,000 × 768 × 4 bytes = ~240 MB. That on its own would be fine. In practice, however, the SQLite + sqlite-vec setup I was running carried indexes, JSON metadata, and an HNSW graph, and the total had crept up close to 2 GB. Cloudflare D1 storage is cheap in absolute terms, but watching the monthly bill drift upward without a clear reason is the kind of thing that quietly drains attention from an indie developer's day. The whole app is funded by AdMob revenue, so any fixed cost I can shave is one I want to shave.

The official documentation tells you that output_dimensionality accepts 128, 256, 512, or 768, but it does not tell you how much accuracy you lose at each step. The only way to find out where to cut is to measure on your own data. That measurement is what this article is about — not as theory, but as a snapshot of one indie project's numbers, so you have at least one reference point besides the docs before you make the decision for yours.

Why Matryoshka representation lets you keep the front of the vector

Gemini's embedding models are trained with Matryoshka representation learning. The short version: the model is shaped so that the leading N dimensions of the vector still carry most of the meaning. When you pass output_dimensionality=256, the model computes the full 768-dimensional vector internally and returns the first 256 to you.

My grandfather was a miyadaiku — a traditional carpenter who built shrines. I sometimes think about how he worked: he would shape the wood roughly first and then refine it gradually toward its final form. Matryoshka feels like the same idea wearing a math suit. One embedding, refined down to whichever resolution your storage budget can afford.

The operational consequence is that you do not need to maintain multiple embeddings of the same text for different use cases. The "fast first-pass" recall layer can read the leading 128 dimensions, the "main" search ranker can read the leading 256 dimensions, and any deep similarity check that needs every drop of accuracy can read the full 768. Conceptually it is a single column in the database; physically you decide at query time how much of it to load.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦Recall@10 measurements at 768 / 512 / 256 / 128 dimensions on 80,000 real rows, plus the line I draw on production regressions I can spot by eye
✦Working code for float16 and int8 quantization with per-row scale factors, and the ANN-library pitfall that silently breaks ranking
✦A decision matrix for picking the right dimensionality, and the 60-second CI benchmark gate I run before every embedding change ships
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Gemini Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

◈ API / SDK2026-09-06
Two Ways to Make a Longer Shot in Gemini Omni 1.1, and Two Different Ways They Break
Omni 1.1 extends scenes in 10-second steps up to 40 seconds cumulative, and interpolates between a pinned first and last frame. Which one you use is decided before your first generation, not after. Here is the planner I run first and the drift check I run last.
◈ API / SDK2026-09-05
Gemini 3.8 Flash Costs the Same Per Token and Can Still Raise Your Bill
Gemini 3.8 Flash carries the same per-token price as 3.7 Flash, but it is designed to work harder, so output tokens can grow and your bill with them. Here is what to measure before you switch, and how to price it across the January boundary.
◈ API / SDK2026-09-04
Screen Loop Seam Clicks With Numbers Before You Hand the Audio to Gemini
An ambient loop that clicks only at the wrap point. Here is the numeric prescreen I run before sending anything to audio understanding, why an absolute threshold fails, and how AAC encoding quietly rebuilt the seam I had just repaired.