Skip to content
workers-go
Esc
navigateopen⌘Jpreview
On this page

KV

Read, write, list, and delete keys in a Cloudflare Workers KV namespace from Go.

Workers KV is a global, low-latency key-value store. The cloudflare/kv package wraps a bound KV namespace.

Declare the binding

[[kv_namespaces]]
binding = "COUNTER"
id = "<your namespace id>"

Connect to a namespace

kv.NewNamespace resolves the binding by name and returns an error when no binding with that name exists.

counterKV, err := kv.NewNamespace("COUNTER")
if err != nil {
	// no binding named COUNTER
}

Get a value

GetString reads a value as a string and GetReader streams it as an io.ReadCloser — the caller is responsible for closing it. Both accept *kv.GetOptions; pass nil for defaults. If the key doesn’t exist, both return kv.ErrNotFound; check for it with errors.Is.

value, err := counterKV.GetString("count", nil)
if errors.Is(err, kv.ErrNotFound) {
	// no value for "count"
} else if err != nil {
	return err
}

r, err := counterKV.GetReader("image", &kv.GetOptions{
	CacheTTL: 3600, // cache the value at the edge for this many seconds
})
if err != nil {
	return err
}
defer r.Close()

Get multiple values

GetStrings reads up to 100 keys in a single call. A missing key is simply omitted from the result map instead of causing an error.

values, err := counterKV.GetStrings([]string{"count", "other"}, nil)
if err != nil {
	return err
}
for key, value := range values {
	fmt.Println(key, value)
}

Put a value

PutString stores a string and PutReader stores the contents of an io.Reader. PutReader copies the full body into memory.

err := counterKV.PutString("count", "42", nil)

err = counterKV.PutString("session", token, &kv.PutOptions{
	ExpirationTTL: 3600, // expire after this many seconds
	// Expiration: 1735689600, // or an absolute Unix timestamp
})

Delete a key

err := counterKV.Delete("count")

List keys

List returns up to Limit keys, optionally filtered by Prefix. When ListComplete is false, pass the returned Cursor back to fetch the next page.

res, err := counterKV.List(&kv.ListOptions{
	Prefix: "user:",
	Limit:  100,
})
if err != nil {
	return err
}
for _, key := range res.Keys {
	fmt.Println(key.Name, key.Expiration)
}
if !res.ListComplete {
	nextCursor := res.Cursor
	_ = nextCursor // pass as ListOptions.Cursor for the next page
}

Example project

_examples/kv-counter implements a page-view counter backed by KV.

Was this page helpful?