Redis session storage for web application

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.
Development and maintenance of all types of websites:
Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Showing 1 of 1 servicesAll 2065 services
Redis session storage for web application
Medium
from 1 business day to 3 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    822
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    847
  • image_website-sbh_0.png
    Website development for SBH Partners
    999
  • image_website-_0.png
    Website development for Red Pear
    451

Setting Up Redis for Web Application Session Storage

File-based sessions don't scale horizontally — with two web servers, a user landing on the second server loses the session from the first. Redis solves this: centralized session storage accessible to all servers. Additionally, Redis is faster than file system under high load and allows setting TTL on each session.

Redis Configuration for Sessions

Sessions are data you can't lose (user logs out). Redis settings for sessions differ from cache settings:

# Persistence mandatory for sessions
appendonly yes
appendfsync everysec

# Eviction policy: don't touch TTL-less keys
# If Redis only for sessions:
maxmemory-policy volatile-lru

# If Redis shared (cache + sessions):
# Store sessions with TTL, policy volatile-lru protects from eviction

Separate Redis instance for sessions (recommended):

# /etc/redis/redis-sessions.conf
port 6380
bind 127.0.0.1
requirepass SessionsRedisPassword
maxmemory 512mb
maxmemory-policy volatile-lru
appendonly yes
appendfsync everysec
databases 1

Laravel Session Driver

config/session.php:

return [
    'driver' => env('SESSION_DRIVER', 'redis'),
    'lifetime' => env('SESSION_LIFETIME', 120),
    'expire_on_close' => false,
    'encrypt' => env('SESSION_ENCRYPT', true), // Session data encryption
    'files' => storage_path('framework/sessions'),
    'connection' => 'sessions',  // Separate redis connection
    'table' => 'sessions',
    'store' => null,
    'lottery' => [2, 100],
    'cookie' => env('SESSION_COOKIE', 'laravel_session'),
    'path' => '/',
    'domain' => env('SESSION_DOMAIN'),
    'secure' => env('SESSION_SECURE_COOKIE', true),  // HTTPS only
    'http_only' => true,
    'same_site' => 'lax',
];

Add sessions connection in config/database.php:

'redis' => [
    'sessions' => [
        'host' => env('REDIS_SESSION_HOST', '127.0.0.1'),
        'password' => env('REDIS_SESSION_PASSWORD'),
        'port' => env('REDIS_SESSION_PORT', '6380'),
        'database' => 0,
        'read_timeout' => 60,
        'persistent' => false,
    ],
],

.env:

SESSION_DRIVER=redis
SESSION_LIFETIME=120
SESSION_ENCRYPT=true
REDIS_SESSION_HOST=127.0.0.1
REDIS_SESSION_PASSWORD=SessionsRedisPassword
REDIS_SESSION_PORT=6380

Session Data Encryption

SESSION_ENCRYPT=true enables session content encryption via APP_KEY. Even with Redis access, session data is unreadable without the app key.

Important: APP_KEY must be unique and securely stored. Key rotation invalidates all sessions.

PHP-FPM + Redis Sessions (without Laravel)

Native PHP configuration for session storage in Redis:

# /etc/php/8.2/fpm/php.ini or conf.d/redis-sessions.ini
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6380?auth=SessionsRedisPassword&database=0&weight=1&timeout=2.5"
session.gc_maxlifetime = 7200
session.cookie_secure = 1
session.cookie_httponly = 1
session.cookie_samesite = Lax
session.use_strict_mode = 1

For Redis Cluster:

session.save_path = "tcp://redis-node1:6379?auth=password,tcp://redis-node2:6379?auth=password,tcp://redis-node3:6379?auth=password"

Managing Active Sessions

Redis lets you view and force-terminate sessions — hard to do with file sessions.

class SessionManager
{
    private Redis $redis;
    private string $prefix = 'laravel_session:';

    public function getUserSessions(int $userId): array
    {
        // If saving user_id -> session_id mapping on creation
        $sessionIds = $this->redis->smembers("user_sessions:{$userId}");

        $sessions = [];
        foreach ($sessionIds as $sessionId) {
            $data = $this->redis->get($this->prefix . $sessionId);
            if ($data) {
                $ttl = $this->redis->ttl($this->prefix . $sessionId);
                $sessions[] = [
                    'id' => $sessionId,
                    'ttl' => $ttl,
                    'data' => $this->decodeSession($data),
                ];
            }
        }

        return $sessions;
    }

    public function invalidateUserSessions(int $userId): void
    {
        $sessionIds = $this->redis->smembers("user_sessions:{$userId}");

        $pipe = $this->redis->pipeline();
        foreach ($sessionIds as $sessionId) {
            $pipe->del($this->prefix . $sessionId);
        }
        $pipe->del("user_sessions:{$userId}");
        $pipe->execute();
    }
}

On login handler — save user to session mapping:

// After successful login
$this->redis->sadd("user_sessions:{$user->id}", session()->getId());
$this->redis->expire("user_sessions:{$user->id}", config('session.lifetime') * 60);

Sticky Sessions vs. Centralized

Some use sticky sessions (nginx ip_hash) instead of centralized storage. Technical debt: one server dies — all sessions lost, load balancing uneven.

Redis sessions work correctly: any server serves any user.

Session Monitoring

# Active sessions count
redis-cli -p 6380 -a SessionsRedisPassword DBSIZE

# Average session TTL
redis-cli -p 6380 -a SessionsRedisPassword INFO keyspace

# Memory usage
redis-cli -p 6380 -a SessionsRedisPassword INFO memory | grep used_memory_human

# Individual session size (debug bloated sessions)
redis-cli -p 6380 -a SessionsRedisPassword DEBUG OBJECT "laravel_session:abc123"

If sessions unexpectedly large — check what's stored. Common mistake: storing large object collections instead of just IDs.

Timeline

Setting up Redis Sessions for Laravel app on one or multiple servers — 4–8 hours. Includes separate Redis instance setup, encryption config, session correctness verification post-deploy.