String
In Valkey, strings are one of the most common types of data stored. You can think of a string as a simple piece of text or numbers, stored under a unique key. A key is a unique identifier, and the string is the value linked to that unique identifier.
Strings can hold text, numbers, or even binary data (like images), but for simplicity, we'll focus on text and numbers here!
Let's understand the different commands and options in the following order:
- Creating strings
- Editing strings
- Reading strings
- Deleting strings
SET
It assigns a value to a key.
Warning
- If the key already exists, the command will overwrite the existing value.
- If the key doesn't exist, it will create the key with the specified value.
Example
Imagine you have a wallet balance system for a user named Ram.
Initially, when Ram's wallet doesn't exist, we create it with an initial balance of 0
. Using the SET command:
SET wallet:ram:savings:balance 0
wallet:ram:savings:balance
with the value 0
. Later, Ram makes a deposit of 500
. To reflect the new balance, we use the SET command again:
SET wallet:ram:savings:balance 500
wallet:ram:savings:balance
from 0
to 500
, reflecting the new balance after the deposit. Time Complexity - O(1)
Whether you're setting a small string or a large binary object, the time complexity remains constant as Valkey simply inserts or updates the key in its internal data structure (a hash table).
Code Snippet
SETNX
It works similarly to SET command, but with a key difference: it only sets a value if the key does not already exist.
This makes it useful for ensuring that a value is only set once, avoiding overwriting existing data.
In short, it’s Set if not exist.
Example
Let’s assume you have a wallet balance system for a user named Ram. Ram wants to create a new account, but to ensure security, the system needs to check if an account already exists with the same username. If it doesn’t, the account will be created with an initial balance of 0.
SETNX wallet:ram:savings:balance 0
This command will create the key wallet:ram:savings:balance
with the value 0
only if the key doesn’t already exist. If the key exists, the command will do nothing, ensuring that Ram’s account is created only once.
Time Complexity - O(1)
Whether you're setting a small string or a large binary object, the time complexity remains constant as Valkey simply inserts or updates the key in its internal data structure (a hash table).
Code Snippet
SETEX
It works similarly to SET command, but extends it by adding an expiration time in seconds.
In short, it’s Set with Expiry.
Example
Let’s assume you have a wallet balance system for a user named Ram. Ram wants to make a transaction, but to ensure security, the system sends a one-time passcode (OTP) to Ram’s registered mobile number or email address. The OTP will expire after 10 seconds.
SETEX wallet:ram:txn:123:otp 10 GH4-S6N-X0C
This command will create the key wallet:ram:txn:123:otp
with the value GH4-S6N-X0C
which expires after 10
seconds.
Time Complexity - O(1)
Whether you're setting a small string or a large binary object, the time complexity remains constant as Valkey simply inserts or updates the key in its internal data structure (a hash table).
Code Snippet
SETRANGE
The SETRANGE command is used to overwrite a portion of a string stored at a specific key starting from a specified offset. It modifies the string by replacing part of it with a new value.
Example
Imagine you have a wallet balance system for a user named Ram.
During the creation of Ram’s account, there was an error in setting the wallet balance, and it was mistakenly set in USD instead of the INR.
SET wallet:ram:savings:balance "500 USD"
After approval, the system needs to correct the wallet balance and change it from USD to INR. We can do this by starting at offset 4 (the position of U in USD) and replacing "USD" with "INR":
SETRANGE wallet:ram:savings:balance 4 "INR"
Now, the balance is correctly updated to INR, reflecting the approved correction.
Code Snippet
MSET
It works similarly to SET command, but it allows you to set multiple key-value pairs at once.
In short, it stands for Multiple Set.
Warning
- If the key already exists, the command will overwrite the existing value.
- If the key doesn't exist, it will create the key with the specified value.
Example
Let’s assume you have a wallet balance system for a user named Ram. Ram wants to create a new account with the net banking feature enabled. To ensure security, the system needs to hold information such as balance
, netbanking_enabled
, logged_in
, login_count
, and logout_count
.
You can use the MSET
command like this:
MSET wallet:ram:savings:balance 0 wallet:ram:netbanking_enabled true wallet:ram:logged_in false wallet:ram:login_count 0 wallet:ram:logout_count 0
This command will create multiple keys for Ram's account:
wallet:ram:savings:balance
with the value0
wallet:ram:netbanking_enabled
with the valuetrue
wallet:ram:logged_in
with the valuefalse
wallet:ram:login_count
with the value0
wallet:ram:logout_count
with the value0
All these keys will be set at once, making it efficient to create Ram’s account with all the necessary information.
Time Complexity - O(N)
The time complexity for the MSET command is O(N), where N is the number of key-value pairs being set.
This means that the time it takes to execute the command increases with the number of keys you are setting, as Valkey processes each key-value pair individually.
Code Snippet
MSETNX
It works similarly to MSET command, but with an important difference: it allows you to set multiple key-value pairs at once only if none of the specified keys already exist.
If any of the keys already exist, the command will not set any of the keys.
In short, it stands for Multiple Set if not exist.
Example
Let’s say you have a wallet balance system for a user named Ram. You want to create a new account for Ram, but you want to ensure that the account is only created if it doesn’t already exist. You need to store information such as balance
, netbanking_enabled
, logged_in
, login_count
, and logout_count
.
You can use the MSETNX
command like this:
MSETNX wallet:ram:savings:balance 0 wallet:ram:netbanking_enabled true wallet:ram:logged_in false wallet:ram:login_count 0 wallet:ram:logout_count 0
This command will create multiple keys for Ram's account:
wallet:ram:savings:balance
with the value0
wallet:ram:netbanking_enabled
with the valuetrue
wallet:ram:logged_in
with the valuefalse
wallet:ram:login_count
with the value0
wallet:ram:logout_count
with the value0
If none of these keys already exist, all of them will be set at once. However, if any of these keys already exist, the command will not set any of the keys, and it will return 0
to indicate that the operation was not successful.
Time Complexity - O(N)
The time complexity for the MSET command is O(N), where N is the number of key-value pairs being set.
This means that the time it takes to execute the command increases with the number of keys you are setting, as Valkey processes each key-value pair individually.
Code Snippet
PSETEX
It is similar to the SETEX command, but it allows you to set a key with a specified value and an expiration time in milliseconds instead of seconds.
Example
Let’s assume you have a wallet balance system for a user named Ram. Ram wants to make a transaction, but to ensure security, the system sends a one-time passcode (OTP) to Ram’s registered mobile number or email address. The OTP will expire after 10000
milliseconds.
SETEX wallet:ram:txn:123:otp 10000 GH4-S6N-X0C
This command will create the key wallet:ram:txn:123:otp
with the value GH4-S6N-X0C
which expires after 10000
milliseconds, or in simpler terms, in 10 seconds.
Time Complexity - O(1)
Whether you're setting a small string or a large binary object, the time complexity remains constant as Valkey simply inserts or updates the key in its internal data structure (a hash table).
Code Snippet
GETSET
It sets a new value for a specified key and returns the old value stored at that key.
This command is atomic, meaning that it guarantees that the old value is returned before the new value is set, making it useful in scenarios where you need to read and update a value in a single operation.
Syntax
GETSET key value
- key: The key for which you want to set a new value.
- value: The new value to be set for the specified key.
Example
Let’s say you have a wallet balance system for a user named Ram, and you want to update Ram's wallet balance after a transaction. You need to retrieve the current balance and then set a new balance based on a transaction (e.g., adding funds).
You can use the GETSET
command like this:
GETSET wallet:ram:savings:balance 100
This command sets wallet:ram:savings:balance
to 100
and returns the old value, which is 0.
Time Complexity - O(1)
The time complexity of the GETSET command is O(1), which means it operates in constant time regardless of the size of the data being handled.
Code Snippet
INCR
It increments the integer value of a specified key by one. If the key does not exist, it is set to 0 before performing the operation.
Syntax
INCR key
- key: The key whose value you want to increment.
Example
Let’s say you have a wallet balance system for a user named Ram and have a counter for the number of logins.
You can use the INCR
command like this:
INCR wallet:ram:login_count
user:ram:login_count
by 1
Time Complexity - O(1)
The time complexity of the INCR
command is O(1), which means it operates in constant time.
Code Snippet
INCRBY
It increments the integer value of a specified key by a specified amount.
If the key does not exist, it is set to 0 before performing the operation.
Syntax
INCRBY key increment
- key: The key whose value you want to increment.
- increment: The amount by which to increment the value.
Example
Continuing with the wallet balance system for Ram, you want to add a specific amount to his balance.
INCRBY wallet:ram:savings:balance 50
This command increments wallet:ram:savings:balance
from 100
to 150
.
Time Complexity - O(1)
The time complexity of the INCRBY
command is O(1), which means it operates in constant time.
Code Snippet
INCRBYFLOAT
It increments the float value of a specified key by a given amount.
If the key does not exist, it is set to 0.0 before performing the operation.
Syntax
INCRBYFLOAT key increment
Example
Let’s say you want to update Ram's wallet balance with a fractional amount.
INCRBYFLOAT wallet:ram:savings:balance 0.50
This command increments wallet:ram:savings:balance
from 100.00
to100.50
.
Time Complexity - O(1)
The time complexity of the INCRBYFLOAT
command is O(1), which means it operates in constant time.
Code Snippet
DECR
It decrements the integer value of a specified key by one.
If the key does not exist, it is set to 0 before performing the operation.
Syntax
DECR key
- key: The key whose value you want to decrement.
Example
Let’s say you want to deduct 1
as monthly SMS charges for Ram.
DECR wallet:ram:savings:balance
This command decrements wallet:ram:savings:balance
by 1
.
Time Complexity - O(1)
The time complexity of the DECR
command is O(1), which means it operates in constant time.
Code Snippet
DECRBY
It decrements the integer value of a specified key by a given amount.
If the key does not exist, it is set to 0 before performing the operation.
Syntax
DECRBY key decrement
- key: The key whose value you want to decrement.
- decrement: The amount by which to decrement the value.
Example
Continuing with the wallet balance system, you want to deduct a specific integer amount for SMS charges for Ram.
DECRBY wallet:ram:savings:balance 2
This command decrements wallet:ram:savings:balance
by 2
.
Time Complexity - O(1)
The time complexity of the DECRBY
command is O(1), which means it operates in constant time.
Code Snippet
APPEND
This command is used to add (or append) data to the end of the existing value stored at a specific key.
Warning
- If the key already exists, the command will append the given value to the existing value.
- If the key doesn’t exist, it will create the key and set the value as the appended string.
Example
Let’s assume you have a wallet balance system for a user named Ram.
Ram is keeping track of his transactions, and every time he makes a deposit or withdrawal, you append the details of each transaction to a log stored in Valkey.
-
Ram deposits ₹1000 on March 4, 2025, and you use the APPEND command to log the transaction under the key
wallet:ram:transactions:2025-03
.At this point, the keyAPPEND wallet:ram:transactions:2025-03 "Deposit: ₹1000 on 04-Mar-2025; "
wallet:ram:transactions:2025-03
will store:"Deposit: ₹1000 on 04-Mar-2025; "
-
On March 5, 2025, Ram withdraws ₹500, and you append this new transaction to the existing record:
The value of the keyAPPEND wallet:ram:transactions:2025-03 "Withdrawal: ₹500 on 05-Mar-2025; "
wallet:ram:transactions:2025-03
will now contain:"Deposit: ₹1000 on 04-Mar-2025; Withdrawal: ₹500 on 05-Mar-2025; "
-
Ram deposits ₹2000 on March 6, 2025, and this transaction is also appended:
APPEND wallet:ram:transactions:2025-03 "Deposit: ₹2000 on 06-Mar-2025; "
After this, the key
wallet:ram:transactions:2025-03
will store:"Deposit: ₹1000 on 04-Mar-2025; Withdrawal: ₹500 on 05-Mar-2025; Deposit: ₹2000 on 06-Mar-2025; "
Time Complexity - O(1)
The operation executes in constant time, meaning the time to append data is unaffected by the size of the string or the number of characters being appended.
Valkey appends the value to the end of the stored string in constant time.
Code Snippet
GET
This command retrieves the value stored at a given key.
Warning
- If the key does not exist, it will return nil.
- If you try to retrieve a non-string value with GET, it will return an error.
Example
Imagine you have a wallet balance system for a user named Ram.
Continuing with the wallet balance system, you might want to retrieve the current balance for a user named Ram.
GET wallet:ram:savings:balance
wallet:ram:savings:balance
. Time Complexity - O(1)
The time complexity is O(1), meaning it takes constant time regardless of the length of the stored value. Valkey simply retrieves the value from its internal hash table.
Code Snippet
GETEX
This command retrieves the value of a key and optionally sets its expiration time.
It's similar to GET, but also allows you to define an expiration time or modify the time to live (TTL) of the key.
Info
Just using GETEX on a key will not expire the key. You must use it with specific expiration options to set or update the TTL.
The expiration options are as follows:
- EX seconds: Set the specified expiration time in seconds.
- PX milliseconds: Set the specified expiration time in milliseconds.
- EXAT timestamp-seconds: Set the Unix timestamp (seconds) at which the key will expire.
- PXAT timestamp-milliseconds: Set the Unix timestamp (milliseconds) at which the key will expire.
Example
Imagine you're using Valkey to store OTP (One-Time Password) codes for users. Each OTP has a limited validity period (e.g., 5 minutes), and once it's used or expired, it should be removed automatically.
Let’s say you want to retrieve the OTP for a user named Ram, while ensuring that the OTP expires after 1 minute (60 seconds):
GETEX wallet:ram:txn:123:otp EX 60
This command:
- Retrieves the OTP stored under
wallet:ram:txn:123:otp
- Sets its expiration to 1 minute from now.
- After 1 minute, the OTP will automatically be removed from Valkey.
You could also specify the expiration time in milliseconds using the PX
option:
GETEX wallet:ram:txn:123:otp EX 60000
Alternatively, if you want to set the expiration to a specific Unix timestamp, use EXAT
or PXAT
:
GETEX wallet:ram:txn:123:otp EXAT 1743465599
GETEX wallet:ram:txn:123:otp PXAT 1743465599000
This will set the expiration for the key at the Unix timestamp 1743465599
in seconds or 1743465599000
in milliseconds, which corresponds to Monday, 31 March 2025, 11:59:59 PM UTC.
Time Complexity - O(1)
The time complexity is O(1) for the retrieval and expiration setting. Valkey simply retrieves the value and updates the expiration time in constant time.
Code Snippet
MGET
The MGET command is used to retrieve multiple keys at once in a single operation. It returns the values of all the specified keys, or nil if a key does not exist.
Example
Let’s assume Ram has multiple types of bank accounts: Savings Account, Current Account, and Fixed Deposit Account. You want to check the balance of these accounts in one go.
We first create three keys for Ram’s different accounts and set their respective balances:
SET wallet:ram:current:balance "1000"
SET wallet:ram:fd:balance "2000"
Now, to retrieve the balances for Ram’s savings account, current account, and fixed deposit account, we use MGET
:
MGET wallet:ram:savings:balance wallet:ram:current:balance wallet:ram:fd:balance
wallet:ram:rd:balance
), it would return nil for that account. Time Complexity - O(N)
The time complexity of the MGET command is O(N), where N is the number of keys being retrieved.
The complexity is linear with respect to the number of keys you query, as Valkey needs to fetch the values for all those keys in one go.
Code Snippet
GETRANGE
The GETRANGE command is used to retrieve a substring of the value stored at a given key, starting from a specified offset to an end offset.
It allows you to extract a portion of a string, making it useful for situations where you need to access only part of the data.
Example
Imagine you have a wallet balance system for a user named Ram.
Continuing with the wallet balance system for Ram and the example of SETRANGE let's say the value stored in wallet:ram:savings:balance
is: 500 INR
Now, if you want to extract the currency type (INR) from the wallet balance, you can use the GETRANGE command. Since the currency type "INR" starts at position 4 in the string "500 INR", you can retrieve it by specifying the range from offset 4 to offset 6 (inclusive).
GETRANGE wallet:ram:savings:balance 4 6
This command will return INR
.
Time Complexity - O(N)
The time complexity of GETRANGE is O(N), where N is the length of the substring being retrieved.
Code Snippet
STRLEN
This command is used to retrieve the length of the string value stored at a given key.
Example
Imagine you have a wallet balance system for a user named Ram, which has balance value as 500 INR
.
Now, if you want to check the length of the value stored in walletsavings:balance, you can use the STRLEN command to find out the number of characters in the string.
STRLEN wallet:ram:savings:balance
7
. Time Complexity - O(1)
The time complexity of STRLEN is O(1), meaning it takes constant time to retrieve the length of the string, regardless of the size of the string.
Valkey simply calculates and returns the length of the string in constant time.
Code Snippet
SUBSTR
Extracts a specific portion of a string stored in a key and returns it.
Example
Let's take a wallet balance as an example, where a user's wallet information contains both the balance and the currency code.
Let's say we have a key called wallet:ram
, and its value is 100.00 INR
. This value contains the amount 100.00
and the currency code INR
. Now, we want to extract the currency code INR
from this string.
substr wallet:ram -3 -1
where:
-3
is the start index (referring to the third character from the end, which is I).-1
is the end index (referring to the last character, which is R).
Time Complexity - O(N)
The time complexity is proportional to the length of the specific portion of a string that is being extracted (i.e., the difference between the start and end indices).
If the substring is small or close to the full length of the string, Valkey has to process a larger part of the string, resulting in a larger complexity.
Code Snippet
LCS
This command is used to find the longest common subsequence between two strings.
It identifies the longest sequence of characters that appear in both strings in the same order, though not necessarily contiguous. This makes it useful for detecting similarities between two texts, even if they are not identical.
Example
Imagine you are reviewing business loan applications for a user named Ram and another applicant, Chotu. Both have submitted loan application letters explaining why they need the loan for their business. You want to compare both letters to check for potential plagiarism or similarity in their business plans.
Ram’s Loan Application Letter:
"I am seeking a loan for my small retail store. The loan will be used to expand the business, purchase inventory, and increase working capital. My business has been running for three years and has shown steady growth."
Chotu’s Loan Application Letter:
"I am applying for a loan to expand my retail business. The loan will help me buy inventory and increase the store’s working capital. My store has been in operation for three years, showing consistent growth."
Both letters look quite similar, and you suspect that one of the applicants may have plagiarized content. You can use the LCS command to find the longest common subsequence between the two letters.
LCS loan:ram:application:letter loan:chotu:application:letter
Result:
"I am ing a loan o m retail se. The loan will ep e bu inventory and increase working capital. My se has been nin for three years shown ste growth."
The result returned by LCS highlights the common portion between the two letters, helping the underwriting team determine whether the letter was plagiarized and whether it should be flagged for fraud or require resubmission.
Options
If you only want to know the length of the longest common subsequence, you can use the LEN option.
LCS loan:ram:application:letter loan:chotu:application:letter LEN
This will return the length of the common subsequence, which in this case is 146
characters long.
If you're interested in the indexes of the matches in both strings (i.e., where the common subsequence appears in each of the original strings), use the IDX option.
LCS loan:ram:application:letter loan:chotu:application:letter IDX
If you want to filter out smaller matches, you can set a minimum match length. This can help you focus only on the larger subsequences, ignoring smaller matches that may not be significant.
LCS loan:ram:application:letter loan:chotu:application:letter IDX MINMATCHLEN 20
Finally, if you want both the subsequences and their lengths, you can use the WITHMATCHLEN option.
LCS loan:ram:application:letter loan:chotu:application:letter IDX MINMATCHLEN 20 WITHMATCHLEN
This result includes both the matches (indices) and the length of the common subsequence.
Time Complexity - O(N * M)
The time complexity of LCS is O(N * M), where N and M are the lengths of the two strings being compared.
This means that the comparison grows with the product of the lengths of the two strings. While it works well for smaller strings, comparing larger documents might take more time.
Code Snippet
GETDEL
This command retrieves the value of a key and simultaneously deletes the key from the database.
Example
Let’s assume you have a wallet balance system for a user named Ram.
Ram wants to make a transaction, but to ensure security, the system sends a one-time passcode (OTP) to Ram’s registered mobile number or email address.
The OTP is initially set to expire after 10 seconds to ensure it's used quickly. However, to prevent any chance of the OTP being reused after successful verification, you want the OTP to expire immediately after it is used, rather than letting it persist for the remaining time.
GETDEL wallet:ram:txn:123:otp
- Retrieves the OTP value stored under
wallet:ram:txn:123:otp
(e.g., "987654"). - Deletes the key
wallet:ram:txn:123:otp
from Valkey, ensuring that the OTP is not used again.
Time Complexity - O(1)
The time complexity is O(1) for the retrieval and deletion operation. It retrieves the value and removes the key in constant time.
Code Snippet