You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Completed migration: 3,560 user writes + 596 story writes = 4,156 total
Audit verified 100% data match
Smoke tests passed 8/8
Key Lessons Learned
getExistingDocIds was the hidden quota killer — reading every doc ID for dedup cost 19,400+ reads per run, making even dry-runs expensive
count() aggregation bills 1 read per 1,000 docs (vs 1 read per doc with .select().get())
batch.set() is idempotent — dedup is unnecessary when overwriting is acceptable
Query optimization is critical — unoptimized getStories() read ALL 19,996 docs per API call; adding .limit(500) + TTL cache made the app viable on the free tier
Retry handlers must cover transient gRPC errors — not just RESOURCE_EXHAUSTED (code 4), but also INTERNAL (code 13) and UNAVAILABLE (code 14)