Connecting to a KV store
Every KV store has two URLs. Which one you use decides everything about how you connect.
| URL | Looks like | Reachable from |
|---|---|---|
Internal (KV_URL) | redis://default:…@my-cache-4e8aad-redis.org-123.svc.us.pandastack.app:6379 | Your PandaStack apps, same region |
| Public | rediss://default:…@my-cache-4e8aad.db.pandastack.app:6379 | Anywhere (public stores only) |
If your code runs on PandaStack, use the internal URL. It’s plain TCP on the private network — no TLS handshake, no proxy hop, and none of the caveats below apply. It’s injected as KV_URL when you link the store to a project, so there’s usually nothing to configure.
The rest of this page is about the public URL.
Node.js
Section titled “Node.js”Both redis (node-redis v4+) and ioredis parse rediss:// and send SNI automatically. Nothing extra to configure.
npm install redisimport { createClient } from "redis";
const kv = createClient({ url: process.env.KV_URL });kv.on("error", (err) => console.error("KV error", err));await kv.connect();
await kv.set("session:abc", JSON.stringify({ userId: 42 }), { EX: 3600 });const session = JSON.parse(await kv.get("session:abc"));With ioredis:
import Redis from "ioredis";const kv = new Redis(process.env.KV_URL);
await kv.set("hits", 0);await kv.incr("hits");Python
Section titled “Python”pip install redisimport redis
kv = redis.from_url(os.environ["KV_URL"], decode_responses=True)
kv.set("session:abc", "…", ex=3600)print(kv.get("session:abc"))redis.ParseURL reads the rediss:// scheme and sets TLSConfig.ServerName for you, which is what makes SNI work.
import "github.com/redis/go-redis/v9"
opt, err := redis.ParseURL(os.Getenv("KV_URL"))if err != nil { log.Fatal(err) }kv := redis.NewClient(opt)
kv.Set(ctx, "session:abc", "…", time.Hour)val, err := kv.Get(ctx, "session:abc").Result()require "redis"kv = Redis.new(url: ENV["KV_URL"])kv.set("session:abc", "…", ex: 3600)Testing from a terminal
Section titled “Testing from a terminal”Since redis-cli won’t work against the public URL, use Python — this sends SNI properly and is a quick way to confirm a store is alive:
python3 - <<'EOF'import redis, oskv = redis.from_url(os.environ["KV_PUBLIC_URL"], decode_responses=True)print("PING :", kv.ping())print("SET :", kv.set("smoke", "ok"))print("GET :", kv.get("smoke"))EOFGetting the password
Section titled “Getting the password”Connection URLs are shown masked everywhere by default — the password is replaced with ********. To see the real one, use Reveal password on the store’s page in the dashboard, or:
curl https://api.pandastack.io/v1/kv/my-cache-4e8aad/password \ -H "Authorization: Bearer $PANDASTACK_TOKEN"This endpoint requires the admin or owner role. If you’re linking the store to a project you don’t need the password at all — KV_URL arrives with the real credentials already in it.
Troubleshooting
Section titled “Troubleshooting”| What you see | What it means |
|---|---|
I/O error, Server closed the connection, connection closes immediately after TLS | Your client isn’t sending SNI. Almost always this is redis-cli — switch to a library above. |
WRONGPASS invalid username-password pair | The password is wrong. Reveal it again; if you rotated or recreated the store, the old one is dead. |
NOAUTH Authentication required | You connected but sent no AUTH. Pass the full URL (including the password) to your client rather than just the host. |
no running KV store found | The store isn’t running yet (provisioning takes ~30s), or it was deleted, or it’s private and you’re using a public hostname. |
| Timeout with no response | Check the store is running in the dashboard. If it’s a free store, confirm it hasn’t been suspended — see lifecycle. |