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.