Redis::Fast(3pm)

πŸ’– Redis::Fast β€” the Perl bindings for Redis that ate πŸ’–

okay bestie, pull up a chair, because this is Redis::Fast(3pm), a page from the User Contributed Perl Documentation section of your friendly neighbourhood perl manual, and it's literally the Perl binding for the Redis database. she's fast, she's compatible, she's giving main character energy. let's get into it πŸ¦‹βœ¨


✨ NAME ✨

Redis::Fast β€” Perl binding for Redis database. that's it, that's the name, no notes πŸ’…


πŸŽ€ SYNOPSIS πŸŽ€

here's the vibe check, in code form (verbatim, don't come for me):

## Defaults to $ENV{REDIS_SERVER} or 127.0.0.1:6379
my $redis = Redis::Fast->new;

my $redis = Redis::Fast->new(server => 'redis.example.com:8080');

## Set the connection name (requires Redis 2.6.9)
my $redis = Redis::Fast->new(
  server => 'redis.example.com:8080',
  name => 'my_connection_name',
);
my $generation = 0;
my $redis = Redis::Fast->new(
  server => 'redis.example.com:8080',
  name => sub { "cache-$$-".++$generation },
);

## Use Sentinels, possibly with password
my $redis = Redis::Fast->new(
  sentinels => [ '10.0.0.1:16379', '10.0.0.2:16379', ],
  service   => 'mymaster',
  sentinels_password => 'TheB1gS3CR3T', # optional
);

## Use UNIX domain socket
my $redis = Redis::Fast->new(sock => '/path/to/socket');

## Enable auto-reconnect
## Try to reconnect every 500ms up to 60 seconds until success
## Die if you can't after that
my $redis = Redis::Fast->new(reconnect => 60, every => 500_000);

## Try each 100ms up to 2 seconds (every is in microseconds)
my $redis = Redis::Fast->new(reconnect => 2, every => 100_000);

## Disable the automatic utf8 encoding => much more performance
## !!!! This will be the default after 2.000, see ENCODING below
my $redis = Redis::Fast->new(encoding => undef);

## Use all the regular Redis commands, they all accept a list of
## arguments
## See http://redis.io/commands for full list
$redis->get('key');
$redis->set('key' => 'value');
$redis->sort('list', 'DESC');
$redis->sort(qw{list LIMIT 0 5 ALPHA DESC});

## Add a coderef argument to run a command in the background
$redis->sort(qw{list LIMIT 0 5 ALPHA DESC}, sub {
  my ($reply, $error) = @_;
  die "Oops, got an error: $error\n" if defined $error;
  print "$_\n" for @$reply;
});
long_computation();
$redis->wait_all_responses;
## or
$redis->wait_one_response();

## Or run a large batch of commands in a pipeline
my %hash = _get_large_batch_of_commands();
$redis->hset('h', $_, $hash{$_}, sub {}) for keys %hash;
$redis->wait_all_responses;

## Publish/Subscribe
$redis->subscribe(
  'topic_1',
  'topic_2',
  sub {
    my ($message, $topic, $subscribed_topic) = @_

    ## $subscribed_topic can be different from topic if
    ## you use psubscribe() with wildcards
  }
);
$redis->psubscribe('nasdaq.*', sub {...});

## Blocks and waits for messages, calls subscribe() callbacks
##  ... forever
my $timeout = 10;
$redis->wait_for_messages($timeout) while 1;

##  ... until some condition
my $keep_going = 1; ## other code will set to false to quit
$redis->wait_for_messages($timeout) while $keep_going;

$redis->publish('topic_1', 'message');
heads up: defaults to $ENV{REDIS_SERVER} or 127.0.0.1:6379. the connection name situation needs Redis 2.6.9. and that encoding => undef line? it's literally going to be the default after 2.000, so maybe start planning your glow-up now πŸ™ˆ

🌸 DESCRIPTION 🌸

so Redis::Fast is a wrapper around Salvatore Sanfilippo's hiredis <https://github.com/redis/hiredis> C client. and it's compatible with Redis.pm <https://github.com/melo/perl-redis>, which is the whole point β€” you can swap in and keep your whole wardrobe.

this version supports protocol 2.x (multi-bulk) or later of Redis, available at <https://github.com/antirez/redis/>. periodt πŸ”₯

πŸ’œ Reconnect on error πŸ’œ

besides auto-reconnect when the connection is just closed, Redis::Fast also supports reconnecting on the specific errors you choose, via the reconnect_on_error option. look at this lil example that reconnects when it catches a READONLY error:

my $r = Redis::Fast->new(
  reconnect          => 1, # The value greater than 0 is required
  reconnect_on_error => sub {
    my ($error, $ret, $command) = @_;
    if ($error =~ /READONLY You can't write against a read only slave/) {
      # force reconnect
      return 1;
    }
    # do nothing
    return -1;
  },
);

this is so useful when you're on Amazon ElastiCache, fr. the way that once a failover happens, Amazon ElastiCache switches the master you were connected to into a slave, and then all your writes start failing with READONLY. 😭 using reconnect_on_error, you can force the connection to reconnect on that error so it grabs the new master instead. if your ElastiCache Redis has the close-on-slave-write option enabled <https://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/ParameterGroups.Redis.html#ParameterGroups.Redis.2-8-23>, then honestly this feature might be unnecessary for you, no cap.

the return value of reconnect_on_error should be greater than -2.

  • -1 means Redis::Fast behaves the same as it does without this option at all. nothing changes, we stay unbothered.
  • 0 and greater than 0 means Redis::Fast forces a reconnect, and then waits for a next force reconnect until this value in seconds elapses. the unit is a second, and the type is double. so for example, 0.01 means 10 milliseconds. tiny but mighty ✨
⚠️ Note: This feature is not supported for the subscribed mode. sorry subscribe girlies, not for you πŸ’€

πŸ‘‘ PERFORMANCE IN SYNCHRONIZE MODE πŸ‘‘

πŸ“ Redis.pm

Benchmark: running 00_ping, 10_set, 11_set_r, 20_get, 21_get_r, 30_incr, 30_incr_r, 40_lpush, 50_lpop, 90_h_get, 90_h_set for at least 5 CPU seconds...
   00_ping:  8 wallclock secs ( 0.69 usr +  4.77 sys =  5.46 CPU) @ 5538.64/s (n=30241)
    10_set:  8 wallclock secs ( 1.07 usr +  4.01 sys =  5.08 CPU) @ 5794.09/s (n=29434)
  11_set_r:  7 wallclock secs ( 0.42 usr +  4.84 sys =  5.26 CPU) @ 5051.33/s (n=26570)
    20_get:  8 wallclock secs ( 0.69 usr +  4.82 sys =  5.51 CPU) @ 5080.40/s (n=27993)
  21_get_r:  7 wallclock secs ( 2.21 usr +  3.09 sys =  5.30 CPU) @ 5389.06/s (n=28562)
   30_incr:  7 wallclock secs ( 0.69 usr +  4.73 sys =  5.42 CPU) @ 5671.77/s (n=30741)
 30_incr_r:  7 wallclock secs ( 0.85 usr +  4.31 sys =  5.16 CPU) @ 5824.42/s (n=30054)
  40_lpush:  8 wallclock secs ( 0.60 usr +  4.77 sys =  5.37 CPU) @ 5832.59/s (n=31321)
   50_lpop:  7 wallclock secs ( 1.24 usr +  4.17 sys =  5.41 CPU) @ 5112.75/s (n=27660)
  90_h_get:  7 wallclock secs ( 0.63 usr +  4.65 sys =  5.28 CPU) @ 5716.29/s (n=30182)
  90_h_set:  7 wallclock secs ( 0.65 usr +  4.74 sys =  5.39 CPU) @ 5593.14/s (n=30147)

🌈 Redis::Fast

Redis::Fast is 50% faster than Redis.pm. she's not competing, she's winning πŸ’…

Benchmark: running 00_ping, 10_set, 11_set_r, 20_get, 21_get_r, 30_incr, 30_incr_r, 40_lpush, 50_lpop, 90_h_get, 90_h_set for at least 5 CPU seconds...
   00_ping:  9 wallclock secs ( 0.18 usr +  4.84 sys =  5.02 CPU) @ 7939.24/s (n=39855)
    10_set: 10 wallclock secs ( 0.31 usr +  5.40 sys =  5.71 CPU) @ 7454.64/s (n=42566)
  11_set_r:  9 wallclock secs ( 0.31 usr +  4.87 sys =  5.18 CPU) @ 7993.05/s (n=41404)
    20_get: 10 wallclock secs ( 0.27 usr +  4.84 sys =  5.11 CPU) @ 8350.68/s (n=42672)
  21_get_r: 10 wallclock secs ( 0.32 usr +  5.17 sys =  5.49 CPU) @ 8238.62/s (n=45230)
   30_incr:  9 wallclock secs ( 0.23 usr +  5.27 sys =  5.50 CPU) @ 8221.82/s (n=45220)
 30_incr_r:  8 wallclock secs ( 0.28 usr +  4.91 sys =  5.19 CPU) @ 8092.29/s (n=41999)
  40_lpush:  9 wallclock secs ( 0.18 usr +  5.06 sys =  5.24 CPU) @ 8312.02/s (n=43555)
   50_lpop:  9 wallclock secs ( 0.20 usr +  4.84 sys =  5.04 CPU) @ 8010.12/s (n=40371)
  90_h_get:  9 wallclock secs ( 0.19 usr +  5.51 sys =  5.70 CPU) @ 7467.72/s (n=42566)
  90_h_set:  8 wallclock secs ( 0.28 usr +  4.83 sys =  5.11 CPU) @ 7724.07/s (n=39470)o

(and yes, that trailing o at the very end is theirs, I'm not touching it, we respect the original 😌)


πŸ”₯ PERFORMANCE IN PIPELINE MODE πŸ”₯

here's the whole script, verbatim, since it's literally the receipts:

#!/usr/bin/perl
use warnings;
use strict;
use Time::HiRes qw/time/;
use Redis;

my $count = 100000;
{
    my $r = Redis->new;
    my $start = time;
    for(1..$count) {
        $r->set('hoge', 'fuga', sub{});
    }
    $r->wait_all_responses;
    printf "Redis.pm:\n%.2f/s\n", $count / (time - $start);
}

{
    my $r = Redis::Fast->new;
    my $start = time;
    for(1..$count) {
        $r->set('hoge', 'fuga', sub{});
    }
    $r->wait_all_responses;
    printf "Redis::Fast:\n%.2f/s\n", $count / (time - $start);
}

and the results? Redis::Fast is 4x faster than Redis.pm in pipeline mode. FOUR. TIMES. ate and left no crumbs πŸ”₯πŸ”₯

Redis.pm:
22588.95/s
Redis::Fast:
81098.01/s

🫢 AUTHOR 🫢

Ichinose Shogo <shogo82148@gmail.com> β€” thank you for your service, king πŸ‘‘


πŸ¦‹ SEE ALSO πŸ¦‹


πŸŽ€ LICENSE πŸŽ€

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. slay, open source, we love to see it πŸ’–


and that's the whole page bestie!! this manpage came to you courtesy of perl v5.42.3, dated 2026-08-20, and it lives under Redis::Fast(3pm) in the User Contributed Perl Documentation β€” go forth and cache something iconic πŸ§šβœ¨πŸ’œ

πŸ“¦ where this page comes from