Install Redis on Debian 13 and connect it to Laravel
verified on 7 September 2026 · 4 min
Install redis-server and the php-redis extension, then set in the .env file: REDIS_CLIENT=phpredis, CACHE_STORE=redis, SESSION_DRIVER=redis and QUEUE_CONNECTION=redis. Careful, CACHE_DRIVER and QUEUE_DRIVER no longer exist: an unknown key is ignored without an error and the application keeps its default driver.
Redis acts as the cache, the session store and the queue backend of a Laravel application. Debian 13 ships Redis 8, and Laravel 13 talks to it by default through the phpredis extension, which is faster than the predis PHP library recommended for years.
This chapter follows on from installing Laravel on a Debian server, in the Web development track. Installation and integration checked on Debian 13 “trixie” with Laravel 13.30.1, on 2 September 2026.
Installing Redis and the PHP extension
sudo apt update
sudo apt install -y redis-server php-redisTwo packages, two jobs: redis-server is the server, php-redis is the extension that lets PHP talk to it. Check both:
redis-server --version
redis-cli ping
php -r 'echo extension_loaded("redis") ? phpversion("redis") : "absente", PHP_EOL;'Redis server v=8.0.2 sha=00000000:0 malloc=jemalloc-5.3.0 bits=64
PONG
6.2.0PONG confirms the service is running and answering. Enable it at boot:
sudo systemctl enable --now redis-server
sudo systemctl status redis-serverSecuring it before going any further
A Redis exposed on a public interface with no password can be read and modified by anyone. It is a classic incident, and Debian’s default configuration already covers the essentials, but check it anyway.
sudo nano /etc/redis/redis.conf# listen on the loopback interface only
bind 127.0.0.1 -::1
# reject unauthenticated connections coming from outside
protected-mode yes
# password, essential as soon as Redis is no longer on the same machine
requirepass un_mot_de_passe_long_et_aleatoiresudo systemctl restart redis-serverIf the application and Redis are on the same machine, keep bind 127.0.0.1: it is the safest setup, and the password becomes a second barrier rather than the only one.
Configuring Laravel
The keys in the .env file have been renamed over the versions. Here are the Laravel 13 ones, as they appear in the file generated at install time:
REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
CACHE_STORE=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redisThis is the most common mistake on the subject, and it is a silent one: an unknown key in the .env raises no error at all, the application simply carries on with its default driver. QUEUE_DRIVER was renamed QUEUE_CONNECTION back in Laravel 5.7, and CACHE_DRIVER became CACHE_STORE in Laravel 11.
Reload the configuration and check what the application actually uses. Careful, the config cache freezes these values:
php artisan config:clear
php artisan tinker --execute='
printf("client : %s\n", config("database.redis.client"));
printf("cache : %s\n", config("cache.default"));
printf("queue : %s\n", config("queue.default"));
printf("session : %s\n", config("session.driver"));
'client : phpredis
cache : redis
queue : redis
session : redisChecking that it really works
A setting that is accepted is not a setting that works. Write a value and read it back:
php artisan tinker --execute='
Cache::put("gk_test", "valeur", 60);
printf("Cache::get : %s\n", Cache::get("gk_test"));
printf("Redis::ping : %s\n", Illuminate\Support\Facades\Redis::ping());
printf("version : %s\n", Illuminate\Support\Facades\Redis::info()["redis_version"]);
'The full facade name is required here: once the phpredis extension is installed, Redis refers to the extension’s class, Laravel no longer registers its alias, and a plain Redis::ping() fails with “Non-static method Redis::ping() cannot be called statically”.
Cache::get : valeur
Redis::ping : 1
version : 8.0.2A redis-cli --scan on database 0 returns nothing, and you conclude the cache is not working. In reality, Laravel writes the cache to database 1 and stacks two prefixes. The key from the example above is stored under this exact name:
redis-cli -n 1 --scanlaravel-database-laravel-cache-gk_testThe first prefix comes from database.redis.options.prefix, the second from cache.prefix. Database 1 is set by database.redis.cache.database, which keeps the cache away from the queues and the sessions.
phpredis or predis
phpredis | predis | |
|---|---|---|
| Nature | C extension | PHP library |
| Installation | apt install php-redis | composer require predis/predis |
| Laravel 13 default | yes | no |
| Root access to the server | required | not required |
Go for phpredis as soon as you administer the machine: the protocol is handled in C. predis remains useful on shared hosting where you cannot install an extension. In that case:
composer require predis/predisREDIS_CLIENT=predisProcessing the queues
Switching QUEUE_CONNECTION over to Redis is not enough: you need a process that consumes the jobs.
php artisan queue:work redis --tries=3The logs of those processes live under storage/logs, the path returned by storage_path() among the application paths. In production, that process has to be supervised so it restarts after a crash or a deployment. Supervisor is the usual tool, but a systemd unit does the job just as well. Remember to restart the workers after every deployment, otherwise they keep running the old code loaded in memory:
php artisan queue:restartCommon errors
redis-cli -n 1 --scan.bind 127.0.0.1 while the application sits on the same machine, and add requirepass as soon as that stops being true.queue:work process is running.