Migrating from Upstash to Layerbase
Upstash made serverless Redis easy: pay per request, scale to zero, connect over HTTP from the edge. That model is perfect when you're at zero, and it gets unpredictable as you grow, because the meter runs on every command. A chatty cache or a rate limiter doing millions of ops a day turns into a bill you can't forecast, and you don't own the instance, you rent commands against it.
If you'd rather pay a flat per-instance price for Redis-compatible storage you can actually run, Valkey on Layerbase Cloud is the move. Valkey is the BSD-licensed Redis fork, wire-compatible with everything you already use. Your data copies over with one API key, and the only code change is swapping Upstash's REST client for a standard Redis driver (and even that only matters on the edge).
Contents
- What Actually Changes
- Set Up Valkey Locally with SpinDB
- Copy Your Data
- Swap the Client
- What to Test
- The Managed Path: Layerbase Cloud
What Actually Changes
Upstash speaks the Redis protocol, so your data structures, commands, and most of your code are unchanged. Two things differ:
- The pricing model. Upstash meters per request (with a fixed-plan option on top). Layerbase Valkey is flat per instance: the bill is the same whether you do a thousand ops a month or a billion. For anything past hobby traffic, this is the whole point of moving.
- The client. Upstash pushes
@upstash/redis, a REST/HTTP client built for edge runtimes that can't open raw TCP sockets. A standard Valkey server speaks the Redis wire protocol over TCP, so on a normal Node/Python/Go server you use a normal client (ioredis,redis,redis-py). If you specifically need HTTP access from an edge function, see the client section below.
What does not change: your keys, values, data types, TTLs, pub/sub, Lua scripts, and the commands you call. It's Redis on both ends.
Set Up Valkey Locally with SpinDB
Stand up Valkey locally first so you can copy your data into it and verify before touching production. SpinDB runs it with one CLI, no Docker. (What is SpinDB?)
Install SpinDB:
npm i -g spindb # npm
pnpm add -g spindb # pnpmCreate a Valkey instance:
spindb create upstash-migration -e valkey --startCheck the URL (it uses the redis:// scheme because Valkey speaks the same protocol):
spindb url upstash-migrationredis://127.0.0.1:6380Connect with redis-cli (or valkey-cli):
spindb connect upstash-migrationCopy Your Data
The managed wizard (one API key)
On Layerbase Cloud, the create flow does the copy. Choose Migrating from another platform, pick Upstash, and paste your Upstash account email and a management API key (Upstash console, then Account, then Management API). It lists your Redis databases; for the one you pick it reads the whole keyspace with a non-blocking SCAN and copies every key, type, and TTL into a fresh managed Valkey. No redis-cli gymnastics, no blocking KEYS *.
By hand with a scan + dump
If you'd rather do it yourself (or copy into the local SpinDB instance above), Upstash gives you a rediss:// endpoint, so a plain redis-cli works. Use --scan (not KEYS *) so you don't block the server, and copy each key with DUMP/RESTORE to preserve type and TTL:
# From your Upstash rediss:// URL, copy every key into the local Valkey.
SRC='rediss://default:<password>@<your-db>.upstash.io:6379'
DST='redis://127.0.0.1:6380'
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"
doneFor large keyspaces, prefer the managed wizard (it batches and resumes); the loop above is fine for small-to-medium caches. Upstash's serverless tier blocks BGSAVE/--rdb, which is why this is a per-key copy rather than an RDB file.
Swap the Client
If your app already uses a normal Redis client, you only change the connection string. The change that matters is for code using Upstash's REST client.
Before (Upstash REST client):
import { Redis } from '@upstash/redis'
const redis = Redis.fromEnv() // UPSTASH_REDIS_REST_URL + token
await redis.set('session:42', value, { ex: 3600 })
const v = await redis.get('session:42')After (standard Redis client over TCP):
import Redis from 'ioredis'
const redis = new Redis(process.env.REDIS_URL!) // rediss://...cloud.layerbase.dev:port
await redis.set('session:42', value, 'EX', 3600)
const v = await redis.get('session:42')Same commands, slightly different option syntax. If you use the @vercel/kv or @auth/upstash-redis-adapter packages, they accept any Redis-compatible client, so point them at ioredis.
A note on edge runtimes: @upstash/redis exists because some edge platforms can't open TCP sockets. If you deploy to a Node runtime (most apps), ioredis is simpler. If you genuinely 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. Commands behave identically; the protocol hasn't changed.
- Check TTL-sensitive logic. Confirm sessions, rate-limit windows, and cache expiries carried their TTLs across (the wizard and the
DUMP/RESTOREloop both preserve them; verify a few keys withPTTL). - Check connection handling. The REST client was stateless; with
ioredisuse a single client/pool per instance rather than constructing one per request, especially in serverless. - If you used Upstash for a queue, note that Layerbase's managed queue add-on, vqueue, runs on Valkey; a plain key/value copy brings your data, and the queue is a separate product.
The Managed Path: Layerbase Cloud
The hands-on version is worth doing once. When you want managed Valkey you don't run yourself, Layerbase Cloud provisions it in seconds with TLS, backups, and flat per-instance pricing, and the Migrating from another platform wizard does the copy from your Upstash API key. Off the per-command meter, onto an instance you own.
Wrapping Up
Leaving Upstash is mostly a data copy plus a one-line client swap. It's Redis on both ends, so your commands and data structures port directly; the wins are predictable pricing and, on a Node runtime, a simpler standard client. Copy your keyspace with one API key through the wizard, or a --scan + DUMP/RESTORE loop by hand.
Manage your local Valkey instance with SpinDB:
spindb stop upstash-migration # Stop the server
spindb start upstash-migration # Start it again
spindb url upstash-migration # Print the connection URL
spindb list # See all your instancesSpinDB handles 20+ database engines, so Valkey can sit next to your Postgres, Meilisearch, or Qdrant while you verify the move. Layerbase Desktop wraps it in a GUI on macOS. For the Redis-to-Valkey background, see Redis vs Valkey and Migrating from Redis to Valkey.