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?
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 });
},
};