lua-resty-redis-fast

The use must have the root permission.

Version compatibility

This page preserves installation and usage instructions for the legacy implementation and adds configuration notes for the new implementation targeting Nginx 1.31.8.

ImplementationApplicable versionsStatus and usage
New standalone dynamic moduleNginx 1.31.8 only, bundled with OpenResty 1.31.8.xLoad ngx_redis_fast_module.so; see “New implementation usage” for Lua API changes.
Legacy implementationMatching legacy packages for OpenResty 1.21.4.x, 1.25.3.x, 1.27.1.x, or 1.31.8.xInstallation steps and “Legacy implementation usage” are retained below.

Continue using matching legacy packages with older OpenResty versions. The new API descriptions follow the current source implementation; install a package matching OpenResty and select the configuration for the installed implementation.

Performance relative to the open-source client

In a typical concurrent-read application scenario, lua-resty-redis-fast achieved 3.47 times the throughput of open-source lua-resty-redis v0.34, a 246.9% increase.

Metriclua-resty-redis-fastlua-resty-redis v0.34
Median GET throughput214,314 commands/s61,778 commands/s
Median GET p99 latency0.785 ms1.793 ms

The comparison uses shared mode at equal Lua concurrency with different physical connection counts. The Fast connection limit was 6 for the test; the current default is 3. Actual gains depend on workload, connection settings, and deployment.

Prerequisites

  • The use must have the root permission.

  • The machine needs to be able to access the following domains to download packages and GPG keys:

    You can check the accessibility of the domains by running the following commands:

    curl https://openresty.org/package/pubkey.gpg
    curl https://pkg2.openresty.com/xray-priv-libs/
    

Configure the software repository

Replace CLIENT_TOKEN with a valid token from your subscription email. Download the repository configuration script, then follow the section for the implementation you use. These commands configure repositories; they do not install library packages.

curl -o get-xray-priv-lib-repo.sh https://pkg2.openresty.com/scripts/get-xray-priv-lib-repo.sh

Both implementations also require the OpenResty open-source repository to install OpenResty and its dependencies. If it is not configured, follow the Linux packages instructions.

New implementation repository for OpenResty 1.31.8.x

For the new implementation, configure the lua-resty-redis-fast private repository:

sudo bash get-xray-priv-lib-repo.sh -l lua-resty-redis-fast -t CLIENT_TOKEN

The new implementation does not require installing the coro-nginx-module or coro-hiredis-nginx-module packages or loading their Nginx dynamic modules.

Legacy implementation repositories

For matching legacy packages, configure both private repositories:

sudo bash get-xray-priv-lib-repo.sh -l coro-nginx-module -t CLIENT_TOKEN

sudo bash get-xray-priv-lib-repo.sh -l lua-resty-redis-fast -t CLIENT_TOKEN

Installation

For OpenResty-1.21.4.x

For systems using yum, run the following command to install the private library:

sudo yum install --disablerepo="*" --enablerepo="coro-nginx-module,lua-resty-redis-fast" -y lua-resty-redis-fast-1.21.4

For systems using dnf, run the following command to install the private library:

sudo dnf install --disablerepo="*" --enablerepo="coro-nginx-module,lua-resty-redis-fast" -y lua-resty-redis-fast-1.21.4

For systems using apt, run the following command to install the private library:

sudo apt-get install -y lua-resty-redis-fast-1.21.4

For OpenResty 1.25.3.x

For systems using yum, run the following command to install the private library:

sudo yum install --disablerepo="*" --enablerepo="coro-nginx-module,lua-resty-redis-fast" -y lua-resty-redis-fast-1.25.3

For systems using dnf, run the following command to install the private library:

sudo dnf install --disablerepo="*" --enablerepo="coro-nginx-module,lua-resty-redis-fast" -y lua-resty-redis-fast-1.25.3

For systems using apt, run the following command to install the private library:

sudo apt-get install -y lua-resty-redis-fast-1.25.3

For OpenResty 1.27.1.x

For systems using yum, run the following command to install the private library:

sudo yum install --disablerepo="*" --enablerepo="coro-nginx-module,lua-resty-redis-fast" -y lua-resty-redis-fast-1.27.1

For systems using dnf, run the following command to install the private library:

sudo dnf install --disablerepo="*" --enablerepo="coro-nginx-module,lua-resty-redis-fast" -y lua-resty-redis-fast-1.27.1

For systems using apt, run the following command to install the private library:

sudo apt-get install -y lua-resty-redis-fast-1.27.1

For OpenResty 1.31.8.x

The package is named lua-resty-redis-fast-1.31.8 and is provided in RPM and DEB formats. The new implementation requires OpenResty 1.31.8.1 or newer in the same series. Configure the OpenResty open-source repository first so the package manager can resolve dependencies. The 1.31.8 suffix identifies the matching Nginx series only; after upgrading, confirm that the new standalone dynamic module is loaded.

For systems using yum, dnf, or apt, run the corresponding command:

sudo yum install -y lua-resty-redis-fast-1.31.8
sudo dnf install -y lua-resty-redis-fast-1.31.8
sudo apt-get install -y lua-resty-redis-fast-1.31.8

Installing OpenResty

Select OpenResty 1.31.8.x for the new implementation, or the matching series for a legacy library. Before installing or upgrading, query the repository for full versions to avoid dynamic module incompatibility.

Package managerQuery available versionsInstall a specific version
yumyum list --showduplicates openrestysudo yum install openresty-VERSION
dnfdnf list --showduplicates openrestysudo dnf install openresty-VERSION
aptapt-cache madison openrestysudo apt-get install openresty=VERSION

Replace VERSION with the full version from the query results matching the selected private library.

Usage

Distinguish the new standalone dynamic module from the legacy coro implementation.

New implementation usage

Nginx configuration

Load the dynamic module provided by the new package in the main context of nginx.conf:

load_module /usr/local/openresty/nginx/modules/ngx_redis_fast_module.so;

For custom installations, use the actual module path. This library no longer needs coro_preload, coro_stack_size, or the two coro dynamic modules. Retain configuration still required by other private libraries. RPM and DEB packages use the same configuration. Packages install Lua bytecode modules under /usr/local/openresty/site/lualib; a custom lua_package_path must preserve defaults with ;; or include /usr/local/openresty/site/lualib/?.ljbc. Nginx workers must be able to read the modules and required certificate and private key files.

Lua API and behavior changes

The entry point remains require "resty.redis.fast", and common command and pipeline methods remain available. Review connection ownership, pooling, and session operations when upgrading:

Interface or optionNew behavior and migration requirements
connect(host, port, options)Supports TCP, TLS, and Unix domain sockets. Ports can be numbers or numeric strings. Hostnames require an Nginx resolver. Reconnect clears pending pipeline and subscription state; a failed reconnect leaves the client closed.
db, select(db)Select a database while connecting, using a number or numeric string. select() changes only this Lua instance’s database binding. It cannot switch databases during transactions, WATCH, subscriptions, or non-replayable session state.
max_connectionsDefaults to 3, limiting ordinary shared connections per worker, endpoint, and database across custom pool names, credentials, and TLS/RESP settings. Databases have independent budgets; exclusive connections are exempt. The first connection establishes the endpoint/database limit while its pools remain in use.
pending_thresholdDefaults to 32, a soft threshold for outstanding command replies per connection. Ordinary commands choose the least-loaded compatible connection. When all reach the threshold, a connection is added if the budget permits; otherwise the least-loaded connection is reused.
pool_size, backlogIdle capacity defaults to 128. With backlog, pool_size also limits ordinary physical connections in that pool, and backlog bounds queued connection requests. Their scope differs from max_connections.
set_keepalive(timeout, size)The new implementation uses both arguments to update idle policy and close the logical client. Defaults are 60000 milliseconds and 128 idle connections; a zero timeout disables expiry. Review the timeout and capacity arguments in existing calls when upgrading.
close()Releases the logical client. Clean ordinary transports remain cached for reuse; private or modified session connections close. It does not guarantee immediate closure of a shared physical connection.
get_reused_times()Reports the last borrowed transport’s reuse count, or 0 while closed. A later operation may borrow a different connection.
exclusive = trueTo use WAIT or WAITAOF, connect with this option before the writes, pinning writes and acknowledgements to the same connection. Shared clients reject both commands.
TLS and authenticationCertificate chain verification defaults to enabled. ssl_ca_cert chooses a CA; ssl_verify_name separately checks the certificate DNS name or IP. SNI does not replace identity verification. Set password and optionally username in connect().
RESP3Set resp3 = true in connect() and supply credentials for protected servers. For manual authentication, connect with default RESP2, authenticate, then call hello(3).
ErrorsRedis command errors still return false, err; transport errors return nil, err. Array or pipeline error entries are {false, err}. RESP3 false, nil is a valid result; check err ~= nil.

Ordinary operations return their physical connection on completion, read timeout, or coroutine cancellation. The Lua instance remains usable for ordinary commands; late replies are discarded rather than delivered to later calls. After a state-changing request times out or is canceled, execute RESET before further commands or keepalive. A timeout does not prove a write was not executed; do not retry writes unconditionally. Do not share one Lua client object between concurrent operations.

AUTH, HELLO, RESET, transactions, WATCH, subscriptions, and blocking commands use exclusive connections. SELECT forms a segment boundary in ordinary pipelines. SELECT inside a transaction or WATCH returns nil, "SELECT cannot switch connections in a transaction"; a pipeline containing such a switch is rejected before any commands are sent. Subscription commands and MONITOR cannot be queued in pipelines.

Lua example

Place the following code inside content_by_lua_block:

local redis = require "resty.redis.fast"
local red = redis:new()
red:set_timeouts(1000, 1000, 1000)

local ok, err = red:connect("127.0.0.1", 6379, {
    db = 0,
    max_connections = 3,
    pending_threshold = 32,
})
if not ok then
    ngx.say("failed to connect: ", err)
    return
end

local res
res, err = red:set("dog", "an animal")
if err ~= nil then
    red:close()
    ngx.say("failed to set dog: ", err)
    return
end

res, err = red:get("dog")
if err ~= nil then
    red:close()
    ngx.say("failed to get dog: ", err)
    return
end

ngx.say("dog: ", res == ngx.null and "not found" or res)
ok, err = red:set_keepalive(60000, 128)
if not ok then
    red:close()
    ngx.say("failed to set keepalive: ", err)
end

See the API manual for all options and session rules. This client supports only the HTTP subsystem and does not provide Redis Cluster routing; use lua-resty-redis-cluster-fast for Redis Cluster.

Legacy implementation usage

The following Nginx configuration and Lua examples apply to the legacy implementation. For the new implementation, use the configuration above and review the Lua API changes.

Nginx configuration

Before you can use lua-resty-redis-fast, you need to add the following configuration items to the configuration file nginx.conf to load the related dynamic modules.

    ...

    load_module "/usr/local/openresty-coro-nginx-module/lib/ngx_http_coro_module.so";
    load_module "/usr/local/openresty-coro-nginx-module/lib/ngx_http_coro_hiredis_module.so";

    http {
        coro_preload /usr/local/openresty/openssl111/lib/libcrypto.so;
        coro_preload /usr/local/openresty/openssl111/lib/libssl.so;
        coro_preload /usr/local/openresty-plus/hiredis/lib/libhiredis.so;
        coro_preload /usr/local/openresty-plus/hiredis/lib/libhiredis_ssl.so;

        coro_stack_size  32768;
        ...
    }

Lua interface

Interface set_keepalive is changed. Other interfaces of this library are consistent with those of the open-source lua-resty-redis. Let’s see the following example:

    load_module "/usr/local/openresty-coro-nginx-module/lib/ngx_http_coro_module.so";
    load_module "/usr/local/openresty-coro-nginx-module/lib/ngx_http_coro_hiredis_module.so";

    http {
        coro_preload /usr/local/openresty-plus/hiredis/lib/libhiredis.so;
        coro_stack_size  32768;

        server {
            location /test {
                # need to specify the resolver to resolve the hostname
                resolver 8.8.8.8;

                content_by_lua_block {
                    local redis = require "resty.redis.fast"
                    local red = redis:new()

                    red:set_timeout(1000) -- 1 sec

                    local ok, err = red:connect("127.0.0.1", $TEST_NGINX_REDIS_PORT)
                    if not ok then
                        ngx.say("failed to connect: ", err)
                        return
                    end

                    ok, err = red:select(1)
                    if not ok then
                        ngx.say("failed to select: ", err)
                        return
                    end

                    local res, err = red:set("dog", "an animal")
                    if not res then
                        ngx.say("failed to set dog: ", err)
                        return
                    end

                    local ok, err = red:set_keepalive()
                    if not ok then
                        ngx.say("failed to set keepalive: ", err)
                        return
                    end
                }
            }
        }
    }