In a Laravel application, it's crucial to always be aware of which Redis client you’re using. Different Redis clients (such as predis or phpredis) can have varying levels of performance, feature support, and configuration differences. Especially when it comes to the implementation of the SCAN command, there are differences that may not be immediately apparent.
A few days ago, we encountered a requirement to search for similarities among keys within a massive pool of keys. So far, no problem.
1$keys = Redis::keys($pattern);
2
3foreach ($keys as $key) {
4 Log::info($key);
5}
Normally, this code would fulfill the requirement. The problem, however, is that the application for which we implemented this functionality handles several million requests per day, resulting in a massive set of caching keys in Redis.
The solution is SCAN. Unlike KEYS, which retrieves all keys at once, SCAN iterates over the data, requiring a cursor to manage the results. But so far, this isn’t the issue.
Our next iteration was a classic attempt at iteration in Redis:
1$pattern = '/test/*'
2$cursor = '0';
3$count = 50000;
4do {
5 $result = $redis->scan($cursor, ['match' => $pattern, 'count' => $count]);
6 if ($result === false) {
7 break;
8 }
9
10 $cursor = $result[0];
11 $allResults = array_merge($allResults, $result[1]);
12
13} while ($cursor !== '0');
An experienced eye will quickly notice that this implementation is primarily designed for PREDIS, a Redis client written in PHP.
Honestly, this caught us off guard. While our developers had been using Predis (perhaps out of convenience for setup 😉), the PHPRedis client, which is written in C, was set up in our staging environment.
The problem with this code is: It will not work with PHPRedis or at least it will not return any result. To change this you need to adjust the code a bit.
1$pattern = '/test/*'
2$cursor = config('database.redis.client') == 'predis' ? '0' : null;
3$count = 50000;
4do {
5 $result = $redis->scan($cursor, ['match' => $pattern, 'count' => $count]);
6 if ($result === false) {
7 break;
8 }
9
10 $cursor = $result[0];
11 $allResults = array_merge($allResults, $result[1]);
12
13} while ($cursor !== '0');
The result of this difference was absolutely absurd. Due to the slight variations in cursor handling between the clients, we ended up with no results at all.
So, always keep an eye on which Redis client you're using in Laravel! 🚀
Feel like cooking this up together?
Whether it's an idea, a refactor, or a new build — tell us briefly about your project. We'll get back to you within 24 hours.
Weiterlesen
20. Jul 2026
Notarization of Mac Apps
When notarizing apps, you need some secrets that are sometimes hard to access and hidden. Here are a few tips.
20. Jul 2026
Nori: Invoices, Proposals and Banking in One Place
Introducing Nori: proposals, invoices, time tracking and banking in one place – connected to the tools you already use. Currently in closed beta.
14. Jul 2026
WiFi Vouchers for UniFi: Guest WiFi in Seconds
We built a small app that gets visitors onto our guest WiFi in seconds. No UniFi Controller needed. Free for everyone.