Use SET to store a string value at a key, replacing whatever was there before, whatever its type.
By default the value is written unconditionally and the key's previous time to live is discarded. KEEPTTL preserves it, while EX, PX, EXAT, and PXAT attach a new lifetime in seconds or milliseconds, or an absolute deadline as a Unix timestamp. Setting the value and its expiration in one command is what keeps a key from ever existing without one.
The condition decides whether the write happens at all. NX writes only when the key does not exist, which combined with an expiration is the standard way to acquire a lock, and XX writes only when it already exists, which refreshes a value without creating it. IFEQ and IFNE compare the current value with the one you supply, and IFDEQ and IFDNE compare its digest as returned by DIGEST, so a large value can be checked without sending it; these conditional forms are implemented by this Upstash deployment and give you compare-and-set semantics in a single command. IFEQ and IFDEQ require the key to exist, while IFNE and IFDNE also write when it does not.
GET makes the reply the previous value instead of OK, which is how you swap a value and read what it replaced in one atomic step. When a condition prevents the write, the reply is null.
Syntax#
Arguments#
| Argument | Required | Repeatable | Description |
|---|---|---|---|
<key> | Yes | No | Redis key targeted by the command. |
<value> | Yes | No | String value to store. |
(NX | XX | IFEQ <ifeq-value> | IFNE <ifne-value> | IFDEQ <ifdeq-digest> | IFDNE <ifdne-digest>) | No | No | Choose one form: NX (only when the key does not exist); XX (only when it already exists); IFEQ (only when the current value equals <ifeq-value>); IFNE (only when it differs); IFDEQ (only when the current value's digest equals <ifdeq-digest>); IFDNE (only when it differs). |
GET | No | No | Also return the previous value. |
(EX <seconds> | PX <milliseconds> | EXAT <unix-time-seconds> | PXAT <unix-time-milliseconds> | KEEPTTL) | No | No | Choose one form: EX (set a lifetime in seconds); PX (set a lifetime in milliseconds); EXAT (expire at a Unix timestamp in seconds); PXAT (expire at a Unix timestamp in milliseconds); KEEPTTL (preserve the existing key lifetime). |
Important points#
NXandXXare mutually exclusive.- Choose at most one expiration form and at most one condition.
GETchanges a successful reply fromOKto the previous value. IFEQ/IFNEcompare the current value;IFDEQ/IFDNEcompare its digest. These conditional forms are implemented by this Upstash deployment.
Response#
The reply reports the result of the operation. Error replies have the same shape in RESP2 and RESP3 and are surfaced as exceptions by the SDKs below.
| Protocol | Reply |
|---|---|
| RESP2 | Simple string OK; with GET, the previous value as a bulk string, or Null bulk string or null array when the key did not exist or a condition failed |
| RESP3 | Simple string OK; with GET, the previous value as a bulk string, or Null when the key did not exist or a condition failed |
Client libraries often decode bulk strings, maps, sets, and numeric strings into language-native values. The table describes the Redis wire reply.
Examples#
TCP examples use the TLS REDIS_URL from the Upstash console. REST examples use UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN.