TairHash (exHash) is a hash data structure that lets you set an expiration time and version for each field. This capability enhances the flexibility of the hash data structure and simplifies development in many scenarios.
Overview
TairHash extends the standard Redis hash with two capabilities that native Redis hash lacks: per-field expiration and per-field versioning. You can set a TTL on individual fields without affecting the rest of the key, and use version numbers to prevent conflicting concurrent writes.
TairHash uses an Active Expire algorithm that proactively checks and deletes expired fields without noticeably affecting response time. It also supports passive expiration, which removes expired fields on access.
Key features
Set an expiration time and version for each field.
Use active and passive expiration policies for fields.
Use syntax similar to the native Redis hash data type.
This module is open source. For more information, see TairHash.
Prerequisites
Before you begin, ensure you have:
A Tair instance of one of the following types:
Persistent memory-optimized (minor version 1.2.6 or later)
Keep your instance on the latest minor version for additional features and improved stability. See Minor version update. For instances using a cluster architecture or read/write splitting architecture, also update the proxy nodes — otherwise some commands may not be recognized.
Precautions
The commands operate on TairHash data in a Tair instance.
Commands
The following tables list all TairHash commands, grouped by operation type.
Write commands
| Command | Syntax | Description |
|---|---|---|
| EXHSET | EXHSET key field value [EX time] [EXAT time] [PX time] [PXAT time] [NX | XX] [VER | ABS version] [KEEPTTL] | Adds a field to the specified TairHash key. Creates the key if it does not exist. Overwrites the field value if the field already exists. |
| EXHMSET | EXHMSET key field value [field value ...] | Adds multiple fields to the specified TairHash key. Creates the key if it does not exist. Overwrites existing field values. |
| EXHINCRBY | EXHINCRBY key field num [EX time] [EXAT time] [PX time] [PXAT time] [VER | ABS version] [MIN minval] [MAX maxval] [KEEPTTL] | Increments the integer value of a field by num. Creates the key or field if they do not exist (field starts at 0 before the increment). |
| EXHINCRBYFLOAT | EXHINCRBYFLOAT key field num [EX time] [EXAT time] [PX time] [PXAT time] [VER | ABS version] [MIN minval] [MAX maxval] [KEEPTTL] | Increments the floating-point value of a field by num. Creates the key or field if they do not exist (field starts at 0 before the increment). |
Expiration commands
| Command | Syntax | Description |
|---|---|---|
| EXHEXPIRE | EXHEXPIRE key field seconds [VER | ABS version] | Sets a relative expiration time in seconds for a field. |
| EXHPEXPIRE | EXHPEXPIRE key field milliseconds [VER | ABS version] | Sets a relative expiration time in milliseconds for a field. |
| EXHEXPIREAT | EXHEXPIREAT key field timestamp [VER | ABS version] | Sets an absolute expiration time (UNIX timestamp in seconds) for a field. |
| EXHPEXPIREAT | EXHPEXPIREAT key field milliseconds-timestamp [VER | ABS version] | Sets an absolute expiration time (UNIX timestamp in milliseconds) for a field. |
Read commands
| Command | Syntax | Description |
|---|---|---|
| EXHGET | EXHGET key field | Gets the value of a field. Returns nil if the key or field does not exist. |
| EXHMGET | EXHMGET key field [field ...] | Gets the values of multiple fields. Returns nil for fields that do not exist. |
| EXHGETWITHVER | EXHGETWITHVER key field | Gets the value and version number of a field. Returns nil if the key or field does not exist. |
| EXHMGETWITHVER | EXHMGETWITHVER key field [field ...] | Gets the values and version numbers of multiple fields. |
| EXHTTL | EXHTTL key field | Gets the remaining TTL of a field, in seconds. |
| EXHPTTL | EXHPTTL key field | Gets the remaining TTL of a field, in milliseconds. |
| EXHVER | EXHVER key field | Gets the current version number of a field. |
| EXHLEN | EXHLEN key [NOEXP] | Gets the number of fields in the key. Specify NOEXP to count only non-expired fields. |
| EXHEXISTS | EXHEXISTS key field | Checks whether a field exists. |
| EXHSTRLEN | EXHSTRLEN key field | Gets the length of a field's value string. |
| EXHKEYS | EXHKEYS key | Gets all fields in the key. |
| EXHVALS | EXHVALS key | Gets all field values in the key. |
| EXHGETALL | EXHGETALL key | Gets all fields and values in the key. |
| EXHSCAN | EXHSCAN key op subkey [MATCH pattern] [COUNT count] | Scans the key iteratively. Memory-optimized instances only. |
Version commands
| Command | Syntax | Description |
|---|---|---|
| EXHSETVER | EXHSETVER key field version | Sets the version number of a field. |
Delete commands
| Command | Syntax | Description |
|---|---|---|
| EXHDEL | EXHDEL key field [field ...] | Deletes one or more fields from the key. |
| DEL | DEL key [key ...] | Deletes one or more TairHash keys using the native Redis DEL command. |
Syntax conventions
| Convention | Meaning |
|---|---|
UPPERCASE KEYWORD | Command keyword |
_italic_ | Variable |
[option] | Optional parameter |
A|B | Mutually exclusive — specify one only |
... | Parameter can be repeated |
EXHSET
time complexity| Syntax | EXHSET key field value [EX time] [EXAT time] [PX time] [PXAT time] [NX | XX] [VER | ABS version] [KEEPTTL] |
|---|---|
| O(1) | |
| Description | Adds a field to the specified TairHash key. Creates the key if it does not exist. Overwrites the field value if the field already exists. |
Options
| Option | Description |
|---|---|
key | The TairHash key. |
field | The field to set. |
value | The value of the field. |
EX time | Relative expiration time in seconds. 0 means the field expires immediately. Omit to set no expiration. |
EXAT time | Absolute expiration time as a UNIX timestamp in seconds. 0 means the field expires immediately. |
PX time | Relative expiration time in milliseconds. 0 means the field expires immediately. |
PXAT time | Absolute expiration time as a UNIX timestamp in milliseconds. 0 means the field expires immediately. |
NX | Sets the field only if it does not already exist. |
XX | Sets the field only if it already exists. |
VER version | Optimistic concurrency control. If the field exists and its current version matches version, the operation proceeds and the version increments by 1. If versions differ, an error is returned. If the field does not exist or its version is 0, the check is skipped and the version becomes 1 after the operation. |
ABS version | Sets the version to an exact value regardless of the current version. |
KEEPTTL | Preserves the field's current expiration when you do not specify EX, EXAT, PX, or PXAT. Without KEEPTTL, EXHSET clears the existing expiration. |
After you set a timeout for a field, running EXHSET again without a timeout option clears the expiration (unless you useKEEPTTL). To set an expiration on the key itself, use the nativeEXPIREorEXPIREATcommand.
Return values
| Value | Meaning |
|---|---|
1 | A new field was created. |
0 | The field existed and its value was overwritten. |
-1 | XX was specified but the field does not exist, or NX was specified but the field already exists. |
"ERR update version is stale" | VER was specified and the version does not match the current version. |
Example
EXHSET myhash field1 val EX 10(integer) 1EXHGET
| Syntax | EXHGET key field |
|---|---|
| Time complexity | O(1) |
| Description | Gets the value of a field. Returns nil if the key or field does not exist. |
Return values
| Value | Meaning |
|---|---|
| Field value | The field exists. |
nil | The key or field does not exist. |
Example
EXHSET myhash field1 val
EXHGET myhash field1"val"EXHMSET
| Syntax | EXHMSET key field value [field value ...] |
|---|---|
| Time complexity | O(N), where N is the number of fields |
| Description | Adds multiple fields to the specified TairHash key. Creates the key if it does not exist. Overwrites existing field values. |
To set expiration on individual fields after creation, use EXHEXPIRE, EXHPEXPIRE, EXHEXPIREAT, or EXHPEXPIREAT. To set expiration on the key itself, use the nativeEXPIREorEXPIREATcommand.
Return values
| Value | Meaning |
|---|---|
OK | The operation succeeded. |
Example
EXHMSET myhash field1 val1 field2 val2OKEXHEXPIRE
| Syntax | EXHEXPIRE key field seconds [VER | ABS version] |
|---|---|
| Time complexity | O(1) |
| Description | Sets a relative expiration time in seconds for a field. |
Options
| Option | Description |
|---|---|
key | The TairHash key. |
field | The field to set the expiration on. |
seconds | Relative expiration time in seconds. |
VER version | Same optimistic concurrency behavior as in EXHSET. |
ABS version | Sets the version to an exact value regardless of the current version. |
Return values
| Value | Meaning |
|---|---|
1 | The field exists and the expiration was set. |
0 | The field does not exist. |
Example
EXHSET myhash field1 val
EXHEXPIRE myhash field1 100(integer) 1EXHPEXPIRE
| Syntax | EXHPEXPIRE key field milliseconds [VER | ABS version] |
|---|---|
| Time complexity | O(1) |
| Description | Sets a relative expiration time in milliseconds for a field. |
Options
| Option | Description |
|---|---|
key | The TairHash key. |
field | The field to set the expiration on. |
milliseconds | Relative expiration time in milliseconds. |
VER version | Same optimistic concurrency behavior as in EXHSET. |
ABS version | Sets the version to an exact value regardless of the current version. |
Return values
| Value | Meaning |
|---|---|
1 | The field exists and the expiration was set. |
0 | The field does not exist. |
Example
EXHSET myhash field1 val
EXHPEXPIRE myhash field1 1000(integer) 1EXHEXPIREAT
| Syntax | EXHEXPIREAT key field timestamp [VER | ABS version] |
|---|---|
| Time complexity | O(1) |
| Description | Sets an absolute expiration time (UNIX timestamp in seconds) for a field. |
Options
| Option | Description |
|---|---|
key | The TairHash key. |
field | The field to set the expiration on. |
timestamp | Absolute UNIX timestamp in seconds. |
VER version | Same optimistic concurrency behavior as in EXHSET. |
ABS version | Sets the version to an exact value regardless of the current version. |
Return values
| Value | Meaning |
|---|---|
1 | The field exists and the expiration was set. |
0 | The field does not exist. |
Example
EXHEXPIREAT myhash field1 1293840000(integer) 1EXHPEXPIREAT
| Syntax | EXHPEXPIREAT key field milliseconds-timestamp [VER | ABS version] |
|---|---|
| Time complexity | O(1) |
| Description | Sets an absolute expiration time (UNIX timestamp in milliseconds) for a field. |
Options
| Option | Description |
|---|---|
key | The TairHash key. |
field | The field to set the expiration on. |
milliseconds-timestamp | Absolute UNIX timestamp in milliseconds. |
VER version | Same optimistic concurrency behavior as in EXHSET. |
ABS version | Sets the version to an exact value regardless of the current version. |
Return values
| Value | Meaning |
|---|---|
1 | The field exists and the expiration was set. |
0 | The field does not exist. |
Example
EXHPEXPIREAT myhash field1 1293840000000(integer) 1EXHTTL
| Syntax | EXHTTL key field |
|---|---|
| Time complexity | O(1) |
| Description | Gets the remaining TTL of a field, in seconds. |
Return values
| Value | Meaning |
|---|---|
| Positive integer | Remaining TTL in seconds. |
-1 | The field exists but has no expiration set. |
-2 | The key does not exist. |
-3 | The field does not exist. |
Example
The following example shows all possible return states in a single sequence: a field with a TTL set (85), and a field with no expiration (-1).
EXHSET myhash field1 val1 EX 100
EXHSET myhash field2 val2
EXHTTL myhash field1
EXHTTL myhash field2
EXHTTL myhash field3(integer) 85
(integer) -1
(integer) -3EXHPTTL
| Syntax | EXHPTTL key field |
|---|---|
| Time complexity | O(1) |
| Description | Gets the remaining TTL of a field, in milliseconds. |
Return values
| Value | Meaning |
|---|---|
| Positive integer | Remaining TTL in milliseconds. |
-1 | The field exists but has no expiration set. |
-2 | The key does not exist. |
-3 | The field does not exist. |
Example
EXHSET myhash field1 val1 EX 100
EXHPTTL myhash field1(integer) 97213EXHVER
| Syntax | EXHVER key field |
|---|---|
| Time complexity | O(1) |
| Description | Gets the current version number of a field. |
Return values
| Value | Meaning |
|---|---|
| Positive integer | The current version number. |
-1 | The key does not exist. |
-2 | The field does not exist. |
Example
EXHVER myhash field1(integer) 1EXHSETVER
| Syntax | EXHSETVER key field version |
|---|---|
| Time complexity | O(1) |
| Description | Sets the version number of a field to an exact value. |
Return values
| Value | Meaning |
|---|---|
1 | The version was set. |
0 | The key or field does not exist. |
Example
EXHSETVER myhash field1 3(integer) 1EXHINCRBY
| Syntax | EXHINCRBY key field num [EX time] [EXAT time] [PX time] [PXAT time] [VER | ABS version] [MIN minval] [MAX maxval] [KEEPTTL] |
|---|---|
| Time complexity | O(1) |
| Description | Increments the integer value of a field by num. Creates the key or field if they do not exist; a new field starts at 0 before the increment. |
Options
| Option | Description |
|---|---|
key | The TairHash key. |
field | The field to increment. |
num | Integer increment value. |
EX, EXAT, PX, PXAT | Same as in EXHSET. |
VER version | Same optimistic concurrency behavior as in EXHSET. |
ABS version | Sets the version to an exact value regardless of the current version. |
MIN minval | Minimum allowed value. Returns an error if the result would be less than minval. |
MAX maxval | Maximum allowed value. Returns an error if the result would exceed maxval. |
KEEPTTL | Preserves the field's current expiration. Same behavior as in EXHSET. |
After you set a timeout for a field, running EXHINCRBY again without a timeout option clears the expiration (unless you use KEEPTTL).Return values
| Value | Meaning |
|---|---|
| Integer | The new value after the increment. |
Example
EXHMSET myhash field1 10
EXHINCRBY myhash field1 100(integer) 110EXHINCRBYFLOAT
| Syntax | EXHINCRBYFLOAT key field num [EX time] [EXAT time] [PX time] [PXAT time] [VER | ABS version] [MIN minval] [MAX maxval] [KEEPTTL] |
|---|---|
| Time complexity | O(1) |
| Description | Increments the floating-point value of a field by num. Creates the key or field if they do not exist; a new field starts at 0 before the increment. |
Options
| Option | Description |
|---|---|
key | The TairHash key. |
field | The field to increment. |
num | Floating-point increment value. |
EX, EXAT, PX, PXAT | Same as in EXHSET. |
VER version | Same optimistic concurrency behavior as in EXHSET. |
ABS version | Sets the version to an exact value regardless of the current version. |
MIN minval | Minimum allowed value. Returns an error if the result would be less than minval. |
MAX maxval | Maximum allowed value. Returns an error if the result would exceed maxval. |
KEEPTTL | Preserves the field's current expiration. Same behavior as in EXHSET. |
After you set a timeout for a field, running EXHINCRBYFLOAT again without a timeout option clears the expiration (unless you use KEEPTTL).Return values
| Value | Meaning |
|---|---|
| Floating-point string | The new value after the increment. |
Example
EXHMSET myhash field1 10
EXHINCRBYFLOAT myhash field1 9.235"19.235"EXHGETWITHVER
| Syntax | EXHGETWITHVER key field |
|---|---|
| Time complexity | O(1) |
| Description | Gets the value and version number of a field. Returns nil if the key or field does not exist. |
Return values
| Value | Meaning |
|---|---|
Array of [value, version] | The field exists. |
nil | The key or field does not exist. |
Example
EXHGETWITHVER myhash field11) "19.235"
2) (integer) 5EXHMGET
| Syntax | EXHMGET key field [field ...] |
|---|---|
| Time complexity | O(1) |
| Description | Gets the values of multiple fields. Returns nil for fields that do not exist. |
Return values
| Value | Meaning |
|---|---|
nil | The key does not exist. |
| Array of values | One element per requested field; nil for non-existent fields. |
Example
EXHMSET myhash field1 10 field2 var1
EXHMGET myhash field1 field21) "10"
2) "var1"EXHMGETWITHVER
| Syntax | EXHMGETWITHVER key field [field ...] |
|---|---|
| Time complexity | O(1) |
| Description | Gets the values and version numbers of multiple fields. Returns nil for fields that do not exist. |
Return values
| Value | Meaning |
|---|---|
nil | The key does not exist. |
Array of [value, version] pairs | One element per requested field; nil for non-existent fields. |
Example
EXHMSET myhash field1 10 field2 var1
EXHMGETWITHVER myhash field1 field21) 1) "10"
2) (integer) 1
2) 1) "var1"
2) (integer) 1EXHLEN
| Syntax | EXHLEN key [NOEXP] |
|---|---|
| Time complexity | O(1) without NOEXP; O(N) with NOEXP |
| Description | Gets the number of fields in the key. By default, includes fields that have expired but not yet been deleted. Use NOEXP to count only non-expired fields. |
Options
| Option | Description |
|---|---|
NOEXP | Traverses the entire key and filters out expired fields before counting. Note that NOEXP filters fields from the count but does not evict them. Response time scales with key size. |
Return values
| Value | Meaning |
|---|---|
| Integer | Number of fields (may include expired-but-not-deleted fields without NOEXP). |
0 | The key does not exist. |
Example
EXHLEN myhash(integer) 2EXHEXISTS
| Syntax | EXHEXISTS key field |
|---|---|
| Time complexity | O(1) |
| Description | Checks whether a field exists in the key. |
Return values
| Value | Meaning |
|---|---|
1 | The field exists. |
0 | The key or field does not exist. |
Example
EXHEXISTS myhash field1(integer) 1EXHSTRLEN
| Syntax | EXHSTRLEN key field |
|---|---|
| Time complexity | O(1) |
| Description | Gets the length of a field's value string. |
Return values
| Value | Meaning |
|---|---|
| Positive integer | The string length. |
0 | The key or field does not exist. |
Example
EXHSTRLEN myhash field1(integer) 2EXHKEYS
| Syntax | EXHKEYS key |
|---|---|
| Time complexity | O(N) |
| Description | Gets all fields in the key. |
Return values
| Value | Meaning |
|---|---|
| Array of field names | The key exists. |
| Empty array | The key does not exist. |
Example
EXHMSET myhash field1 10 field2 var1
EXHKEYS myhash1) "field1"
2) "field2"EXHVALS
| Syntax | EXHVALS key |
|---|---|
| Time complexity | O(N) |
| Description | Gets all field values in the key. |
Return values
| Value | Meaning |
|---|---|
| Array of values | The key exists. |
| Empty array | The key does not exist. |
Example
EXHMSET myhash field1 10 field2 var1
EXHVALS myhash1) "10"
2) "var1"EXHGETALL
| Syntax | EXHGETALL key |
|---|---|
| Time complexity | O(N) |
| Description | Gets all fields and their values in the key. The response alternates between field names and values. |
Return values
| Value | Meaning |
|---|---|
| Array of field-value pairs | The key exists. |
| Empty array | The key does not exist. |
Example
EXHMSET myhash field1 10 field2 var1
EXHGETALL myhash1) "field1"
2) "10"
3) "field2"
4) "var1"EXHSCAN
| Syntax | EXHSCAN key op subkey [MATCH pattern] [COUNT count] |
|---|---|
| Time complexity | O(1) per call; O(N) for a full traversal |
| Description | Scans the key iteratively and returns a cursor and a batch of field-value pairs. Memory-optimized instances only. |
Options
| Option | Description |
|---|---|
key | The TairHash key. |
op | Starting position of the scan. See valid values below. |
subkey | Reference field used with op. Ignored when op is ^ or $. |
MATCH pattern | Filters results by a regular expression pattern applied to field names. |
COUNT count | Number of fields to scan per call. Defaults to 10. The actual number of results may differ depending on the key size and whether MATCH is applied. |
Valid `op` values
| Value | Starting position |
|---|---|
> | First field greater than subkey |
>= | First field greater than or equal to subkey |
< | First field less than subkey |
<= | First field less than or equal to subkey |
== | First field equal to subkey |
^ | First field in the key |
$ | Last field in the key |
Return values
The response is an array of two elements:
The starting field for the next scan call. Empty when the scan is complete.
The scanned fields and their values, interleaved as
[field, value, field, value, ...].
Returns an empty array if the key does not exist.
Example
EXHMSET myhashkey field1 val1 field2 val2 field3 val3 field4 val4 field5 val5
EXHSCAN myhashkey ^ xx COUNT 31) "field4"
2) 1) "field1"
2) "val1"
3) "field2"
4) "val2"
5) "field3"
6) "val3"The next scan starts from field4. Pass field4 as subkey with op >= to continue.
EXHDEL
| Syntax | EXHDEL key field [field ...] |
|---|---|
| Time complexity | O(1) |
| Description | Deletes one or more fields from the key. |
Return values
| Value | Meaning |
|---|---|
1 | The field was deleted. |
0 | The key or field does not exist. |
Example
EXHDEL myhash field1(integer) 1FAQ
Why does exHash use more memory than a standard Redis hash for the same data?
Each field in TairHash stores additional metadata — the expiration timestamp and version number — that a standard Redis hash does not have. This extra per-field metadata is the source of the higher memory usage.