Laravel - PhpRedis is recommended by Redis library, but aren't there a lot of situations where it's better to use Predis?
Tags: larave, redis, phpredis, predis
Published: 2022-10-23 14:51:57

**Environment**
MySQL version : 5.7
Laravel version : 8.16.1
PHP version : 7.4.7


## The library when you use Redis with Laravel
There are 2 PHP libraries when you use Redis in Laravel.

 * [Predis](https://github.com/predis/predis)
 * [PhpRedis](https://github.com/phpredis/phpredis)

By default, composer.lock contains "predis".


### composer.lock
```php
    "packages": [
        {
            "require-dev": {
                "predis/predis": "^1.1.2",
                "symfony/cache": "^5.1.4"
            },
```

### config\database.php
```php
    'redis' => [
        'client' => env('REDIS_CLIENT', 'phpredis'),
```

"predis" is not used which is contained in composer.lock.(By default config)

It is necessary to install "phpredis" separately, which is contained in database.php.

cf.
phpredis couldn't be installed by composer.


What is this contradiction?

I wondered about it and looked it up.
It seems like predis was supposed to be removed from the default, but it has been reconsider.
However, they would like to suggest to use phpredis...

It seems that they are still in confusion.(maybe)


## Which should we adapt?
There seems to be a lot of debate about which one to use, and here's what I found.

[PHP向けRedisクライアントのpredisを使うのは止めた方がいいです(You should not use predis, the Redis client for PHP)](https://yoshinorin.net/2019/08/28/predis-not-maintain/)


> predisはPHP向けのRedisクライアントです。
> predis is a Redis client for PHP.
>
> リポジトリを見て察しのいい方は気づいたと思うのですが、2年ぐらいメンテ（コミットすら）されていません。
> If you have a good guess and check their repository, you'll notice that it hasn't been updated (even committed) for about two years.
>
> すでにPHP7.3周りで問題が出てます。これが「どういった事情でメンテされていないのか？」「されないのではなく、できないのか？」などは誰もわからないと思いますし、もしかしたら将来的に再度メンテされる可能性はありえます。
> There is already a problem from PHP7.3. I don't think anyone knows "Why is this not being updated?"


I looked up current situation, and as of September 2022, development has resumed and is active.
https://github.com/predis/predis/pulse

Therefore, there is no concern due to development stoppage.

> Laravelのドキュメントにも書いてありますが、phpredis使えばいいと思います。
> It is also stated in the Laravel documentation, but I think you should use phpredis.
>
> こちらはcomposerでインストールできない（PHP拡張モジュールなので）のでpeclでインストールします。
> This can not be installed with composer (because it is a PHP extension module), so install it with pecl.

Nooooooo!!!!!
Are you serious? We're not in the Stone Age now!

As expected, I thought that it was fixed now, so I looked at the official PhpRedis installation guide on the official website.
But, there is a message without a dream or hope to use pecl.

[https://github.com/phpredis/phpredis/blob/develop/INSTALL.markdown](https://github.com/phpredis/phpredis/blob/develop/INSTALL.markdown)

I found also this.
[How to install phpredis using composer?](https://github.com/phpredis/phpredis/issues/745)

> I need to install phpredis using composer on windows server running IIS. What is the package name for this?
>
> You cannot.
> Composer is for pure-PHP library not for C extension (pickle will do it later)
>
>You need to compile it! See more information here: 

Apparently it is impossible to install with composer, and the possibility of being able to do it in the future seems to be close to zero.

Just in case, I checked other articles as well.
[Laravel 8のRedisクライアントのパフォーマンスの比較(Laravel 8 Redis client performance comparison)](https://tdomy.com/2020/11/redis-client-comparison/)


It seems that PhpRedis was better in performance comparison.

> 上記のコマンドをそれぞれ50回実行し、平均（±標準偏差）を算出しました。
> I executed each command 50 times, and calculate average and standard deviation.
>
> * PhpRedis … 1.317 ± 0.03 (秒) *secs
> * Predis … 1.509 ± 0.026 (秒)*secs
>
> Predisを使用した場合の処理時間はPhpRedisの場合の約1割増しと、明らかに差がでました
>
> Laravel 8 でPhpRedisとPredisを比較しました。PhpRedisの方が普通に速いので、導入できる環境であれば、Laravelの推奨に従ってPhpRedisで良さそうです。
> I compared PhpRedis and Predis in Laravel 8. PhpRedis is usually faster, so if it is an environment that can be introduced, PhpRedis seems to be good according to Laravel's recommendation.

But I hate not being able to manage it with composer.

[PhpRedis vs Predis: Comparison on real production data](https://akalongman.medium.com/phpredis-vs-predis-comparison-on-real-production-data-a819b48cbadb)

> PhpRedis is faster about x6 times. Using igbinary serializer reduces stored data size about 3x times.
>
> If Redis installed on separate machines, reducing network traffic is a very significant speedup.

PhpRedis is also praised here.

Here is Laravel official statement.

[Redis 8.x Laravel](https://readouble.com/laravel/8.x/en/redis.html)
> Before using Redis with Laravel, we encourage you to install and use the phpredis PHP extension via PECL. 

Many developers highly recommended phpredis.


## How to install PhpRedis

### install command
I have tried Debian and Alpine distributions.
```
pecl install redis
```

If you get an error as below, try the following commands before.
```
/application # pecl install redis
downloading redis-5.3.4.tgz ...
Starting to download redis-5.3.4.tgz (268,154 bytes)
........................................................done: 268,154 bytes
29 source files, building
running: phpize
Configuring for:
PHP Api Version:         20190902
Zend Module Api No:      20190902
Zend Extension Api No:   320190902
Cannot find autoconf. Please check your autoconf installation and the
$PHP_AUTOCONF environment variable. Then, rerun this script.

ERROR: `phpize' failed
```

Command to run when the above error occurs
```
apk add --no-cache \
        $PHPIZE_DEPS \
        openssl-dev
```

### When writing in Dockerfile
```Dockerfile
FROM php:7.4.11-fpm

# omission

RUN git clone https://github.com/phpredis/phpredis.git /usr/src/php/ext/redis
RUN docker-php-ext-install redis
```

### Installation check
You can check whether PhpRedis is installed correctly with the following command.
```
php -m | grep redis
```
If you see the following message, PhpRedis has been successfully installed.
```
redis
```

## Redis container configuration

### docker-compose.yml
```yml
version: '3'
services:

# omission

  redis:
    image: "redis:6.0"
    container_name: redis
    restart: always
    ports:
      - "6379:6379"
    volumes:
      - "./data/redis:/data"
```


## Laravel configuration

### .env
```
CACHE_DRIVER=redis

REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379
```

### config\database.php
```php
    'redis' => [

        'client' => env('REDIS_CLIENT', 'phpredis'),
```

Before running the app, clear the cache with the following command.
```
php artisan config:clear
```

## Sample sources
I have written the following code to try it.

### routes\web.php
```php
namespace App\Http\Controllers;

use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Cache;

//============================================================================================
//                                       Cache
//============================================================================================
// http://localhost:8000/cache/put
Route::get('/cache/put', function () {
    echo "put";

    // store value in cache
    Cache::put('key01', 'value01');
});

// http://localhost:8000/cache/remember
Route::get('/cache/remember', function () {
    echo "remember";

    // store value permanently
    $cache = \Cache::remember('key02', 10, function(){
        return "value02_remember";
    });

    dump($cache);
});

// http://localhost:8000/cache/get
Route::get('/cache/get', function () {
    echo "get";

    // get one value from cache
    $cache01 = Cache::get('key01');
    $cache02 = Cache::get('key02');

    dump($cache01);
    dump($cache02);
});

// http://localhost:8000/cache/forget
Route::get('/cache/forget', function () {
    echo "forget";

    // remove value from cache
    Cache::forget('key01');
    Cache::forget('key02');
});
```


I was able to successfully get Redis to work.


## caution
After installing with command pecl install redis, the following message was displayed.

> You should add "extension=redis.so" to

However, it worked without adding it.
I have no idea about the details, but I guess Laravel take care of it and read it on its own.

As I thought, I also found this.

[Laravel Redisのライブラリをインストールしたらエラーが発生した(An error occurred when installing laravel redis library)](https://qiita.com/miriwo/items/d6ad9e0edc422e8a363a)


The content says,
"I got an error, but I fixed it by commenting out php.ini "extension="redis.so". 』

So, when you use Laravel, this setting may not be necessary.

However, there seems to be a case where an error occurs when uploading to another environment.
[AWSにLaravelをデプロイしたらエラーが出たときの対応方法(How to solve an error when deploying Laravel to AWS)](https://qiita.com/freeneer/items/8162c562337e304b4417)


It seems that extension=redis.so is added to php.ini to make it work in EC2.

It seems better to keep in mind that there are cases where such an error occurs, just in case "It does not work in the production environment!"

Maybe, using Amazon Linux(RedHat distribution) is one of the causes.
I tried it later and it worked just fine on Debian.


### How to add "extension=redis.so" to php.ini
First, check the path of php.ini.
Below is the command.
```
php -i | grep php.ini
```
Execution result example
```
/application $ php -i | grep php.ini
Configuration File (php.ini) Path => /usr/local/etc/php
Loaded Configuration File => /usr/local/etc/php/php.ini
```

In the above, the saved path was "/usr/local/etc/php/php.ini", so the additional path is as follows.
```
echo "extension=redis.so" >> /usr/local/etc/php/php.ini
```
After adding it, check the contents of php.ini.

Then reboot.


## case of Predis
I also tried it.

It can be installed with composer, so it's much easier than PhpRedis.

For more details, read the official website.
[https://readouble.com/laravel/8.x/ja/redis.html](https://readouble.com/laravel/8.x/ja/redis.html)

Execution command is here.
```
composer require predis/predis
```

If .env and config are set correctly, I think it works without any problem.


## Laravel configuration

### config\database.php
```php
    'redis' => [

        'client' => env('REDIS_CLIENT', 'predis'),
```

Other settings and the code used in the experiment are the same as above.

Since there is no difference due to distribution, you will not encounter unexpected issue, and you will have peace in your mind.


## perspective of library selection
Same engineers say that "PhpRedis is fast! PhpRedis is the best! You should definitely use PhpRedis!"
But, it cannot be managed by a package manager, and since it is necessary to modify parts close to hardware, there are many things to take account.

At the end of time, the difficulty of the building an environment may be complicated, it increases the possibility of unexpected errors during regular work.
In my opinion, then Predis is a good choice.

I found an article talking about the concern which Predis development had been suspended, but now development has resumed.
It can be managed by composer and has many advantages.

PhpRedis has better performance, but depending on system, there are cases where access to the cache does not happen so frequently.
If you don't need such a strict access speed performance, I think one of the selection criteria is to choose a library that can reduce management costs.

By the way, I am not agree with such an idea.
"Faster and lighter is always right! (Even if the application does not require high front-end performance. It should be implemented even if you have technical debt!)

Since you can't manage it with composer, you need to recreate the Docker image.
And also, If you are planning to use it in virtual server such as EC2, it will be necessary to prepare an installation command for each distribution, and the number of complicated works will increase.


## summary

 * When using Redis in Laravel, you will need to adopt one of two types of libraries. "Predis" or "PhpRedis"
 * Previously, Predis was commonly used, but now PhpRedis is recommended. (even in official website)
 * PhpRedis cannot be managed by composer and must be installed by pecl.
 * Therefore, if you are using containers, you need to rebuild the image.
 * You may need to add "extension=redis.so" to php.ini, but it may work without it depend on the environment.

If you think that "Why am I having such a hard time just using the cache driver...?The front end is not important in this system",
I recommend consider adopting Predis.


## Extra
One day, I got a "500 error" no matter what I did.
So I looked in laravel.log and found such a message.

```
local.ERROR: Please make sure the PHP Redis extension is installed and enabled. 
{"exception":"[object] (LogicException(code: 0): Please make sure the PHP Redis extension is installed and enabled. 
at /var/www/html/my-laravel-app/vendor/laravel/framework/src/Illuminate/Redis/Connectors/PhpRedisConnector.php:77)
```

Why? I didn't edit about redis configuration?
I wondered and looked into it, and it was caused by an error in reading the environment setting file due to editing .env.(The Parts that have nothing to do with Redis)


It's quite assertive that redis error is prioritized from all other errors and come to front...