7 questions foundWhy would you use a Lua script with Redis instead of just sending several separate commands from your application?
Beginner A Lua script runs entirely on the Redis server as a single atomic operation, meaning no other client's commands can run in between the individual steps of your script, which both guarantees consistency for multi step logic and reduces network round trips compared to sending several separate commands back and forth between your application and Redis.
EVAL "return redis.call('set', KEYS[1], ARGV[1])" 1 mykey myvalue
Real-world example A ticket booking system uses a Lua script to atomically check available seats and reserve one in a single operation, preventing a race condition where two customers might otherwise both believe they successfully booked the very last seat.
Common follow-ups: What does the atomicity guarantee of a Lua script actually protect against?;What is the difference between EVAL and EVALSHA?
Transactions;Distributed Locks with Redis
How do you pass keys and other arguments into a Lua script when executing it with the EVAL command?
Beginner You specify the actual key names as a group after the script text, preceded by a count of how many keys you are passing, followed by any additional argument values, and within the script itself you access these using the KEYS and ARGV tables, which is the recommended way to reference keys so Redis Cluster can correctly route the script to the right node.
EVAL "return redis.call('set', KEYS[1], ARGV[1])" 1 'mykey' 'myvalue'
Real-world example A rate limiting script receives the specific key to check as KEYS[1] and the maximum allowed requests as ARGV[1], keeping the script generic and reusable across many different rate limited resources.
Common follow-ups: Why should key names always be passed through KEYS rather than hardcoded in the script?;What happens if you provide the wrong number for the key count argument?
Rate Limiting with Redis;Cluster Sharding & Hash Slots
What is the difference between EVAL and EVALSHA, and why would you use EVALSHA in a production application?
Intermediate EVAL sends the full text of the Lua script to Redis every single time it runs, while EVALSHA sends only a hash identifier of a script that has already been loaded and cached on the server beforehand, which reduces network bandwidth usage since you avoid repeatedly transmitting the same script text for every single execution.
SCRIPT LOAD "return redis.call('get', KEYS[1])"
-- returns a SHA hash
EVALSHA 'e0e1f9fabfc9d4800c877a703b823ac0578ff831' 1 mykey
Real-world example A high traffic application loads its frequently used Lua scripts once at startup, then calls them repeatedly using EVALSHA, saving meaningful network bandwidth compared to sending the full script text with every single call.
Common follow-ups: What happens if you call EVALSHA with a hash for a script that has not actually been loaded?;How long does Redis keep a loaded script cached?
Redis Performance Tuning & Benchmarking;Redis CLI & Basic Commands
How do you call other Redis commands from within a Lua script, and what restrictions apply to this?
Intermediate You call other Redis commands from within a Lua script using the redis.call or redis.pcall functions, passing the command name and its arguments, and while you have access to most standard Redis commands this way, certain commands that could introduce non determinism or block the server for a long time are restricted or behave differently within a script's context.
local current = redis.call('get', KEYS[1])
if current == false then
redis.call('set', KEYS[1], ARGV[1])
end
Real-world example An inventory management script checks whether a product's stock key already exists using redis.call, only initializing it with a default value if it does not already exist, all within a single atomic script execution.
Common follow-ups: What is the difference between redis.call and redis.pcall for error handling?;What Redis commands are restricted from being used inside a Lua script?
Transactions;Distributed Locks with Redis
How would you write a Lua script to implement an atomic rate limiter that checks and increments a request counter in a single operation?
Advanced You write a script that increments a counter for the specific rate limited key, sets an expiration on it only if this is the very first request within the current time window, checks if the incremented count exceeds your configured limit, and returns whether the current request should be allowed or rejected, all as a single atomic operation that avoids race conditions between the check and the increment.
local current = redis.call('incr', KEYS[1])
if current == 1 then
redis.call('expire', KEYS[1], ARGV[1])
end
if current > tonumber(ARGV[2]) then
return 0
end
return 1
Real-world example An API gateway uses this kind of atomic Lua script to enforce a rate limit of one hundred requests per minute per customer, guaranteeing accurate enforcement even under extremely high concurrent request volume.
Common follow-ups: Why would this rate limiting logic be unsafe if implemented as several separate Redis commands instead of one script?;How do you adjust this script to support a sliding window rather than a fixed window?
Rate Limiting with Redis;Redis Performance Tuning & Benchmarking
What are the performance and blocking implications of running a Lua script in Redis, especially for a script that takes a long time to execute?
Advanced Since Redis processes commands using a single main thread, a Lua script runs to completion before Redis can process any other client's commands, meaning a slow or inefficient script can block the entire server and delay every other operation, making it important to keep scripts fast, avoid unbounded loops over large datasets, and thoroughly test script performance before deploying it to production.
-- A script that loops over a very large dataset
-- can block the entire Redis server while it runs
for i = 1, 1000000 do
redis.call('set', 'key' .. i, 'value')
end
Real-world example A team accidentally deployed a Lua script that looped over a very large dataset, briefly freezing their entire Redis instance and affecting every other application sharing that server, prompting them to add stricter script performance review to their deployment process.
Common follow-ups: How do you measure how long a specific Lua script takes to execute before deploying it?;What configuration options exist to limit how long a script is allowed to run?
Redis Performance Tuning & Benchmarking;Redis Monitoring & Observability
How do you manage and organize Lua scripts in a larger application to keep them maintainable as your codebase grows?
Intermediate You would typically store each script in its own separate file with clear naming, load and cache their SHA hashes once at application startup, document each script's purpose, expected keys, and arguments clearly, and consider version controlling them alongside your application code just like any other important piece of business logic.
-- rate_limiter.lua
local current = redis.call('incr', KEYS[1])
-- Load once at startup and reuse the returned SHA
const sha = await redis.script('load', luaScriptText);
Real-world example A development team keeps all their Lua scripts organized in a dedicated folder within their codebase, each with clear documentation explaining its purpose, making it easy for new team members to understand and safely modify this critical server side logic.
Common follow-ups: What testing strategies work well for validating Lua script behavior before deployment?;How do you handle updating a Lua script that is already cached and in active use?
Distributed Locks with Redis;Rate Limiting with Redis