Skip to content

Migration from gemini-embedding-001 Fresh 🌱

Migrate from gemini-embedding-001 to Gemini Embedding 2 with zero downtime using parallel systems.

Migration Architecture

Migration Timeline

Key Differences: v1 vs v2

Featuregemini-embedding-001Gemini Embedding 2
Model IDgemini-embedding-001gemini-embedding-2-preview
ModalitiesText onlyText, Image, Video, Audio, PDF
Default dimensions7683072
Dimension range1-768128-3072
Languages100+100+
Pricing (text)$0.15/1M tokens$0.20/1M tokens
Pricing (batch)$0.075/1M tokens$0.10/1M tokens
MRL supportYesYes
Interleaved inputNoYes

Incompatible Embedding Spaces

Embeddings from gemini-embedding-001 and gemini-embedding-2-preview are NOT compatible. You cannot compare vectors across models. All data must be re-embedded.

Implementation

Step 1: Audit Current System

python
# Inventory your current embedding setup
audit = {
    'model': 'gemini-embedding-001',
    'dimensions': 768,          # Check your current setting
    'total_documents': 0,       # Count your indexed docs
    'vector_db': 'chromadb',    # Your vector database
    'task_types_used': [],      # Which task types you use
    'collections': [],          # List of collections
}

# Count documents in your vector DB
import chromadb
chroma = chromadb.PersistentClient(path='./vectordb')
for collection_name in chroma.list_collections():
    col = chroma.get_collection(collection_name.name)
    count = col.count()
    audit['total_documents'] += count
    audit['collections'].append({
        'name': collection_name.name,
        'count': count
    })

print(f"Total documents to re-embed: {audit['total_documents']}")

Step 2: Update Model ID and Dimensions

python
# Old code
OLD_MODEL = 'gemini-embedding-001'
OLD_DIMENSIONS = 768

# New code
NEW_MODEL = 'gemini-embedding-2-preview'
NEW_DIMENSIONS = 768  # Keep same for easy comparison, or upgrade to 1536/3072

Step 3: Create Parallel Collection

python
import chromadb

chroma = chromadb.PersistentClient(path='./vectordb')

# Keep old collection
old_collection = chroma.get_collection('documents_v1')

# Create new collection for v2 embeddings
new_collection = chroma.get_or_create_collection(
    name='documents_v2',
    metadata={'hnsw:space': 'cosine'}
)

Step 4: Re-embed All Data

python
from google import genai
from google.genai import types
import time

client = genai.Client()

def re_embed_collection(old_col, new_col, batch_size=100):
    """Re-embed all documents from old collection to new collection."""
    total = old_col.count()
    processed = 0
    offset = 0

    while offset < total:
        # Get batch from old collection
        batch = old_col.get(
            limit=batch_size,
            offset=offset,
            include=['documents', 'metadatas']
        )

        if not batch['ids']:
            break

        # Re-embed with new model
        for i, (doc_id, doc_text) in enumerate(zip(batch['ids'], batch['documents'])):
            try:
                result = client.models.embed_content(
                    model='gemini-embedding-2-preview',
                    contents=doc_text,
                    config=types.EmbedContentConfig(
                        task_type='RETRIEVAL_DOCUMENT',
                        output_dimensionality=768
                    )
                )

                new_col.add(
                    ids=[doc_id],
                    embeddings=[result.embeddings[0].values],
                    documents=[doc_text],
                    metadatas=[batch['metadatas'][i]] if batch['metadatas'] else None
                )

                processed += 1
                if processed % 100 == 0:
                    print(f"  Re-embedded {processed}/{total}")

            except Exception as e:
                print(f"  Error on {doc_id}: {e}")
                time.sleep(1)  # Rate limit backoff

        offset += batch_size

    print(f"Migration complete: {processed}/{total} documents")

re_embed_collection(old_collection, new_collection)

Step 5: Quality Comparison

python
import numpy as np

def compare_search_quality(queries, old_col, new_col, top_k=10):
    """Compare search results between old and new collections."""
    for query in queries:
        # Old model embedding
        old_result = client.models.embed_content(
            model='gemini-embedding-001',
            contents=query,
            config=types.EmbedContentConfig(task_type='RETRIEVAL_QUERY')
        )
        old_hits = old_col.query(
            query_embeddings=[old_result.embeddings[0].values],
            n_results=top_k
        )

        # New model embedding
        new_result = client.models.embed_content(
            model='gemini-embedding-2-preview',
            contents=query,
            config=types.EmbedContentConfig(
                task_type='RETRIEVAL_QUERY',
                output_dimensionality=768
            )
        )
        new_hits = new_col.query(
            query_embeddings=[new_result.embeddings[0].values],
            n_results=top_k
        )

        # Compare overlap
        old_ids = set(old_hits['ids'][0])
        new_ids = set(new_hits['ids'][0])
        overlap = old_ids & new_ids

        print(f"\nQuery: {query[:60]}...")
        print(f"  Overlap: {len(overlap)}/{top_k} results in common")
        print(f"  Old top result: {old_hits['ids'][0][0]}")
        print(f"  New top result: {new_hits['ids'][0][0]}")

# Test with representative queries
test_queries = [
    'How to deploy a machine learning model',
    'Best practices for data security',
    'Revenue growth strategies for Q4',
]
compare_search_quality(test_queries, old_collection, new_collection)

Step 6: Switch Traffic

python
# Feature flag approach
USE_V2 = True  # Flip this to switch

def search(query, top_k=10):
    model = 'gemini-embedding-2-preview' if USE_V2 else 'gemini-embedding-001'
    collection = new_collection if USE_V2 else old_collection

    config_kwargs = {'task_type': 'RETRIEVAL_QUERY'}
    if USE_V2:
        config_kwargs['output_dimensionality'] = 768

    result = client.models.embed_content(
        model=model,
        contents=query,
        config=types.EmbedContentConfig(**config_kwargs)
    )

    return collection.query(
        query_embeddings=[result.embeddings[0].values],
        n_results=top_k
    )

Migration Checklist

  • [ ] Current system audited (document count, dimensions, task types)
  • [ ] SDK updated to latest google-genai
  • [ ] New model ID configured (gemini-embedding-2-preview)
  • [ ] New vector collection created
  • [ ] All documents re-embedded with new model
  • [ ] Quality comparison completed with test queries
  • [ ] Parallel system running (both v1 and v2)
  • [ ] Traffic switched to v2
  • [ ] Monitoring in place for quality metrics
  • [ ] Old collection decommissioned after validation period

Troubleshooting

IssueSolution
Dimension mismatch errorsEnsure new collection uses the same dimensions as your v2 embeddings
Rate limiting during re-embedAdd exponential backoff; use batch API for 50% savings
Search quality regressionCompare task types; try higher dimensions (1536, 3072)
Cost increaseText went from $0.15 to $0.20/1M; use batch API at $0.10/1M
Old/new embedding mixedNEVER mix; use separate collections and model IDs

See Also

Built with VitePress. Not affiliated with Google.