# How we migrated the database behind every Vercel build

DevFeed: [How we migrated the database behind every Vercel build](<https://devfeed.tech/articles/how-we-migrated-the-database-behind-every-vercel-build-756.md>)

Original publisher: [Read original article](<https://vercel.com/blog/how-we-migrated-the-database-behind-every-vercel-build>)

Author: Andrew Healey

Published: 2026-08-11T22:00:00Z

Content type: article

Language: en

Sources: [Vercel News](<https://devfeed.tech/sources/vercel-news.md>)

Topics: [migration](<https://devfeed.tech/topics/migration.md>), [Redis](<https://devfeed.tech/topics/redis.md>), [Vercel](<https://devfeed.tech/topics/vercel.md>), [Containers](<https://devfeed.tech/topics/containers.md>), [Deployment](<https://devfeed.tech/topics/deployment.md>), [Database](<https://devfeed.tech/topics/database.md>), [Cache](<https://devfeed.tech/topics/cache.md>)

Tags: [cache](<https://devfeed.tech/tags/cache.md>), [containers](<https://devfeed.tech/tags/containers.md>), [database](<https://devfeed.tech/tags/database.md>), [deployment](<https://devfeed.tech/tags/deployment.md>), [latency](<https://devfeed.tech/tags/latency.md>), [migration](<https://devfeed.tech/tags/migration.md>), [production](<https://devfeed.tech/tags/production.md>), [redis](<https://devfeed.tech/tags/redis.md>), [vercel](<https://devfeed.tech/tags/vercel.md>)

## AI overview

Vercel describes migrating the database behind its build warm pool from Redis to DynamoDB. The migration moved important billing mappings and other pool state to durable storage while running live under production traffic, in phased rollouts with feature flags and rollback plans.

## Source excerpt

Every build on Vercel starts in the build warm pool, which is a set of standby containers that let builds begin without waiting for new compute. The pool runs on state that tracks which containers are ready, the tokens each one uses to authenticate, and the mapping that ties every running build back to the deployment that gets billed for it. When we built the pool, we put all of that in Redis, which was fast and made sense at the time. Over the years, though, that state turned into a liability. Tokens and container statuses can be rebuilt if they get lost, but the billing mappings can't, and all of it was sitting in a store that we ran as an ephemeral cache. That state needed to live somewhere durable, which is why we decided to migrate it to DynamoDB. The problem is that the pool never stops. Containers are coming up, polling, picking up work, and expiring around the clock, which meant we couldn't pause the world, copy the data, and restart. The migration had to happen live, under production traffic, in phases, each one behind a flag with a rollback ready if we needed it. Durable state in an ephemeral store Redis was a good home for it at first. It was fast, familiar, and efficient for the access patterns the pool started with. But over time the state became more important than the store holding it. If Redis became unavailable or lost data, the pool could no longer reliably authenticate containers, track which of them were ready, or resolve the work in flight. Lose a token and the pool rebuilds it within about ten minutes. Lose a mapping and the build is never billed, because nothing else records which deployment it belonged to. We wanted it in durable storage and landed on DynamoDB. On-demand scaling fits bursty deployment traffic, TTL is native, and there are no connections to manage at high concurrency. But what it did not promise was Redis's latency. What Redis made cheap Inside Redis, the pool's state looked like this: Tokens lived in a set so we could check m