Skip to main content

redis_lua_atomic_operations

🛡️ Atomic Multi-key Operations with Lua Scripts

Leverage Redis' built‑in Lua engine to execute complex, multi‑key operations atomically, avoiding race conditions in high‑concurrency environments. By preloading scripts with SCRIPT LOAD and invoking them via EVALSHA, you minimize network overhead and ensure deterministic execution. This approach is invaluable for token buckets, rate limiters, and distributed locks.

# config/initializers/redis.rb
$redis = Redis.new(url: ENV.fetch("REDIS_URL"))

# lib/redis_scripts.rb
module RedisScripts
LUA_TRANSFER = <<~LUA
local src, dest, amount = KEYS[1], KEYS[2], tonumber(ARGV[1])
if redis.call('GET', src) == false or tonumber(redis.call('GET', src)) < amount then
return {err = 'Insufficient funds'}
end
redis.call('DECRBY', src, amount)
redis.call('INCRBY', dest, amount)
return {ok = 'Transfer complete'}
LUA
SHA_TRANSFER = $redis.script(:load, LUA_TRANSFER)
end

# Usage
result = $redis.evalsha(RedisScripts::SHA_TRANSFER, keys: ["account:1:balance", "account:2:balance"], argv: [100])
puts result # => "Transfer complete"