DEV Community

Alex Spinov
Alex Spinov

Posted on

Deno KV Has a Free API: Built-In Key-Value Database with Zero Configuration

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"]);
Enter fullscreen mode Exit fullscreen mode

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"] });
Enter fullscreen mode Exit fullscreen mode

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");
}
Enter fullscreen mode Exit fullscreen mode

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);
  }
});
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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");
});
Enter fullscreen mode Exit fullscreen mode

Deploy to Deno Deploy

deployctl deploy --project=my-app main.ts
Enter fullscreen mode Exit fullscreen mode

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)