Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/styles/config/vocabularies/Doc/accept.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ LLM
LLMs
Lume
LTS
Materia
Matomo
maven
Metabase
Expand Down
35 changes: 35 additions & 0 deletions content/changelog/2026/03-30-materia-kv-hash-ttl-commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: "Materia KV: new hash, string and TTL commands"
description: Materia KV now supports GETDEL, HEXISTS, HSETNX, HINCRBY, EXPIREAT and PEXPIREAT commands, with improved scan reliability and transaction retry limits.
date: 2026-03-30
tags:
- addons
- materia
- kv
authors:
- name: Baptiste Le Morlec
link: https://github.com/baptiste-le-m
image: https://github.com/baptiste-le-m.png?size=40
- name: Pierre Zemb
link: https://github.com/pierrez
image: https://github.com/pierrez.png?size=40
excludeSearch: true
---

[Materia KV](/doc/addons/materia-kv/) adds six new commands to its Redis-compatible layer, expanding hash, string and time to live (TTL) management capabilities:

- `HEXISTS`: check if a field exists in a hash
- `HSETNX`: set a hash field only if it doesn't already exist
- `HINCRBY`: increment the integer value of a hash field
- `GETDEL`: atomically get a string value and delete its key
- `EXPIREAT`: set key expiration using an absolute Unix timestamp in seconds
- `PEXPIREAT`: set key expiration using an absolute Unix timestamp in milliseconds

These commands are available for new and already deployed add-ons, with no additional configuration.

This update also brings reliability improvements to the underlying storage layer. The `SCAN`, `HSCAN`, `SSCAN` and `KEYS` commands now produce more accurate results thanks to fixes in the scan boundary logic.

Transactions now enforce retry limits of 5 retries with a 5-second timeout, preventing cascading retries from overwhelming the cluster under heavy contention. Previously, transactions could retry indefinitely on conflict.

- [Learn more about Materia KV](/doc/addons/materia-kv/)
- [Learn more about Materia KV supported commands](/doc/addons/materia-kv/#supported-types-and-commands)
12 changes: 9 additions & 3 deletions content/doc/addons/materia-kv.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,20 +153,25 @@ Find below the list of currently supported commands:
| `DECRBY` | Decrements the number stored at `key` by the given `decrement`. If the `key` doesn't exist, it is set to `0` before performing the operation. An error is returned if `key` contains a value of the wrong type or contains a string that can not be represented as integer. This operation is limited to 64-bit signed integers. |
| `DEL` | Removes the specified `key`. A key is ignored if it doesn't exist. |
| `EXISTS` | Returns if `key` exists. |
| `EXPIRE` | Set a `key` time to live in seconds. After the timeout has expired, the `key` will be automatically deleted. The time to live can be updated using the `EXPIRE` command or cleared using the `PERSIST` command. |
| `EXPIRE` | Set a `key` time to live in seconds. After the timeout has expired, the `key` will be automatically deleted. The time to live can be updated using the `EXPIRE` command or cleared using the `PERSIST` command. |
| `EXPIREAT` | Sets a `key` to expire at the specified Unix timestamp (in seconds). After that time, the `key` is automatically deleted. Returns `1` if the timeout was set, `0` if the `key` doesn't exist. |
| `FLUSHALL` | Delete all the keys of all the existing databases, not just the currently selected one. This command never fails. |
| `FLUSHDB` | Delete all the keys of the currently selected DB. This command never fails. |
| `GET` | Get the value of `key`. If the `key` doesn't exist the special value nil is returned. An error is returned if the value stored at `key` is not a string, because `GET` only handles string values. |
| `GETBIT` | Returns the bit value at offset in the string value stored at `key`. |
| `GETDEL` | Gets the value of `key` and deletes the key. If the `key` doesn't exist, returns `nil`. Returns an error if the value stored at `key` isn't a string. |
| `GETRANGE` | Returns the substring of the string value stored at `key`, determined by the offsets start and end (both are inclusive). Negative offsets can be used in order to provide an offset starting from the end of the string. So `-1` means the last character, `-2` the penultimate and so forth. |
| `HDEL` | Removes the specified fields from the hash stored at `key`. Specified fields that do not exist within this hash are ignored. If `key` does not exist, it is treated as an empty hash and this command returns `0`. |
| `HELLO` | Switch to a different protocol, optionally authenticating and setting the connection's name, or provide a contextual client report. It always replies with a list of current server and connection properties. |
| `HEXISTS` | Returns `1` if `field` exists in the hash stored at `key`, `0` if `field` or `key` don't exist. Returns an error if the value stored at `key` isn't a hash. |
| `HGET` | Returns the value associated with `field` in the hash stored at `key`. If `key` does not exist, or `field` is not present in the hash, `nil` is returned. |
| `HGETALL` | Returns all fields and values of the hash stored at `key`. In the returned value, every field name is followed by its value, so the length of the reply is twice the size of the hash. |
| `HINCRBY` | Increments the number stored at `field` in the hash stored at `key` by the given `increment`. If `key` doesn't exist, creates a new key holding a hash. If `field` doesn't exist, sets the value to `0` before performing the operation. Returns an error if the field contains a value of the wrong type or the resulting value exceeds a 64-bit signed integer. |
| `HLEN` | Returns the number of fields contained in the hash stored at `key`. If `key` does not exist, it is treated as an empty hash and `0` is returned. |
| `HMGET` | Returns the values associated with the specified `fields` in the hash stored at `key`. For every field that does not exist in the hash, a `nil` value is returned. Because of this, the operation never fails. |
| `HSCAN` | Incrementally iterate over hash fields and associated values. It is a cursor based iterator, this means that at every call of the command, the server returns an updated cursor that the user needs to use as the cursor argument in the next call. An iteration starts when the cursor is set to `0`, and terminates when the cursor returned by the server is `0`. |
| `HSET` | Sets the specified fields to their respective values in the hash stored at `key`. If `key` does not exist, a new key holding a hash is created. If `key` exists but does not hold a hash, an error is returned. |
| `HSETNX` | Sets `field` in the hash stored at `key` to `value`, only if `field` doesn't yet exist. If `key` doesn't exist, creates a new key holding a hash. If `field` already exists, the operation has no effect. Returns `1` if `field` is a new field in the hash and the value was set, `0` if `field` already exists. |
| `INCR` | Increments the number stored at `key` by one. If the `key` doesn't exist, it is set to `0` before performing the operation. An error is returned if `key` contains a value of the wrong type or contains a string that can not be represented as integer. This operation is limited to 64-bit signed integers. |
| `INCRBY` | Increments the number stored at `key` by the given `increment`. If the `key` doesn't exist, it is set to `0` before performing the operation. An error is returned if `key` contains a value of the wrong type or contains a string that can not be represented as integer. This operation is limited to 64-bit signed integers. |
| `INCRBYFLOAT` | Increment the string representing a floating point number stored at `key` by the specified `increment`. If the key does not exist, it is set to `0` before performing the operation. An error is returned if the key contains a value of the wrong type or a string that can not be represented as a floating point number. |
Expand All @@ -179,7 +184,8 @@ Find below the list of currently supported commands:
| `MGET` | Returns the values of all specified keys. For every key that doesn't hold a string value or doesn't exist, the special value `nil` is returned. Because of this, the operation never fails. |
| `MSET` | Sets the given keys to their respective values. `MSET` replaces existing values with new values, just as regular `SET`. `MSET` is atomic, so all given keys are set at once. It is not possible for clients to see that some keys were updated while others are unchanged. |
| `PERSIST` | Remove the existing time to live associated with the `key`. |
| `PEXPIRE` | Set a `key` time to live in milliseconds. After the timeout has expired, the `key` will be automatically deleted. The time to live can be updated using the `PEXPIRE` command or cleared using the `PERSIST` command. |
| `PEXPIRE` | Set a `key` time to live in milliseconds. After the timeout has expired, the `key` will be automatically deleted. The time to live can be updated using the `PEXPIRE` command or cleared using the `PERSIST` command. |
| `PEXPIREAT` | Sets a `key` to expire at the specified absolute Unix timestamp in milliseconds. After that time, the `key` is automatically deleted. Returns `1` if the timeout was set, `0` if the `key` doesn't exist. |
| `PING` | Returns `PONG` if no argument is provided, otherwise return a copy of the argument as a bulk. |
| `PTTL` | Returns the remaining time to live of a `key`, in milliseconds. |
| `SADD` | Add the specified members to the set stored at `key`. Specified members that are already a member of this set are ignored. If `key` doesn't exist, a new set is created before adding the specified members. |
Expand All @@ -200,9 +206,9 @@ Find below the list of currently supported commands:
| `SRANDMEMBER` | When called with just the `key` argument, return a random element from the set value stored at `key`. |
| `SREM` | Remove the specified members from the set stored at `key`. Specified members that are not a member of this set are ignored. If `key` doesn't exist, it is treated as an empty set and this command returns `0`. |
| `SSCAN` | Incrementally iterate over set elements. It is a cursor based iterator, this means that at every call of the command, the server returns an updated cursor that the user needs to use as the cursor argument in the next call. An iteration starts when the cursor is set to `0`, and terminates when the cursor returned by the server is `0`. |
| `STRLEN` | Returns the length of the string value stored at `key`. An error is returned when key holds a non-string value. |
| `SUNION` | Returns the members of the set resulting from the union of all the given sets. |
| `SUNIONSTORE` | This command is equal to `SUNION`, but instead of returning the resulting set, it is stored in `destination`. If `destination` already exists, it is overwritten. |
| `STRLEN` | Returns the length of the string value stored at `key`. An error is returned when key holds a non-string value. |
| `TTL` | Returns the remaining time to live of a `key`, in seconds. |
| `TYPE` | Returns the string representation of the type of the value stored at `key`. Can be: `hash`, `list`, `set` or `string`. |

Expand Down
Loading