> ## Documentation Index
> Fetch the complete documentation index at: https://voyant.travel/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# KV

> Workers KV namespaces for your app: provisioned and managed by Voyant, bound to your Worker through wrangler, and accessed with the standard Cloudflare KV API.

[Workers KV](https://developers.cloudflare.com/kv/) is a low-latency key-value store, good for caches, feature flags, hostname routing, and small config that is read often and written rarely. On Voyant you provision KV **namespaces**, bind them to your app, and call them through the standard Cloudflare KV binding, so your app never holds storage credentials.

## Provision a namespace

Manage namespaces from the dashboard under **Cloud → KV**: list the namespaces provisioned for your organization, create a new one by name, and delete ones you no longer use. Cloud provisions the underlying Cloudflare KV namespace and tracks it as a resource scoped to your organization.

You can also let a deploy provision a namespace for you: declare it in `wrangler.jsonc` and Cloud resolves and provisions it on deploy (see below). Either way, KV is dashboard- and declaration-driven; there is no `voyant kv` CLI command (unlike R2 buckets, which have `voyant storage` commands).

## Bind it to your app

KV reaches your code as a **binding**. Declare it in your app's `wrangler.jsonc`, and on deploy Cloud resolves the binding to a provisioned namespace scoped to your organization and environment:

```jsonc theme={null}
{
  "kv_namespaces": [{ "binding": "CACHE" }]
}
```

Cloud derives the binding name by upper-casing the resource name and turning dashes into underscores, so a namespace named `my-cache` is reachable as `env.MY_CACHE`. The platform owns the `kv_namespaces` key in the merged wrangler config, so the resolved ids always point at your provisioned namespaces.

## Use it

Read and write through the binding with Cloudflare's KV API:

```ts theme={null}
await env.CACHE.put("rate:eur", "1.08", { expirationTtl: 3600 });
const rate = await env.CACHE.get("rate:eur");
```

The methods (`get`, `put`, `list`, `delete`, metadata, and TTLs) are Cloudflare's. See Cloudflare's [KV API reference](https://developers.cloudflare.com/kv/api/) for the full surface. Key and value access happens at the edge through the binding, not through a Cloud API.

## Deleting a namespace

A namespace that is still bound to one or more app deployments cannot be deleted. Remove the binding from every app's `wrangler.jsonc` `kv_namespaces` and redeploy, then delete the namespace. This prevents a live deployment from losing a binding it still resolves.

<Note>
  The platform's public response cache uses a KV binding named `CACHE` when the Cache API is unavailable. See [Caching](/docs/platform/fundamentals/caching) for what the platform stores in KV and the TTL-first invalidation model.
</Note>

## Next steps

<CardGroup cols={2}>
  <Card title="Storage" icon="box" href="/docs/services/storage">
    Object storage (R2) and the binding model KV shares.
  </Card>

  <Card title="Database" icon="database" href="/docs/services/database">
    Managed Postgres (Neon) and Cloudflare D1.
  </Card>

  <Card title="Caching" icon="bolt" href="/docs/platform/fundamentals/caching">
    How the platform uses KV for the public response cache.
  </Card>

  <Card title="CLI commands" icon="terminal" href="/docs/cli/commands">
    The `voyant storage` and `voyant databases` resource commands.
  </Card>
</CardGroup>
