Skip to main content
Deno KV is in open beta

Deno KV is the fastest, easiest way to add a strongly consistent database to your application. It’s built right into the runtime so you can skip configuration and dive right into coding:

const kv = await Deno.openKv();
Add state with a single line of code — no need to provision a database or copy/paste environmental variables.

Today, we’re excited to announce that Deno KV on Deno Deploy is now in open beta. There’s no longer a waitlist so you can get access to Deno KV by simply signing up for Deno Deploy. For those already using Deno Deploy, your projects are automatically updated with KV access.

You can also watch our 2 minute video announcement summarizing this post.

Alongside our announcement, here are some other exciting updates about Deno KV on Deno Deploy:

Connect to KV from outside of Deno Deploy

To make it easier to explore, import, migrate, and update your KV data on Deno Deploy, you can now connect directly to your KV instance from the command line. Simply set a Deno Deploy personal access token as the local environmental variable DENO_KV_ACCESS_TOKEN and pass your database URL to Deno.openKv():

const kv = await Deno.openKv(

You can find your database ID, URL, and more information on how to connect to your managed KV database from your Deno Deploy project page:

Connecting to your Deno KV locally

Now it’ll be easier to import data into production, handle data migrations, inspecting/modifying/exploring data manually, and hosting Deno apps on a different platform with global Deno KV for storage:

// This script updates the format of the `createdAt` field of all entries under the prefix
// `["items"]` from UNIX millisecond timestamps to ISO date strings.
import { Semaphore } from "";

const kv = await Deno.openKv(
const concurrencyLimit = 20;
const sem = new Semaphore(concurrencyLimit);

for await (
  const { key, value, versionstamp } of kv.list<any>({ prefix: ["items"] })
) {
  if (typeof value?.createdAt === "number") {
    value.createdAt = new Date(value.createdAt).toISOString();
    const release = await sem.acquire();
    (async () => {
      await kv.atomic().check({ key, versionstamp }).set(key, value).commit();

for (let i = 0; i < concurrencyLimit; i++) {
  await sem.acquire();

console.log("Migration completed!");

Learn more about connecting to your global Deno KV from the command line →

Want to use Deno KV on Deno Deploy but with an app hosted on Here’s a quick guide on using Deno KV connect to do so:


We’re excited to announce transparent Deno KV pricing that scales with your needs. Deno KV is billed along three dimensions: storage, read units, and write units.

Storage is the amount of data you store in your Deno KV database over a month, measured in gigabytes. Read and write units are the number of times you read and write data from your Deno KV database, measured in 4 KiB read units and 1 KiB write units respectively. If you perform 3 read transactions of 1 KiB each, you will be billed for 3 read units. If you perform 1 write transaction of 4 KiB, you will be billed for 4 write units.

Write unit usage is additionally multiplied by the number of regions you have enabled for your database. If you have the primary region, and two read replicas enabled, you will be billed for 3 write units for every 1 KiB of writes.

For every user, Deno Deploy’s free tier includes 1 GiB of storage, 15k read units per day and 10k write units per day. Daily usage resets at UTC 00:00.

For those scaling with Deno KV and Deno Deploy, our Pro tier offers:

  • 5 GiB of monthly storage, with $0.75 per additional GiB
  • 45k read units per day, with $1 per additional million reads
  • 30k write units per day, with $2.5 per additional million writes

Here is the complete pricing table for more details:

Free Pro Custom
KV storage 1 GB 5GB (then $0.50/GB) Custom
KV read units/day (4kb) 15,000 45,000 (then $1/M) Custom
KV write units/day (1kb) 10,000 30,000 (then $2.50/M) Custom
Number of DB regions 1 Custom Custom
Select your write region No No Yes
Max monthly usage Free $250 N/A
Does your application or business have unique scaling or global data storage needs? We’d love to learn more.

As a reminder, using Deno KV locally without Deno Deploy will be free.

Learn more about our Deno Deploy and Deno KV pricing plans →

More read regions for lower latency

By default, every Deno KV database comes with a single write region and a single read region. If your users are all over the world, some may experience longer latencies due to the single read region.

Now, you can enable more read regions to expand your database globally for even lower latency:

Screenshot of selecting read regions

Expand your database globally by enabling multiple read regions with a click.

More powerful atomic operations

Atomic operations are a powerful feature of Deno KV that allow you to perform multiple operations in a single transaction. If any of the operations fail, the entire transaction is rolled back, ensuring that your data is always consistent.

Previously, you could only perform up to 10 mutation operations in a single transaction. Many of you told us that this limit was too low, especially when dealing with complex data that require many secondary indexes.

We’ve heard you! The limit has been increased to 1000 mutations per atomic operation, or a total atomic operation size of 800 KiB, whichever is reached first.

OAuth made easy

User authentication is table stakes for any modern web app. To make it as simple as possible to implement auth into your Deno Deploy projects, we’ve built Deno KV OAuth, a high-level OAuth 2.0 wrapper with Deno KV as a backend with a ton of pre-configured common OAuth 2.0 providers, such as GitHub, Google, Facebook, Slack, Discord, and more.

You can add OAuth functionality to your Fresh project using the new plugin:

// main.ts
import { start } from "$fresh/server.ts";
import { createGitHubOAuth2Client } from "";
import { kvOAuthPlugin } from "";
import manifest from "./fresh.gen.ts";

await start(manifest, {
  plugins: [

Or, if using another framework using the Web API:

// Sign-in, callback and sign-out handlers
import {
} from "";

const oauth2Client = createGitHubOAuth2Client();

async function handleSignIn(request: Request) {
  return await signIn(request, oauth2Client);

async function handleOAuth2Callback(request: Request) {
  return await handleCallback(request, oauth2Client);

async function handleSignOut(request: Request) {
  return await signOut(request);
This high level wrapper provides many helper functions to make it easy to add auth, login, and more to your app.

Projects are already using Deno KV OAuth for authentication, such as SaaSKit, KV Sketchbook, and more.

Coming soon

We’ve received your feedback and are working hard to add useful features to make Deno KV on Deno Deploy the easiest, fastest way to add state to your globally hosted project.

Here’s an incomplete list of previews of what’s to come.

Key TTL with expireIn

Key time-to-live expiration is an important feature in Redis, which allows you to easily manage user sessions or create your own caching system. Soon, you can do the same in Deno KV with the expireIn option, which accepts a number in milliseconds:

const db = await Deno.openKv();

await db.set(["a"], 1, { expireIn: 1000 });

The key will be deleted from the database after the specified number of milliseconds in expireIn have elapsed. If the expireIn is not specified, the key will not expire.

Note this feature is already available in the Deno runtime.

S3 backups

Every production application demands data backups in case things go awry. Soon, you’ll be able to enable backups of your Deno KV data to your own S3 bucket:

Enabling S3 backups for your Deno KV data

The backup is real-time, supporting point-in-time recovery for your data. Initially you’ll be able to restore backups to a local Deno KV database, with support for restoring to a hosted Deno KV database coming soon after.

Primary region selection

Deno KV uses a single primary region that processes writes and multiple read regions handling reads. When a write transaction is sent, it’s first processed at the primary region, then replicated to all read regions, providing eventual data consistency across all regions. Thusly, your write latencies are impacted by how far your users are from your primary region, while read latencies when using when using consistency: "eventual" are impacted by how far your users are from any of your read regions.

Soon, you’ll be able to optimize latency and performance for your users by selecting your primary region:

Selecting your primary region in Deno KV

Since there’s no one-size-fits-all configuration for every app or business, its important to have full control over how and where your data is being stored and retrieved to optimize performance for your users.

A primary region switch takes less than 5 seconds to take effect and causes no downtime for your application. We’ll be rolling out this feature to Deno Deploy users in the coming weeks.

What’s next?

Our vision for Deno Deploy is to make it the easiest place to host JavaScript through built-in cloud primitives such as Deno KV (and more — stay tuned!). As we work towards a generally available release of Deno KV and Deno Deploy, we’ll continue to add features to make it as simple as possible to build and host production-ready JavaScript apps.

We’re always open to feedback and feature requests! Feel free to join our growing Discord or create an issue here.

Deploy a project to to Deno Deploy today — it’ll take less than 5 minutes.