# Vercel KV alternatives: own your Redis in 2026

> Vercel KV was first-party Redis built on Upstash, and it was sunset into Upstash Redis on the Vercel Marketplace. If you want a Redis you own at flat pricing, here is how to move to managed Valkey with the rediss:// string you already have.

Published: 2026-06-23
Canonical: https://layerbase.com/blog/vercel-kv-alternatives

Short version: Vercel KV is gone as a product. Vercel moved every existing store to Upstash Redis in December 2024, so what you hold today is a metered Upstash Redis database reachable by an ordinary `rediss://` connection string. That makes leaving it a data copy plus one client swap: paste the string into a migration wizard (or run a `--scan` with `DUMP`/`RESTORE`), then replace the deprecated `@vercel/kv` package with a standard Redis driver. If you want a Redis you own at a flat price rather than a per-request meter, managed Valkey is the closest landing spot.

Vercel KV was Vercel's first-party key/value store: Redis, with Upstash running underneath and a `@vercel/kv` client that worked nicely from the edge. It is not a product you can buy anymore. Vercel's [Redis docs](https://vercel.com/docs/redis) say "Vercel KV is no longer available" and that existing stores were automatically moved to Upstash Redis in December 2024, with new projects pointed at a Redis integration from the Marketplace. So if you still think of your store as Vercel KV, what you actually hold is a metered Upstash Redis database. That makes it a good moment to ask a different question: do you want to keep renting Redis through a per-request meter, or own an instance at a flat price?

If the answer is "own it," [Valkey on Layerbase Cloud](https://cloud.layerbase.com/create?engine=valkey) is a managed, Redis-compatible instance with flat per-instance pricing. Because the store was always Redis, your data is portable with a single `rediss://` connection string, and the only code change is swapping the deprecated `@vercel/kv` client for a standard Redis driver.

> **Just want it done?** Start at [layerbase.com/migrate/vercel-kv](https://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. For the step-by-step version, see [Migrating from Vercel KV to Layerbase](/blog/migrating-from-vercel-kv-to-layerbase).

## Contents

- [What Vercel KV Actually Was](#what-vercel-kv-actually-was)
- [Where the Data Can Go](#where-the-data-can-go)
- [Set Up Valkey Locally with the Layerbase CLI](#set-up-valkey-locally-with-the-layerbase-cli)
- [Copy Your Data](#copy-your-data)
- [Swap the Client](#swap-the-client)
- [What to Test](#what-to-test)
- [The Managed Path: Layerbase Cloud](#the-managed-path-layerbase-cloud)
- [FAQ](#faq)

## What Vercel KV Actually Was

KV was Redis. Vercel exposed it two ways: a `KV_URL` (a standard `rediss://` connection string) and a REST API (`KV_REST_API_URL` + `KV_REST_API_TOKEN`) that the `@vercel/kv` package used for edge runtimes. That was the same shape as Upstash, because it was Upstash, and after the December 2024 move it is Upstash without the Vercel wrapper.

Which of those variables your project still carries depends on when it was provisioned: older ones often keep the `KV_*` set, 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 and take whichever variable holds a `rediss://` string.

So moving off it is the same as moving any Redis:

- Your keys, types, and TTLs copy over with the `rediss://` URL.
- The `@vercel/kv` client (REST) becomes a standard Redis client (`ioredis`) on a Node runtime, or stays HTTP-shaped if you genuinely need edge access.
- Flat per-instance pricing replaces the per-request meter.

## Where the Data Can Go

Because the store was always Redis, every option below reads the same `rediss://` string. The choice is really about who operates the instance and how it bills.

| Option | What it is | When to pick it |
| --- | --- | --- |
| [Managed Valkey on Layerbase Cloud](https://cloud.layerbase.com/create?engine=valkey) | A Redis-compatible instance with TLS, backups and flat per-instance pricing | You want a Redis you own rather than a per-request meter |
| Upstash Redis, unchanged | What your Vercel KV store already became in December 2024 | The meter suits your traffic and you would rather not move |
| [Local Valkey via the Layerbase CLI](https://layerbase.com/docs/cli) | The same engine on your machine, one command, no Docker | Copying the keyspace and running your suite before you cut over |
| [Layerbase Desktop](https://layerbase.com/desktop/download) | The same local instances behind a GUI on macOS | You want the local instance without the terminal |
| A Node route in front of Valkey | A small API route your edge functions call over HTTP | You genuinely need key access from an edge runtime |

## Set Up Valkey Locally with the Layerbase CLI

Stand up Valkey locally so you can copy into it and verify first. [The Layerbase CLI](https://layerbase.com/docs/cli) (formerly SpinDB) runs it with one CLI, no Docker. ([What is the Layerbase CLI?](https://layerbase.com/docs/cli))

```bash
npm i -g layerbase    # npm
pnpm add -g layerbase # pnpm

lbase create vercel-kv-migration -e valkey --start
lbase url vercel-kv-migration
```

```text
redis://127.0.0.1:6380
```

The `redis://` scheme is correct; Valkey speaks the same protocol as Redis.

## Copy Your Data

### The managed wizard (paste your connection string)

On [Layerbase Cloud](https://cloud.layerbase.com/create?engine=valkey), choose **Migrating from another platform**, pick the connection-string option, and paste the `rediss://` value. As of August 2026 you find it by opening your Vercel project's **Storage** tab, selecting the Redis resource, and following the link into the Upstash console, where the database page lists the TLS endpoint; a legacy `KV_URL` still sitting in your environment works just as well. It reads the keyspace once with a non-blocking `SCAN` and copies every key, type, and TTL into a fresh managed Valkey. No REST tokens, no manual export.

### By hand with a scan + dump

That connection string is a normal `rediss://` endpoint, so `redis-cli` works directly. Use `--scan` (never `KEYS *`) and `DUMP`/`RESTORE` to preserve types and TTLs:

```bash
SRC='rediss://default:<token>@<name>.upstash.io:6379'
DST='redis://127.0.0.1:6380'        # or your Layerbase Valkey rediss:// URL

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
```

For large keyspaces, the managed wizard batches and resumes; the loop is fine for typical cache/session data.

## Swap the Client

The one code change is the client. `@vercel/kv` is the Upstash REST client with a Vercel wrapper, and npm now marks it deprecated.

**Before (`@vercel/kv`):**

```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!) // your Valkey rediss:// URL
await redis.set('session:42', JSON.stringify(value), 'EX', 3600)
const v = JSON.parse((await redis.get('session:42')) ?? 'null')
```

Two small differences: `ioredis` stores strings, so serialize objects yourself (`@vercel/kv` auto-JSON-encoded), and the expiry option is `'EX', seconds` rather than `{ ex: seconds }`. If you deploy to a Node runtime, this is the simpler path. If you need HTTP from an edge function, keep that path behind a small Node API route that talks to Valkey over TCP.

## What to Test

- **Run your suite against the local Valkey** before cutting over.
- **Check JSON handling.** Since `@vercel/kv` auto-encoded values, audit every `get`/`set` to add explicit `JSON.stringify`/`JSON.parse` (or use a small wrapper) so you don't store `[object Object]`.
- **Confirm TTLs carried across** on sessions and rate-limit keys (`PTTL` a few).
- **Use one client per instance**, not one per request, especially in serverless.

## The Managed Path: Layerbase Cloud

Worth doing the copy once by hand to see the shape. When you want managed Valkey you own, [Layerbase Cloud](https://cloud.layerbase.com/create?engine=valkey) provisions it with TLS, backups, and flat per-instance pricing, and the **Migrating from another platform** flow copies your data from the `rediss://` string you already have. Off the per-request meter, onto an instance that's yours.

## FAQ

### Is Vercel KV still available?

No. Vercel's Redis docs say "Vercel KV is no longer available," and new projects are pointed at a Redis integration from the Vercel Marketplace instead. You cannot provision a new Vercel KV store, and the `@vercel/kv` package is marked deprecated on npm.

### What happened to my existing Vercel KV database?

It was automatically moved to Upstash Redis in December 2024. Nothing was deleted and nothing broke, but the thing you own is now a metered Upstash Redis database without the Vercel wrapper on top. That is why the question worth asking is not "how do I keep Vercel KV" but "do I want to keep renting Redis through a per-request meter."

### Where do I find my connection string now?

Open your Vercel project's **Storage** tab, select the Redis resource, and follow the link into the Upstash console, where the database page lists the TLS endpoint. If a legacy `KV_URL` is still sitting in your environment variables, that works just as well. Which variables your project carries depends on when it was provisioned, so read the actual environment list and take whichever one holds a `rediss://` string.

### Do I have to rewrite my code to move off Vercel KV?

Only the client, and only in two small places. `@vercel/kv` auto-encoded values as JSON, so with `ioredis` you serialize objects yourself, and the expiry option becomes `'EX', seconds` instead of `{ ex: seconds }`. Your keys, types and TTLs copy across untouched, and everything else in your application stays as it is.

### Is Valkey compatible with Redis clients?

Yes. Valkey speaks the same protocol as Redis, which is why a local Valkey instance hands you a `redis://` URL and why `ioredis` connects to it with no special handling. Anything that talks to Redis talks to Valkey.

### How does Upstash pricing compare to a flat-priced instance?

Upstash bills per command rather than per instance. The free plan includes 500K commands a month with 256 MB of storage, pay-as-you-go bills $0.20 per 100K commands with storage at $0.25 per GB beyond the first, and the fixed-size plans start at $10 a month for 250 MB. A flat per-instance price inverts that: you pay for the database to exist and your command volume stops being a line item, which is the trade if your traffic is chatty or spiky.

Upstash Redis rates verified 2026-08-25 from [upstash.com/pricing/redis](https://upstash.com/pricing/redis).

## Wrapping Up

Vercel KV was Redis, so leaving it is a data copy plus a one-client swap: paste the `rediss://` string into the wizard (or run a `--scan` + `DUMP`/`RESTORE` loop), then replace `@vercel/kv` with `ioredis` and handle JSON encoding yourself. The payoff is a flat-priced Redis you control.

Manage your local Valkey instance with the Layerbase CLI:

```bash
lbase stop vercel-kv-migration    # Stop the server
lbase start vercel-kv-migration   # Start it again
lbase url vercel-kv-migration     # Print the connection URL
lbase list                        # See all your instances
```

The Layerbase CLI handles [20+ database engines](https://layerbase.com/docs/cli), so Valkey can sit next to your Postgres or Meilisearch while you verify the move. [Layerbase Desktop](https://layerbase.com/desktop/download) wraps it in a GUI on macOS. Coming from Upstash directly? See [Migrating from Upstash to Layerbase](/blog/migrating-from-upstash-to-layerbase).
