Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where is the database saved and opened in Deno KV?

Tags:

saas

deno

freshjs

I have always thought that Deno KV is an SaaS as it has a price, and thus is stored only on the cloud. This assumption has never been challenged since every time I use openKv without any parameter I can set and get entries to or from Deno KV just fine:

const kv = await Deno.openKv();
const a = await kv.get(["preferences", "ada"]);
console.log(a);
// Result: {"key":["preferences","ada"],"value":{"username":"ada","theme":"dark","language":"en-US"},"versionstamp":"00000000000000090000"}

Today, when I run routes/test.tsx with Fresh, the data is null:

export const handler: Handlers = {
  async GET(req, ctx) {
    const kv = await Deno.openKv();
    const a = await kv.get(["preferences", "ada"]);
    console.log(a);
    return ctx.render({ a });
  },
};
// Result: {"key":["preferences","ada"],"value":null,"versionstamp":null}

From Deno.openKv | Runtime APIs | Deno:

When no path is provided, the database will be opened in a default path for the current script. This location is persistent across script runs and is keyed on the origin storage key (the same key that is used to determine localStorage persistence). More information about the origin storage key can be found in the Deno Manual.

I look at the manual and the article Web Storage API | Deno Docs seems to be about that. But I don't understand what it says.

So, where is exactly the database stored? Is it on the cloud or on my machine?

like image 739
Ooker Avatar asked Aug 31 '25 23:08

Ooker


2 Answers

When running locally, data is persisted on your machine by default, not the cloud. If you simply run Deno.openKv(), depending on where you make the call, it could conect to a different filepath. You can find where Deno is storing your local data by running deno info.

Optionally, you can specify a path for your database. This could be a filepath, ":memory:" for an in-memory instance, or a URL to a hosted KV instance. To remotely connect to a KV instance hosted on Deploy you also have to set the environment variable DENO_KV_ACCESS_TOKEN to a token value that you generate on Deploy.

So, when you are running your Fresh project locally, I would recommend only calling Deno.openKv() in a single location in your program. Export the kv object, and import it wherever you need it. This should work both locally and when deployed. You don't need to call Deno.openKv() on every request, this might even hurt performance.

// Deno decides automatically what path to persist data to
const kv = await Deno.openKv()

// Open an instance at a specific filepath
const kv = await Deno.openKv("./db.sqlite3")

// Open an in-memory KV instance
const kv = await Deno.openKv(":memory:")

// Remotely connect to a KV instance hosted on Deno Deploy
// In your .env file: DENO_KV_ACCESS_TOKEN=<token>
const kv = await Deno.openKv("https://api.deno.com/databases/<project_id>/connect");

I usually do this, which should work when running locally and on Deploy:

// In db.ts
export const kv = await Deno.openKv()

// In routes/test.tsx
import { kv } from "../db.ts"

export const handler: Handlers = {
  async GET(req, ctx) {
    const a = await kv.get(["preferences", "ada"]);
    console.log(a);
    return ctx.render({ a });
  },
};
like image 150
Noobster Avatar answered Sep 07 '25 07:09

Noobster


When running locally without parameters, Deno KV instances are created on your local machine (no cloud involved). While you can't get the exact location programmatically, you can run deno info to get the origin storage location.

14:55:53 ~/dev/deno/my-project main $ deno info
DENO_DIR location: /Users/chris/Library/Caches/deno
Remote modules cache: /Users/chris/Library/Caches/deno/deps
npm modules cache: /Users/chris/Library/Caches/deno/npm
Emitted modules cache: /Users/chris/Library/Caches/deno/gen
Language server registries cache: /Users/chris/Library/Caches/deno/registries
Origin storage: /Users/chris/Library/Caches/deno/location_data

Under that origin storage will be hash subdirectories and in one of them will be your KV database. E.g. on my Mac machine, one of my projects has it's KV store at

/Users/chris/Library/Caches/deno/location_data/76e55328e36839ed4769f6e60580dad36584898849bf4a9264fa1be1fc692990/kv.sqlite3

This is the default location for 'my-project' storage. If I have an a.ts and a b.ts in my project, running either via deno run a.ts or deno run b.ts, both will use the same local KV store (as shown above) when using the default KV store (e.g. const kv = await Deno.openKv();). However, another deno project on my machine will have a separate hash and therefore separate location data. The semantics of how the hash is generated is not documented, but it seems to be tied to a project. Alternatively, you can specify an exact location for the db to be created/used via const kv = await Deno.openKv('./myKv.db');.

On Deno Deploy, there are two KV databases created. One for your production deployment and the other one shared between all preview deployments. In Deploy, you cannot specify an exact file location and only the default await Deno.openKv() will work (n.b. you can also specify a self-hosted URL I believe).

As for your differences in test vs routes code, I can't answer that without further insight into your project and file setup, other than that the location storage sub-directory will be different between them.

like image 45
Chris Knight Avatar answered Sep 07 '25 08:09

Chris Knight