What is Deno KV?
Deno KV is a built-in key-value database that ships with the Deno runtime. No installation, no configuration, no connection strings. Just Deno.openKv() and you have a globally distributed database.
Free on Deno Deploy: unlimited reads, 1 GB storage.
Quick Start
const kv = await Deno.openKv();
// Set
await kv.set(["users", "user_123"], {
name: "Alice",
email: "alice@example.com",
plan: "pro",
});
// Get
const user = await kv.get(["users", "user_123"]);
console.log(user.value); // {name: "Alice", ...}
// Delete
await kv.delete(["users", "user_123"]);
That's it. No npm install, no database setup.
Hierarchical Keys
// Keys are arrays — naturally hierarchical
await kv.set(["posts", "2026", "03", "my-post"], { title: "Hello", body: "..." });
await kv.set(["posts", "2026", "03", "another"], { title: "World", body: "..." });
// List all March 2026 posts
const posts = kv.list({ prefix: ["posts", "2026", "03"] });
for await (const entry of posts) {
console.log(entry.key, entry.value.title);
}
// List all posts ever
const allPosts = kv.list({ prefix: ["posts"] });
Atomic Operations
// Transfer money atomically
const sender = await kv.get(["accounts", "alice"]);
const receiver = await kv.get(["accounts", "bob"]);
const result = await kv.atomic()
.check(sender) // Ensure no concurrent modification
.check(receiver)
.set(["accounts", "alice"], { balance: sender.value.balance - 100 })
.set(["accounts", "bob"], { balance: receiver.value.balance + 100 })
.commit();
if (!result.ok) {
console.log("Conflict — retry");
}
Queues (Built-In)
// Enqueue a task
await kv.enqueue({
type: "send_email",
to: "user@example.com",
subject: "Welcome!",
});
// Process queue
kv.listenQueue(async (message) => {
if (message.type === "send_email") {
await sendEmail(message.to, message.subject);
}
});
Secondary Indexes
// Store user with email index
async function createUser(user) {
const result = await kv.atomic()
.set(["users", user.id], user)
.set(["users_by_email", user.email], user.id)
.commit();
return result;
}
// Lookup by email
async function getUserByEmail(email) {
const entry = await kv.get(["users_by_email", email]);
if (!entry.value) return null;
const user = await kv.get(["users", entry.value]);
return user.value;
}
HTTP Server with KV
const kv = await Deno.openKv();
Deno.serve(async (req) => {
const url = new URL(req.url);
if (url.pathname === "/api/visits") {
// Atomic counter
const current = await kv.get(["visits"]);
const count = (current.value as number || 0) + 1;
await kv.set(["visits"], count);
return Response.json({ visits: count });
}
if (url.pathname.startsWith("/api/users/")) {
const id = url.pathname.split("/")[3];
const user = await kv.get(["users", id]);
if (!user.value) return new Response("Not found", { status: 404 });
return Response.json(user.value);
}
return new Response("OK");
});
Deploy to Deno Deploy
deployctl deploy --project=my-app main.ts
Your KV database automatically becomes globally distributed — replicated across 35+ regions.
Deno KV vs Redis vs DynamoDB
| Feature | Deno KV | Redis | DynamoDB |
|---|---|---|---|
| Setup | Zero (built-in) | Install/Docker | AWS Console |
| Transactions | Atomic ops | MULTI/EXEC | TransactWriteItems |
| Queues | Built-in | Separate (Bull) | SQS |
| Global replication | Automatic | Manual | Global Tables |
| Free tier | 1 GB | Self-host | 25 GB |
| Latency | <10ms edge | <1ms local | <10ms |
Need edge-first backend or Deno deployment help?
📧 spinov001@gmail.com
🔧 My tools on Apify Store
Redis or Deno KV — which key-value store do you prefer?
Top comments (0)