# Key/Value Store Walkthrough

The Key/Value Store is a JetStream feature, so we need to verify it is enabled by

```shell
nats account info
```

which may return

```
JetStream Account Information:

   JetStream is not supported in this account
```

In this case, you should enable JetStream.

## Prerequisite: enabling JetStream

If you are running a local `nats-server` stop it and restart it with JetStream enabled using `nats-server -js` (if that's not already done)

You can then check that JetStream is enabled by using

```shell
nats account info
```

```
Connection Information:

               Client ID: 6
               Client IP: 127.0.0.1
                     RTT: 64.996µs
       Headers Supported: true
         Maximum Payload: 1.0 MiB
           Connected URL: nats://127.0.0.1:4222
       Connected Address: 127.0.0.1:4222
     Connected Server ID: ND2XVDA4Q363JOIFKJTPZW3ZKZCANH7NJI4EJMFSSPTRXDBFG4M4C34K

JetStream Account Information:

           Memory: 0 B of Unlimited
          Storage: 0 B of Unlimited
          Streams: 0 of Unlimited
        Consumers: 0 of Unlimited 
```

## Creating a KV bucket

A 'KV bucket' is like a stream; you need to create it before using it, as in `nats kv add <KV Bucket Name>`:

```shell
nats kv add my-kv
```

```
my_kv Key-Value Store Status

         Bucket Name: my-kv
         History Kept: 1
        Values Stored: 0
           Compressed: false
   Backing Store Kind: JetStream
          Bucket Size: 0 B
  Maximum Bucket Size: unlimited
   Maximum Value Size: unlimited
          Maximum Age: unlimited
     JetStream Stream: KV_my-kv
              Storage: File
```

## Storing a value

Now that we have a bucket, we can assign, or 'put', a value to a specific key:

```shell
nats kv put my-kv Key1 Value1
```

which should return the key's value `Value1`

## Getting a value

We can fetch, or 'get', the value for a key "Key1":

```shell
nats kv get my-kv Key1
```

```
my-kv > Key1 created @ 12 Oct 21 20:08 UTC

Value1
```

## Deleting a value

You can always delete a key and its value by using

```shell
nats kv del my-kv Key1
```

It is harmless to delete a non-existent key (check this!!).

## Atomic operations

K/V Stores can also be used in concurrent design patterns, such as semaphores, by using atomic 'create' and 'update' operations.

E.g. a client wanting exclusive use of a file can lock it by creating a key, whose value is the file name, with `create` and deleting this key after completing use of that file. A client can increase the resilience against failure by using a timeout for the `bucket` containing this key. The client can use `update` with a revision number to keep the `bucket` alive.

Updates can also be used for more fine-grained concurrency control, sometimes known as `optimistic locking`, where multiple clients can try a task, but only one can successfully complete it.

### Create (aka exclusive locking)

Create a lock/semaphore with the `create` operation.

```shell
nats kv create my-sem Semaphore1 Value1
```

Only one `create` can succeed. First come, first serve. All concurrent attempts will result in an error until the key is deleted

```shell
nats kv create my-sem Semaphore1 Value1
nats: error: nats: wrong last sequence: 1: key exists
```

### Update with CAS (aka optimistic locking)

We can also atomically `update`, sometimes known as a CAS (compare and swap) operation, a key with an additional parameter `revision`

```shell
nats kv update my-sem Semaphore1 Value2 13
```

A second attempt with the same revision 13, will fail

```shell
nats kv update my-sem Semaphore1 Value2 13
nats: error: nats: wrong last sequence: 14
```

## Watching a K/V Store

An unusual functionality of a K/V Store is being able to 'watch' a bucket, or a specific key in that bucket, and receive real-time updates to changes in the store.

For the example above, run `nats kv watch my-kv`. This will start a watcher on the bucket we have just created earlier. By default, the KV bucket has a history size of one, and so it only remembers the last change. In our case, the watcher should see a delete of the value associated with the key "Key1":

```shell
nats kv watch my-kv
```

```
[2021-10-12 13:15:03] DEL my-kv > Key1
```

If we now concurrently change the value of 'my-kv' by

```shell
nats kv put my-kv Key1 Value2
```

The watcher will see that change:

```shell
[2021-10-12 13:25:14] PUT my-kv > Key1: Value2
```

## Cleaning up

When you are finished using a bucket, you can delete the bucket, and its resources, by using the `rm` operator:

```shell
nats kv rm my-kv
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.nats.io/nats-concepts/jetstream/key-value-store/kv_walkthrough.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
