Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Redis Laravel Package

webman/redis

Redis client for the webman framework, providing connection pooling and coroutine-safe access through ext-redis or Predis. Supports multiple connections, cluster and sentinel setups, lazy connections, and an expressive API for caching, queues, pub/sub and other common Redis workloads.

View on GitHub
Deep Wiki
Context7

Getting Started

webman/redis bundles illuminate/redis (the Redis component extracted from Laravel) into webman, wiring it to the Worker lifecycle with an optional connection pool. If you have written Redis::set(...) in a Laravel app, this is the same API surface.

Install and publish config

composer require -W webman/redis

The -W flag matters on older webman skeletons whose pinned dependencies would otherwise block the install. The plugin installer copies config/redis.php into your project; if it does not appear, copy it manually from vendor/webman/redis/src/config/plugin/webman/redis/redis.php.

Look here first

  1. config/redis.php – host, port, password, database, timeout, and the pool block.
  2. support\Redis – the static entry point; every static call proxies to the default connection.
  3. vendor/webman/redis/README.md – short, but it is the canonical list of supported keys.

First use case: cache a hot query

<?php
namespace app\controller;

use support\Redis;
use support\Request;

class UserController
{
    public function show(Request $request, $id)
    {
        $key  = "user:{$id}";
        $data = Redis::get($key);

        if ($data === null) {
            $data = json_encode(['id' => $id, 'name' => 'tom']); // replace with a DB call
            Redis::setex($key, 300, $data);
        }

        return response(json_decode($data, true));
    }
}

Start with php start.php start and hit the route. If you see Class "support\Redis" not found, the plugin was not installed or the composer autoloader was not regenerated (composer dump-autoload).

Implementation Patterns

Facade for the default, explicit connection objects for everything else. Static calls are convenient for one-liners, but any block of more than two commands should bind the connection once:

$redis = Redis::connection();          // default from config/redis.php
$redis = Redis::connection('cache');   // named key in config/redis.php
$redis->incr('hits:today');
$redis->expire('hits:today', 86400);

Multi-connection layout. Define one entry per concern rather than mixing SELECT calls at runtime: default (business data), cache (throwaway, higher eviction risk), session, queue. Each connection can point to a different host, database, or pool size. Give cache connections a shorter timeout than business connections so a slow cache does not stall requests.

Pipelines and transactions. Both are first-class on the connection:

Redis::pipeline(function ($pipe) use ($ids) {
    foreach ($ids as $id) {
        $pipe->get("user:{$id}");
    }
});

Redis::transaction(function ($tx) use ($key) {
    $tx->incr($key);
    $tx->expire($key, 60);
});

A pipeline turns N round trips into one; on a per-process worker this is the single biggest latency win for list pages.

Distributed locks. Use SET NX EX plus a Lua compare-and-delete, not SETNX + EXPIRE (non-atomic):

$token = bin2hex(random_bytes(16));
$ok = Redis::set($key, $token, 'EX', 10, 'NX');

// release
Redis::eval(
    "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end",
    1, $key, $token
);

Raw client escape hatch. For anything the abstraction hides (SCAN cursors, OBJECT ENCODING, CLIENT LIST), drop to the driver:

$client = Redis::connection()->client();   // Redis (phpredis) or Predis\Client
$iterator = null;
while ($keys = $client->scan($iterator, 'user:*', 500)) { /* ... */ }

Background work. webman/redis-queue, cache stores, and cron tasks all want Redis. Register a dedicated connection per consumer so a queue backlog cannot exhaust the pool the request path depends on. For SUBSCRIBE/PSUBSCRIBE/BLPOP, write a custom Workerman process in config/process.php — never subscribe inside a controller.

Coroutine runtimes. Under Swoole/Swow the pool is real: max_connections should exceed expected concurrent coroutines per process, and wait_timeout bounds how long a coroutine queues for a free connection. Under plain Workerman (no coroutines) one connection per process handles everything, so max_connections => 1 is sufficient and pool mostly provides reconnect hygiene.

Wrap it once. A thin app\support\Cache class that owns key prefixes, TTLs, and JSON (de)serialization keeps key naming consistent and gives you one place to add metrics or fallbacks.

Gotchas and Tips

  • Config changes require a restart/reload. webman loads config/redis.php at process start. Editing it and re-running a request does nothing until php start.php reload.
  • Stale connections after a Redis restart. phpredis keeps a persistent socket; a server bounce leaves workers throwing Redis server went away. Keep timeout low (2s), let the pool's heartbeat_interval/idle_timeout recycle sockets, and wrap hot paths in a retry-once try/catch.
  • Blocking commands freeze the worker. KEYS *, SUBSCRIBE, BLPOP, MONITOR, and huge SMEMBERS/LRANGE calls block the whole event loop for that process — every other request queued on it waits too. Use SCAN with a COUNT hint, and isolate blocking work in a dedicated process.
  • Big values are worse than big key counts. A 5 MB payload deserializes on every hit and stalls the loop. Compress or store a reference.
  • pipeline vs transaction. Pipelines are not atomic; if you need atomicity use transaction() or a Lua script. Do not assume MULTI semantics from a pipeline.
  • Type coercion differs between drivers. phpredis and predis disagree on booleans, nulls, and float formatting. If you might switch drivers, serialize complex values yourself (json_encode) and set the value type explicitly.
  • database is per physical connection. With pooling, every pooled socket issues SELECT n. Mixing logical DBs on one connection at runtime will confuse you under concurrency — use named connections instead.
  • Do not hoist a connection into a static property. In coroutine mode that object is shared across coroutines and can be returned to the pool while still in use. Resolve Redis::connection() inside the request/scope.
  • Redis::connection() is cheap (the manager caches instances), so there is no penalty for calling it per method — unlike instantiating your own Illuminate\Redis\RedisManager, which opens a fresh socket each time and will exhaust maxclients.
  • Exceptions are driver exceptions. Expect RedisException from phpredis and Predis\Connection\ConnectionException from predis. Catch broadly around Redis calls in user-facing paths and degrade to the database rather than returning a 500.
  • Testing. Point a testing connection at a separate database index and flushdb in setUp; never let tests share the production index. Assert on TTLs as well as values — missing expire calls are the most common leak.
  • Extension points. Add a named connection in config/redis.php for any new Redis instance; for custom behaviour (prefixing, tracing, serialization) subclass the connection or wrap support\Redis in a service class rather than patching vendor code, so composer update stays safe.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle