Guide

How to Migrate from OpenAI to Gemini Embeddings

Step-by-step guide to switching your vector database from OpenAI embeddings to Google Gemini — without re-embedding, without downtime.

Updated March 2026

Moving from OpenAI to Gemini embeddings? This guide walks through every step — from testing compatibility to migrating your production vector database. No re-embedding required.

Prerequisites

  • A Schift account (sign up free)
  • Python 3.9+
  • Existing vectors embedded with an OpenAI model
pip install schift

Step 1: Connect Schift

from schift import Schift

s = Schift(api_key="sk-...")  # Get your key at schift.io/app

Step 2: Benchmark Before Migrating

Always test migration quality before committing. Schift runs your actual queries against projected vectors and reports retrieval recovery:

# Run a benchmark with your data
report = s.bench.run(
    source="openai/text-embedding-3-small",
    target="google/gemini-embedding-2",
    data="your_test_dataset"
)

print(report)
# ┌─────────────────────────────────────────┐
# │ Source: openai/text-embedding-3-small   │
# │ Target: google/gemini-embedding-2       │
# │                                         │
# │ R@1:   97.2%                            │
# │ R@10:  99.7%                            │
# │ nDCG:  98.4%                            │
# │                                         │
# │ Verdict: SAFE                           │
# └─────────────────────────────────────────┘

If recovery is above 95%, migration is safe. Most OpenAI → Gemini migrations achieve 99%+ recovery.

Step 3: Migrate Your Vector Database

# One command to migrate all vectors
s.upgrade(
    db="my_pgvector",           # Your vector DB
    to="google/gemini-embedding-2"  # Target model
)

# → Migrating 1,247,832 vectors...
# → Projection applied in 2.3s
# → Verification: 99.7% recovery
# → Done. New queries will use Gemini.

Step 4: Switch New Embeddings to Gemini

# Before: OpenAI
vec = s.embed("search query", model="openai/text-embedding-3-small")

# After: Gemini (same API, just change the model string)
vec = s.embed("search query", model="google/gemini-embedding-2")

That's it. Your existing vectors were projected, and new embeddings use Gemini directly. Same API format, same response structure.

Step 5: Monitor Quality

Set up drift monitoring to continuously verify that retrieval quality stays high after migration:

# Optional: continuous monitoring
monitor = s.drift.create(
    name="openai-to-gemini-migration",
    source="openai/text-embedding-3-small",
    target="google/gemini-embedding-2",
    cadence="daily",
    min_recovery=95.0
)
# → Alerts if recovery drops below 95%

What About Rollback?

Schift keeps projection matrices bidirectional. If you need to go back:

# Rollback to OpenAI (if needed)
s.upgrade(
    db="my_pgvector",
    to="openai/text-embedding-3-small"
)
# → Reverse projection applied

FAQ

Do I need access to the original text?

No. Schift projects the vectors mathematically — no raw text involved. This is critical for teams that don't store original documents.

How long does migration take?

Vector projection runs at <1ms per vector. A million vectors take about 2-3 seconds. There's no API call to the embedding provider — it's pure linear algebra.

Is there downtime?

Zero downtime. Existing vectors are projected in-place, and new queries start using the target model immediately.

What if my vectors are in Pinecone / Weaviate / Qdrant?

Schift supports all major vector databases. The db parameter accepts connection strings for Pinecone, Weaviate, Qdrant, pgvector, Milvus, and ChromaDB.

How much does this cost?

Migration is free. You only pay for new embeddings at provider cost + 5%. Since Gemini embeddings are free under rate limits, your effective cost could be $0.

Ready to migrate?

Test your migration quality in 60 seconds. No credit card required.