> ## Documentation Index
> Fetch the complete documentation index at: https://cache-pot.thatdevguy.in/llms.txt
> Use this file to discover all available pages before exploring further.

# String commands in Cache-Pot: GET, SET, INCR, APPEND

> Full reference for Cache-Pot string commands: GET, SET, GETSET, APPEND, STRLEN, GETRANGE, SETRANGE, INCR, DECR, INCRBY, DECRBY, MGET, MSET.

Strings are Cache-Pot's most fundamental data type. Every string value is a sequence of bytes — you can store plain text, serialized JSON, binary blobs, or numeric strings that you increment and decrement in place. All the commands on this page operate on keys whose type is `string`. Values are capped at 512 MB.

<Note>
  String values are limited to 512 MB. `SETRANGE` enforces this limit and returns an error if the resulting string would exceed it.
</Note>

***

### GET

Returns the value stored at `key`. Returns nil (null bulk string) when the key does not exist.

**Syntax:** `GET key`

```redis theme={null}
SET greeting "hello"
GET greeting
# "hello"

GET nonexistent
# (nil)
```

**Returns:** Bulk string, or nil if the key does not exist.

***

### SET

Sets `key` to `value`. Optionally sets a TTL or enforces a conditional write.

**Syntax:** `SET key value [EX seconds | PX milliseconds] [NX | XX]`

<ParamField path="EX seconds" type="integer">
  Expire the key after this many seconds.
</ParamField>

<ParamField path="PX milliseconds" type="integer">
  Expire the key after this many milliseconds.
</ParamField>

<ParamField path="NX" type="flag">
  Only set the key if it does **not** already exist.
</ParamField>

<ParamField path="XX" type="flag">
  Only set the key if it **already** exists.
</ParamField>

```redis theme={null}
SET session:abc "user42" EX 3600
# OK

SET counter 0 NX
# OK  (set, key was absent)

SET counter 0 NX
# (nil)  (not set, key already exists)
```

**Returns:** `OK` on success. Nil when the `NX` or `XX` condition is not met.

***

### GETSET

Atomically sets `key` to a new `value` and returns the previous value stored at that key. Useful for implementing atomic swap patterns.

**Syntax:** `GETSET key value`

```redis theme={null}
SET token "old-token"
GETSET token "new-token"
# "old-token"

GET token
# "new-token"
```

**Returns:** Bulk string containing the old value, or nil if the key did not exist before the call.

***

### APPEND

Appends `value` to the end of the string stored at `key`. If `key` does not exist, it is created as an empty string first.

**Syntax:** `APPEND key value`

```redis theme={null}
APPEND log "2024-01-01: server started\n"
# (integer) 27

APPEND log "2024-01-01: request received\n"
# (integer) 57
```

**Returns:** Integer — the new byte length of the string after the append.

***

### STRLEN

Returns the byte length of the string stored at `key`.

**Syntax:** `STRLEN key`

```redis theme={null}
SET name "Alice"
STRLEN name
# (integer) 5

STRLEN nonexistent
# (integer) 0
```

**Returns:** Integer — the length in bytes, or `0` if the key does not exist.

***

### GETRANGE

Returns a substring of the string stored at `key`, between the `start` and `end` byte offsets (both inclusive). Negative indices count from the end: `-1` is the last byte, `-2` the second-to-last, and so on.

**Syntax:** `GETRANGE key start end`

```redis theme={null}
SET msg "Hello, World!"
GETRANGE msg 0 4
# "Hello"

GETRANGE msg -6 -1
# "World!"
```

**Returns:** Bulk string — the substring. Returns an empty string if the key does not exist or the range is invalid.

***

### SETRANGE

Overwrites part of the string stored at `key`, beginning at `offset`. Zero-pads the string if the offset extends past the current length. The offset must be non-negative.

**Syntax:** `SETRANGE key offset value`

```redis theme={null}
SET greeting "Hello World"
SETRANGE greeting 6 "Cache"
# (integer) 11

GET greeting
# "Hello Cache"
```

**Returns:** Integer — the new byte length of the string after the overwrite.

***

### INCR

Increments the integer value stored at `key` by 1. If the key does not exist, it is initialised to `0` before incrementing. Returns an error if the value is not a valid integer.

**Syntax:** `INCR key`

```redis theme={null}
SET page_views 100
INCR page_views
# (integer) 101

INCR new_counter
# (integer) 1
```

**Returns:** Integer — the new value after incrementing.

***

### DECR

Decrements the integer value stored at `key` by 1. Behaves like `INCR` in reverse; initialises to `0` if the key does not exist.

**Syntax:** `DECR key`

```redis theme={null}
SET stock 5
DECR stock
# (integer) 4
```

**Returns:** Integer — the new value after decrementing.

***

### INCRBY

Increments the integer value stored at `key` by the given `delta`.

**Syntax:** `INCRBY key delta`

```redis theme={null}
SET score 50
INCRBY score 25
# (integer) 75
```

**Returns:** Integer — the new value after incrementing.

***

### DECRBY

Decrements the integer value stored at `key` by the given `delta`.

**Syntax:** `DECRBY key delta`

```redis theme={null}
SET balance 200
DECRBY balance 30
# (integer) 170
```

**Returns:** Integer — the new value after decrementing.

***

### MGET

Returns the values of all specified keys in order. For any key that does not exist or holds a non-string type, nil is returned in that position.

**Syntax:** `MGET key [key ...]`

```redis theme={null}
SET user:1:name "Alice"
SET user:2:name "Bob"

MGET user:1:name user:2:name user:3:name
# 1) "Alice"
# 2) "Bob"
# 3) (nil)
```

**Returns:** Array of bulk strings (or nil entries) in the same order as the requested keys.

***

### MSET

Sets multiple key-value pairs in a single atomic call. Existing keys are overwritten. Unlike `SET`, `MSET` has no conditional options.

**Syntax:** `MSET key value [key value ...]`

```redis theme={null}
MSET user:1:name "Alice" user:1:age "30" user:1:city "Berlin"
# OK

MGET user:1:name user:1:age user:1:city
# 1) "Alice"
# 2) "30"
# 3) "Berlin"
```

**Returns:** Always `OK`.

<Tip>
  Use `MSET` and `MGET` to batch reads and writes into a single round-trip, reducing client latency when working with related keys.
</Tip>
