EVAL to run a Lua script on the server.
<numkeys> says how many of the arguments that follow are key names. The script receives those in the KEYS table and every remaining argument in ARGV. Passing key names as keys rather than hardcoding them in the script body matters, because Redis uses that list for routing and access checks. Inside the script, redis.call runs Redis commands and its return value is converted to a Lua value.
The script runs as a single atomic step, which makes it the standard way to do read, decide, and write logic, such as a rate limiter or a compare-and-set update, in one round trip and without a transaction. Keep scripts short, since a script that holds the database blocks everything else, and keep them deterministic by deriving values from KEYS, ARGV, or data read inside the script rather than from clock or random sources.
Upstash isolates a script with a lock. By default that is the global lock, because the engine cannot know in advance which keys the script will touch, so no other command runs while the script does. Adding the allow-key-locking flag to the script’s shebang line makes it lock only the keys passed in KEYS instead, so calls that work on disjoint keys run in parallel:
KEYS, and commands that need database-wide access, such as FLUSHDB, are rejected. See Key-Based Locking for the full rules.
Sending a script also caches it under its SHA1 digest, so later calls can use EVALSHA and avoid resending the body. Use EVAL_RO for scripts that only read.
Syntax
Arguments
Important points
numkeysmust equal the number of key arguments that immediately follow it; remaining arguments are available to the script or function as ordinary arguments.- The script takes the global lock unless its shebang sets the
allow-key-lockingflag, in which case it locks only the keys passed inKEYS. See Key-Based Locking. - A script queued inside a
MULTI/EXECtransaction always runs under the global lock, even when it setsallow-key-locking. Call it directly if you want per-key locking. - Pass every key the script touches through
KEYSwhether or notallow-key-lockingis set. A key built inside the script is read from disk under the lock when it is not in memory, and it is rejected outright when the flag is set. See Dynamic Keys and Latency.
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.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 TLSREDIS_URL from the Upstash console. REST examples use UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN.
Redis CLI
Redis CLI
@upstash/redis
@upstash/redis
upstash_redis
upstash_redis
ioredis
ioredis
node-redis
node-redis
redis-py
redis-py
go-redis
go-redis
jedis
jedis
redis-rs
redis-rs