Skip to content

Migrating from Vercel KV to Layerbase

7 min readVercel KVRedisValkeyMigrationDatabases

Vercel KV was Redis, with Upstash running it under the hood. It is not a product you can buy anymore: Vercel's Redis docs say "Vercel KV is no longer available. If you had an existing Vercel KV store, we automatically moved it to Upstash Redis in December 2024." So whatever your project still calls it, what you are migrating today is an Upstash Redis database reached through the Vercel Marketplace integration. The useful consequence for a migration is that there is nothing exotic to move: it is a keyspace, it speaks the Redis wire protocol, and one rediss:// connection string is enough to copy it. This post is the move, start to finish. If you are still weighing whether to leave, Vercel KV alternatives: own your Redis makes that case; this post assumes you have decided and walks the migration.

Just want it done? Start at layerbase.com/migrate/vercel-kv. You sign in, the wizard opens with Vercel KV already selected, and it reads your store once with a non-blocking scan and copies every key, type, and TTL into managed Redis (or Valkey): read-once, nothing written back to your KV store. The rest of this post is that same migration explained step by step, plus the manual path.

Contents

What moves and what does not

Your former KV store holds a Redis keyspace, and the whole keyspace moves.

Moves automatically:

  • Every key, with its type preserved: strings, hashes, lists, sets, sorted sets, and streams.
  • Every TTL. Expiring keys keep expiring on the same schedule after the move, so sessions, rate-limit windows, and cache entries do not suddenly become immortal.

Does not move:

  • The Vercel dashboard wiring. The store is an Upstash integration on your Vercel project; migrating the data does not touch your deployment. You swap an environment variable when you are ready to cut over (see the client section).
  • Nothing else, because there is nothing else. Unlike a database migration with schemas and auth, a KV move is just the keyspace. That is the whole appeal.

Find your connection string

This is the only credential you need, and it is already in your Vercel account.

In the Vercel dashboard, open your project and go to the Storage tab, then select the Redis resource. It is listed as an Upstash integration rather than a native KV product, because that is what the December 2024 move turned it into. From that page Vercel links out to the provider's own console (its storage docs list "Access provider dashboard" among the things you manage there), and the Upstash database page is where the TLS endpoint lives: Upstash shows the Endpoint, Port, and Token, which compose into a rediss:// string like:

text
rediss://default:<token>@<name>.upstash.io:6379

That single string is enough to read the whole store. There is no separate API key and no account email to dig up, because it is a standard Redis connection string.

Vercel's labels have moved more than once since the sunset, so treat the click path as the shape of it rather than a script. As of August 2026 the store sits under Storage and the connection details live on the Upstash side.

Your environment variables may already hold the string. Projects provisioned back when this was Vercel KV often still carry KV_URL next to the KV_REST_API_* set, and newer ones get the Upstash pair instead. Neither vendor publishes a definitive list of what the integration injects today, so read your project's actual environment list rather than trusting any post, including this one. What you need is whichever variable holds a rediss:// string: the REST URL and token are HTTP credentials and will not copy a keyspace.

The migration, step by step

The fastest path is the built-in migration flow. It handles the scan and the copy for you.

Step 1: Start the migration

In the Layerbase dashboard, click New database and choose Migrating from another platform, then pick Vercel KV. (You can also open the Migrate tab on an existing blank database.)

Paste the rediss:// string you copied above. Unlike the API-key sources, there is no "list your databases" step here: the connection string points at exactly one store, so the wizard reads it directly.

Step 2: Let it copy

Layerbase provisions a Redis (or Valkey, your choice) instance and reads your store with a non-blocking SCAN, never a blocking KEYS *, so your live app keeps serving reads and writes while the copy runs. Every key is recreated with its type and remaining TTL. For a typical cache or session store this is quick; a very large keyspace takes proportionally longer.

Step 3: Grab the connection string

Open the new database in the dashboard and copy its connection string. It is a standard rediss:// URL:

text
rediss://layerbase:<password>@your-host.cloud.layerbase.dev:port

Any standard Redis client takes it as-is.

Redis or Valkey, and the queue question

The wizard lets you land on either Redis or Valkey. They are wire-compatible, so your commands and data structures are identical on both, and the copy is the same either way. Two things help you choose:

  • If you just want a Redis you own at flat pricing, either works. Valkey is the BSD-licensed Redis fork; pick it if you would rather not depend on the Redis license, or Redis if you want the exact upstream.
  • If your KV store backs a message queue, pick Valkey. Layerbase's managed queue add-on, vqueue, runs on Valkey. A plain key/value copy brings your data across to either target, but if you want the queue product on the other side, Valkey is where it lives.

Whichever you pick, the pricing is flat per instance rather than per request, which is the point of moving off a metered Upstash-backed store: the bill is the same at a thousand ops a month or a billion.

Swap the @vercel/kv client

If your code already talks to KV through a standard Redis client, this is one environment variable: point REDIS_URL (or whatever you call it) at the new connection string and deploy.

The change that matters is for code using the @vercel/kv client, a REST/HTTP wrapper built for edge runtimes that npm now marks deprecated.

Before (Vercel KV client):

ts
import { kv } from '@vercel/kv'

await kv.set('session:42', value, { ex: 3600 })
const v = await kv.get('session:42')

After (standard Redis client over TCP):

ts
import Redis from 'ioredis'

const redis = new Redis(process.env.REDIS_URL!) // rediss://...cloud.layerbase.dev:port
await redis.set('session:42', JSON.stringify(value), 'EX', 3600)
const v = JSON.parse((await redis.get('session:42')) ?? 'null')

Two notes. @vercel/kv auto-serialized objects to JSON; a raw Redis client stores strings, so serialize on the way in and parse on the way out (or keep a thin wrapper that does it). And @vercel/kv exists because some edge runtimes cannot open raw TCP sockets: if you call KV from an edge function, keep that path behind a small Node API route that talks to the new instance over TCP, and use ioredis there.

The manual path

If you would rather drive the copy yourself, the source is a normal rediss:// endpoint, so redis-cli works. Use --scan (not KEYS *) so you do not block the store, and copy each key with DUMP/RESTORE to preserve type and TTL:

bash
SRC='rediss://default:<token>@<name>.upstash.io:6379'   # from the Upstash side
DST='rediss://layerbase:<password>@your-host.cloud.layerbase.dev:port'

redis-cli -u "$SRC" --scan | while read -r key; do
  ttl=$(redis-cli -u "$SRC" --no-raw PTTL "$key")
  dump=$(redis-cli -u "$SRC" --no-raw DUMP "$key")
  redis-cli -u "$DST" RESTORE "$key" "${ttl/-1/0}" "$dump"
done

The ${ttl/-1/0} turns a "no expiry" PTTL of -1 into the 0 that RESTORE wants for a persistent key. This loop is fine for small-to-medium stores; for a large keyspace prefer the wizard, which batches and resumes.

Rehearse locally first

The Layerbase CLI (formerly SpinDB) runs Valkey locally with no Docker, so you can copy into a local instance and verify before you touch production:

bash
npm i -g layerbase
lbase create kv-test -e valkey --start
# point DST at "$(lbase url kv-test)" in the loop above, then check a few keys:
redis-cli -u "$(lbase url kv-test)" PTTL session:42

Confirm your TTL-sensitive logic (sessions, rate limits, cache expiries) survived, then run the real copy into Layerbase Cloud.

Leaving Vercel KV is a keyspace copy and a one-line client swap, because it was Redis the whole time. Paste the rediss:// string, copy every key and TTL through the wizard or a --scan loop, and land on a Redis or Valkey instance you own at flat pricing. For the decision behind the move, see Vercel KV alternatives; for the same move framed from the Upstash side, which is where your data now lives, see Migrating from Upstash.