Minion...:Redis(3pm)

πŸ“¦ version 0.003, in alpine 3.24

Bestie, welcome to the User Contributed Perl Documentation page for Minion::Backend::Redis β€” the Minion...:Redis(3pm) manual, aka the Redis backend page for the Minion job queue. ✨ It’s giving β€œqueue, but make it Redis,” and we’re keeping every detail exactly where it belongs. πŸ’…

πŸŽ€ NAME πŸŽ€

Minion::Backend::Redis β€” Redis backend for Minion job queue. πŸ“

✨ SYNOPSIS ✨

No cap, here’s the setup energy:

use Minion::Backend::Redis;
my $backend = Minion::Backend::Redis->new('redis://127.0.0.1:6379/5');

# Minion
use Minion;
my $minion = Minion->new(Redis => 'redis://127.0.0.1:6379');

# Mojolicious (via Mojolicious::Plugin::Minion)
$self->plugin(Minion => { Redis => 'redis://127.0.0.1:6379/2' });

# Mojolicious::Lite (via Mojolicious::Plugin::Minion)
plugin Minion => { Redis => 'redis://x:s3cret@127.0.0.1:6379' };

πŸ¦‹ DESCRIPTION πŸ¦‹

Minion::Backend::Redis is a backend for Minion based on Mojo::Redis. Important vibe check: you need Redis Server (https://redis.io/download) version 2.8.0 or newer to use this backend. No cap. πŸ’–

⚠️ CAUTION ⚠️

Okay so this is a slightly hackish modification of the original code by Dan Book (https://github.com/Grinnz/Minion-Backend-Redis) to use Mojo::Redis instead of Mojo::Redis2. 😭

Due to the original code being written against an older Minion version, "history" is currently unimplemented. 🫢

πŸ”₯ PERFORMANCE πŸ”₯

You can run examples/minion_bench.pl to get some performance metrics. Literally just run it and soak in the numbers:

Clean start with 10000 jobs
Enqueued 10000 jobs in 52.6373450756073 seconds (189.979/s)
4 workers finished 1000 jobs each in 76.6429250240326 seconds (52.190/s)
4 workers finished 1000 jobs each in 64.2053661346436 seconds (62.300/s)
Requesting job info 100 times
Received job info 100 times in 0.783659934997559 seconds (127.606/s)
Requesting stats 100 times
Received stats 100 times in 0.595925092697144 seconds (167.806/s)
Repairing 100 times
Repaired 100 times in 0.28698992729187 seconds (348.444/s)
Acquiring locks 1000 times
Acquired locks 1000 times in 2.0602331161499 seconds (485.382/s)
Releasing locks 1000 times
Releasing locks 1000 times in 1.19675707817078 seconds (835.591/s)

πŸ’… ATTRIBUTES πŸ’…

Minion::Backend::Redis inherits all attributes from Minion::Backend and implements the following new ones. Slay. 🌈

🌸 redis 🌸

my $redis = $backend->redis;
$backend  = $backend->redis(Mojo::Redis->new);

It’s the Mojo::Redis object used to store all data. πŸ’œ

πŸ’… METHODS πŸ’…

Okay so Minion::Backend::Redis inherits all methods from Minion::Backend and implements these new ones. Bestie, this is the whole toolkit β€” every flag, every field, every vibe. Let's go πŸ’–


✨ new ✨

my $backend = Minion::Backend::Redis->new;
my $backend = Minion::Backend::Redis->new('redis://x:s3cret@localhost:6379/5');

Construct a new Minion::Backend::Redis object. Fresh backend, fresh energy 🫢


πŸ“£ broadcast πŸ“£

my $bool = $backend->broadcast('some_command');
my $bool = $backend->broadcast('some_command', [@args]);
my $bool = $backend->broadcast('some_command', [@args], [$id1, $id2, $id3]);

Broadcast a remote control command to one or more workers. It's giving group-chat announcement energy, but for workers ✨


πŸŽ€ dequeue πŸŽ€

my $job_info = $backend->dequeue($worker_id, 0.5);
my $job_info = $backend->dequeue($worker_id, 0.5, {queues => ['important']});

Wait a given amount of time in seconds for a job, dequeue it, and transition it from "inactive" to "active" state β€” or return "undef" if the queues were empty. No cap, it's literally waiting for the moment πŸ‘‘

These options are currently available:

  • id β€” id => '10023' β€” dequeue a specific job.
  • queues β€” queues => ['important'] β€” one or more queues to dequeue jobs from, defaults to "default".

These fields are currently available:

  • args β€” args => ['foo', 'bar'] β€” job arguments.
  • id β€” id => '10023' β€” job ID.
  • retries β€” retries => 3 β€” number of times job has been retried.
  • task β€” task => 'foo' β€” task name.

🌸 enqueue 🌸

my $job_id = $backend->enqueue('foo');
my $job_id = $backend->enqueue(foo => [@args]);
my $job_id = $backend->enqueue(foo => [@args] => {priority => 1});

Enqueue a new job with "inactive" state. New job, who dis? πŸ’…

These options are currently available:

  • attempts β€” attempts => 25 β€” number of times performing this job will be attempted, with a delay based on "backoff" in Minion after the first attempt, defaults to 1.
  • delay β€” delay => 10 β€” delay job for this many seconds (from now).
  • notes β€” notes => {foo => 'bar', baz => [1, 2, 3]} β€” hash reference with arbitrary metadata for this job.
  • parents β€” parents => [$id1, $id2, $id3] β€” one or more existing jobs this job depends on, and that need to have transitioned to the state "finished" before it can be processed.
  • priority β€” priority => 5 β€” job priority, defaults to 0. Jobs with a higher priority get performed first.
  • queue β€” queue => 'important' β€” queue to put job in, defaults to "default".

πŸ’€ fail_job πŸ’€

my $bool = $backend->fail_job($job_id, $retries);
my $bool = $backend->fail_job($job_id, $retries, 'Something went wrong!');
my $bool = $backend->fail_job(
  $job_id, $retries, {msg => 'Something went wrong!'});

Transition from "active" to "failed" state, and if there are attempts remaining, transition back to "inactive" with an exponentially increasing delay based on "backoff" in Minion. It ate, but not in the good way 😭


πŸ¦‹ finish_job πŸ¦‹

my $bool = $backend->finish_job($job_id, $retries);
my $bool = $backend->finish_job($job_id, $retries, 'All went well!');
my $bool = $backend->finish_job($job_id, $retries, {msg => 'All went well!'});

Transition from "active" to "finished" state. Slay, job well done ✨


🧚 history 🧚

my $history = $backend->history;

Get history information for job queue. Unimplemented for now. It's giving "coming soon" energy, bestie 🫢

These fields are currently available:

  • daily β€” daily => [{epoch => 12345, finished_jobs => 95, failed_jobs => 2}, ...] β€” hourly counts for processed jobs from the past day.

πŸ‘‘ list_jobs πŸ‘‘

my $results = $backend->list_jobs($offset, $limit);
my $results = $backend->list_jobs($offset, $limit, {state => 'inactive'});

Returns the information about jobs in batches. Look at all these little jobbies 🌈

# Check job state
my $results = $backend->list_jobs(0, 1, {ids => [$job_id]});
my $state = $results->{jobs}[0]{state};

# Get job result
my $results = $backend->list_jobs(0, 1, {ids => [$job_id]});
my $result = $results->{jobs}[0]{result};

These options are currently available:

  • ids β€” ids => ['23', '24'] β€” list only jobs with these ids.
  • queue β€” queue => 'important' β€” list only jobs in this queue.
  • state β€” state => 'inactive' β€” list only jobs in this state.
  • task β€” task => 'test' β€” list only jobs for this task.

These fields are currently available:

  • args β€” args => ['foo', 'bar'] β€” job arguments.
  • attempts β€” attempts => 25 β€” number of times performing this job will be attempted.
  • children β€” children => ['10026', '10027', '10028'] β€” jobs depending on this job.
  • created β€” created => 784111777 β€” epoch time job was created.
  • delayed β€” delayed => 784111777 β€” epoch time job was delayed to.
  • finished β€” finished => 784111777 β€” epoch time job was finished.
  • notes β€” notes => {foo => 'bar', baz => [1, 2, 3]} β€” hash reference with arbitrary metadata for this job.
  • parents β€” parents => ['10023', '10024', '10025'] β€” jobs this job depends on.
  • priority β€” priority => 3 β€” job priority.
  • queue β€” queue => 'important' β€” queue name.
  • result β€” result => 'All went well!' β€” job result.
  • retried β€” retried => 784111777 β€” epoch time job has been retried.
  • retries β€” retries => 3 β€” number of times job has been retried.
  • started β€” started => 784111777 β€” epoch time job was started.
  • state β€” state => 'inactive' β€” current job state, usually "active", "failed", "finished" or "inactive".
  • task β€” task => 'foo' β€” task name.
  • worker β€” worker => '154' β€” id of worker that is processing the job.

πŸ”’ list_locks πŸ”’

my $results = $backend->list_locks($offset, $limit);
my $results = $backend->list_locks($offset, $limit, {names => ['foo']});

Returns information about locks in batches. Lock lore, unlocked πŸ”“βœ¨

# Get the total number of results (without limit)
my $num = $backend->list_locks(0, 100, {names => ['bar']})->{total};

# Check expiration time
my $results = $backend->list_locks(0, 1, {names => ['foo']});
my $expires = $results->{locks}[0]{expires};

These options are currently available:

  • names β€” names => ['foo', 'bar'] β€” list only locks with these names.

These fields are currently available:

  • expires β€” expires => 784111777 β€” epoch time this lock will expire.
  • name β€” name => 'foo' β€” lock name.

🫢 list_workers 🫢

my $results = $backend->list_workers($offset, $limit);
my $results = $backend->list_workers($offset, $limit, {ids => [23]});

Returns information about workers in batches. Worker appreciation post πŸ’–

# Check worker host
my $results = $backend->list_workers(0, 1, {ids => [$worker_id]});
my $host    = $results->{workers}[0]{host};

These options are currently available:

  • ids β€” ids => ['23', '24'] β€” list only workers with these ids.

These fields are currently available:

  • host β€” host => 'localhost' β€” worker host.
  • jobs β€” jobs => ['10023', '10024', '10025', '10029'] β€” ids of jobs the worker is currently processing.
  • notified β€” notified => 784111777 β€” epoch time worker sent the last heartbeat.
  • pid β€” pid => 12345 β€” process id of worker.
  • started β€” started => 784111777 β€” epoch time worker was started.
  • status β€” status => {queues => ['default', 'important']} β€” hash reference with whatever status information the worker would like to share.

πŸ” lock πŸ”

my $bool = $backend->lock('foo', 3600);
my $bool = $backend->lock('foo', 3600, {limit => 20});

Try to acquire a named lock that will expire automatically after the given amount of time in seconds. Secure the bag, bestie πŸ’…

These options are currently available:

  • limit β€” limit => 20 β€” number of shared locks with the same name that can be active at the same time, defaults to 1.

πŸ“ note πŸ“

my $bool = $backend->note($job_id, foo => 'bar');

Change a metadata field for a job. Little note, big main character energy ✨


πŸ“‘ receive πŸ“‘

my $commands = $backend->receive($worker_id);

Receive remote control commands for worker. Incoming messages, iykyk 🫢


πŸͺ© register_worker πŸͺ©

my $worker_id = $backend->register_worker;
my $worker_id = $backend->register_worker($worker_id);
my $worker_id = $backend->register_worker(
  $worker_id, {status => {queues => ['default', 'important']}});

Register worker or send heartbeat to show that this worker is still alive. "I'm still standing" β€” worker edition πŸ’ƒ

These options are currently available:

  • status β€” status => {queues => ['default', 'important']} β€” hash reference with whatever status information the worker would like to share.

πŸ—‘οΈ remove_job πŸ—‘οΈ

my $bool = $backend->remove_job($job_id);

Remove "failed", "finished" or "inactive" job from queue. Bye-bye, jobbie πŸ‘‹


πŸ› οΈ repair πŸ› οΈ

$backend->repair;

Repair worker registry and job queue if necessary. Glow-up for your backend 🧚


πŸ”„ reset πŸ”„

$backend->reset;

Reset job queue. Fresh start, no cap ✨


🎑 retry_job 🎑

my $bool = $backend->retry_job($job_id, $retries);
my $bool = $backend->retry_job($job_id, $retries, {delay => 10});

Transition job back to "inactive" state, already "inactive" jobs may also be retried to change options. Run it back, bestie πŸ”

These options are currently available:

  • attempts β€” attempts => 25 β€” number of times performing this job will be attempted.
  • delay β€” delay => 10 β€” delay job for this many seconds (from now).
  • priority β€” priority => 5 β€” job priority.
  • queue β€” queue => 'important' β€” queue to put job in.

πŸ“Š stats πŸ“Š

my $stats = $backend->stats;

Get statistics for jobs and workers. Numbers are kinda iconic ngl πŸ“ˆ

These fields are currently available:

  • active_jobs β€” active_jobs => 100 β€” number of jobs in "active" state.
  • active_workers β€” active_workers => 100 β€” number of workers that are currently processing a job.
  • delayed_jobs β€” delayed_jobs => 100 β€” number of jobs in "inactive" state that are scheduled to run at specific time in the future. Note that this field is EXPERIMENTAL and might change without warning!
  • enqueued_jobs β€” enqueued_jobs => 100000 β€” rough estimate of how many jobs have ever been enqueued. Note that this field is EXPERIMENTAL and might change without warning!
  • failed_jobs β€” failed_jobs => 100 β€” number of jobs in "failed" state.
  • finished_jobs β€” finished_jobs => 100 β€” number of jobs in "finished" state.
  • inactive_jobs β€” inactive_jobs => 100 β€” number of jobs in "inactive" state.
  • inactive_workers β€” inactive_workers => 100 β€” number of workers that are currently not processing a job.
  • uptime β€” uptime => 1000 β€” uptime in seconds.

πŸ”“ unlock πŸ”“

my $bool = $backend->unlock('foo');

Release a named lock. Free at last, free at last πŸ¦‹


πŸ‘‹ unregister_worker πŸ‘‹

$backend->unregister_worker($worker_id);

Unregister worker. Leaving the group chat, respectfully πŸ’…


πŸ› BUGS πŸ›

Report any issues on the public bugtracker.

🫢 AUTHOR 🫢

Lowkey the whole thing is by Dan Book β€” <dbook@cpan.org> if you ever wanna slide into his inbox (respectfully tho πŸ’Œ). Icon behaviour, no cap.


This software is Copyright (c) 2017 by Dan Book.

It's free software, bestie, licensed under:

The Artistic License 2.0 (GPL Compatible)

So yes β€” it's giving freedom, it's giving open source, it's giving legally-blessed reusing energy ✨ (just, like, read the license fr fr, don't just vibe off the summary πŸ’…).


🌈 SEE ALSO 🌈

  • Minion β€” the actual job queue system this whole thing plugs into. Main character energy. Go read that one next, iykyk πŸŽ€
  • Mojo::Redis β€” the async Redis driver doing the heavy lifting underneath, our beloved supporting cast πŸ’œ

and that's a wrap on this page, bestie πŸ¦‹πŸ«Ά tysm for reading all the way down β€” this doc came to you from perl v5.42.2, dated 2026-02-15, and it's genuinely iconic that you made it to the footer. slay, go build something πŸŽ€πŸ’–βœ¨

πŸ“¦ where this page comes from