Transactions vs Lua scripts in Redis - Performance Comparison
We want to understand how the time cost changes when using Redis transactions compared to Lua scripts.
How does the number of operations grow as we handle more commands inside these two methods?
Analyze the time complexity of these Redis commands.
MULTI
SET key1 value1
SET key2 value2
SET key3 value3
EXEC
-- vs --
EVAL "redis.call('SET', KEYS[1], ARGV[1]); redis.call('SET', KEYS[2], ARGV[2]); redis.call('SET', KEYS[3], ARGV[3]);" 3 key1 key2 key3 value1 value2 value3
The first snippet uses a transaction with multiple commands queued and executed together. The second uses a Lua script to run the same commands atomically.
Look at what repeats inside each method.
- Primary operation: Setting keys with SET commands.
- How many times: Three times in both cases.
- In transactions, commands are queued then executed in one batch.
- In Lua scripts, commands run inside the script without network round trips.
As the number of commands increases, the total work grows.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 SET commands executed |
| 100 | About 100 SET commands executed |
| 1000 | About 1000 SET commands executed |
Pattern observation: The number of commands grows linearly with input size, so total work grows linearly too.
Time Complexity: O(n)
This means the time to complete grows in direct proportion to the number of commands you run.
[X] Wrong: "Lua scripts always run faster than transactions because they are scripts."
[OK] Correct: Both run commands one after another, so time grows with command count. Lua scripts reduce network trips but do not change the total command work.
Understanding how Redis handles multiple commands helps you explain performance trade-offs clearly and shows you know how to reason about scaling operations.
What if we replaced multiple SET commands with a single Lua script that uses a loop to set keys? How would the time complexity change?
Practice
Solution
Step 1: Understand Redis transactions
Transactions group multiple commands to run atomically, meaning all commands succeed or none do.Step 2: Understand Lua scripts in Redis
Lua scripts run inside Redis and can include complex logic, running atomically as a single operation.Final Answer:
Transactions group commands to run atomically, Lua scripts run complex logic atomically inside Redis. -> Option BQuick Check:
Transactions vs Lua scripts = Grouped commands vs complex logic [OK]
- Thinking Lua scripts run outside Redis
- Believing transactions can only read or write
- Assuming transactions are always faster
Solution
Step 1: Recall Redis transaction commands
Redis uses the command MULTI to start a transaction block.Step 2: Identify the correct command
START TRANSACTION and BEGIN are SQL commands, not Redis. EXEC ends the transaction.Final Answer:
MULTI -> Option DQuick Check:
Start Redis transaction = MULTI [OK]
- Using SQL commands like START TRANSACTION
- Confusing EXEC as start command
- Using BEGIN which is not Redis syntax
local current = redis.call('GET', KEYS[1])
if not current then
redis.call('SET', KEYS[1], ARGV[1])
return ARGV[1]
else
return current
end
What will be the output if the key does not exist and ARGV[1] is "100"?Solution
Step 1: Analyze the Lua script logic
The script checks if the key exists. If not, it sets the key to ARGV[1] and returns ARGV[1].Step 2: Apply the input values
Since the key does not exist, it sets the key to "100" and returns "100".Final Answer:
"100" -> Option CQuick Check:
Key missing sets and returns ARGV[1] = "100" [OK]
- Assuming nil is returned when key missing
- Expecting an error from redis.call
- Confusing return values with zero
MULTI SET key1 foo INCR key1 EXECBut the INCR command fails with an error. What is the likely cause?
Solution
Step 1: Understand SET and INCR behavior
SET stores the value as a string. INCR expects the key to hold an integer value.Step 2: Identify the error cause
Since SET sets "foo" as a string, INCR fails because it cannot increment a non-integer string.Final Answer:
SET sets key1 as a string, INCR expects an integer value -> Option AQuick Check:
INCR needs integer, SET stores string [OK]
- Thinking INCR can't be in MULTI
- Forgetting to EXEC the transaction
- Assuming MULTI syntax is wrong
Solution
Step 1: Understand the atomicity requirement
The operation must be atomic: check existence and update in one step without race conditions.Step 2: Compare approaches
Transactions with WATCH can be complex and may fail due to race conditions. Separate commands or pipelines are not atomic. Lua scripts run atomically inside Redis and can handle logic safely.Final Answer:
Use a Lua script that checks and updates the key atomically -> Option AQuick Check:
Atomic check and update = Lua script [OK]
- Assuming WATCH transactions are always safe
- Using separate commands risking race conditions
- Confusing pipelines with atomic execution
Ready to prove it?
Pass the test and this pattern moves unknown
