Stop Killing Your I/O: High-Performance PHP Session Management with Redis
It is 3:00 AM on a Tuesday. Your monitoring system is screaming. Your load average just spiked to 50.0 on a dual-core box. You check top and see almost zero CPU usage, but your wa (I/O wait) is hitting 80%. What is happening? Your traffic isn't even that high.
I have seen this scenario play out in dozens of Norwegian e-commerce deployments this year. The culprit is almost always the same archaic default setting: file-based sessions. When you rely on the default PHP configuration, every single visitor creates a small file in /var/lib/php/session. On a standard rotating HDD (hard disk drive), or even on cheap, oversold VPS hosting, the physical head of the disk cannot keep up with thousands of random read/write operations per second. Your server isn't out of CPU; it is choking on its own filesystem.
In this guide, we are going to fix this permanently using Redis. Unlike Memcached, Redis offers persistence, meaning you won't log out every user on your site just because you restarted the service. We will implement this on a standard Linux stack (CentOS 6 / Ubuntu 12.04 LTS), the kind we run daily at CoolVDS.
The Problem: flock(), Latency, and the Disk Bottleneck
By default, PHP's session.save_handler is set to files. When a user requests a page, PHP calls flock() on their session file. If you have AJAX requests firing simultaneously, or if your disk I/O is slow because your hosting provider puts 500 tenants on one spindle, those requests queue up. This creates a cascade of latency that no amount of code optimization can fix.
I recently audited a Magento store based in Oslo that was taking 4 seconds to load the checkout page. They blamed the database. I switched their session handling to Redis, and the load time dropped to 450ms. The database was fine; the disk was the bottleneck.
Why Redis?
Redis (Remote Dictionary Server) is an in-memory key-value store. It is blindingly fast. We are talking about sub-millisecond response times. With the release of Redis 2.6 just a few weeks ago, we now have Lua scripting support, but for session management, we primarily care about two things:
- Speed: It runs in RAM.
- Persistence: Unlike Memcached, Redis can write to disk asynchronously (RDB) or append-only file (AOF), so session data survives a reboot.
Step 1: Installing Redis (The 2012 Standard Way)
Let's assume you are running a CoolVDS KVM instance with CentOS 6 or Ubuntu 12.04. Avoid OpenVZ for high-performance databases; you want dedicated kernel resources.
On Ubuntu 12.04 LTS
The default repositories might have an older version. For the latest stable release, we often compile from source or use a PPA, but for stability, the package manager is safer.
sudo apt-get update
sudo apt-get install redis-server php5-redis
On CentOS 6
You will need the EPEL repository enabled.
rpm -Uvh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
yum install redis php-pecl-redis
chkconfig redis on
service redis start
Once installed, verify it is listening. Note that by default, Redis listens on 127.0.0.1:6379. Do not expose this port to the public internet.
$ netstat -nlpt | grep 6379
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 1452/redis-server
Step 2: Configuring Redis for Sessions
You don't need a complex cluster for this. A single instance on a robust VPS is sufficient for millions of hits. Open your Redis configuration file, usually located at /etc/redis/redis.conf.
We want to ensure we don't use 100% of the server's RAM and crash the OS. Set a limit.
maxmemory 256mb
maxmemory-policy allkeys-lru
The allkeys-lru setting is critical. It tells Redis: "If you run out of memory, delete the least recently used keys (old sessions) to make room for new ones." This keeps your server stable automatically.
Step 3: Connecting PHP to Redis
Now, we tell PHP to stop looking at the file system and start talking to Redis. You need to edit your php.ini file (often in /etc/php5/apache2/php.ini or /etc/php.ini).
Find the [Session] section and comment out the old handler. Add the following:
; session.save_handler = files
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379?weight=1&timeout=2.5"
Restart your web server to apply the changes.
# For Apache
service httpd restart
# OR
service apache2 restart
# For PHP-FPM
service php-fpm restart
Step 4: Verification
How do you know it is working? Use the redis-cli tool to monitor operations in real-time while you browse your website.
$ redis-cli monitor
OK
1353675401.562123 "GET" "PHPREDIS_SESSION:j9c7d83f..."
1353675401.562455 "SETEX" "PHPREDIS_SESSION:j9c7d83f..." "3600" "...session_data..."
If you see the GET and SETEX commands flying by as you click through your site, congratulations. You have just decoupled your user sessions from disk latency.
Infrastructure Matters: The Role of SSDs and Virtualization
Software configuration is only half the battle. The underlying hardware defines your ceiling. While Redis runs in RAM, it needs to persist data to disk (via RDB snapshots or AOF) to prevent data loss during a restart.
Pro Tip: Even with Redis, avoid "noisy neighbor" syndrome. Shared hosting or budget VPS providers using OpenVZ often oversell RAM. If the host node swaps, your "in-memory" Redis ends up on the physical disk anyway, destroying performance.
This is why at CoolVDS, we strictly use KVM (Kernel-based Virtual Machine). KVM provides hard memory isolation—if you buy 4GB of RAM, that RAM is reserved for you. Furthermore, as of 2012, we are aggressively rolling out Solid State Drive (SSD) storage across our Norwegian datacenters. Writing the Redis AOF log to a spinning 7200 RPM drive can block the event loop; writing it to an Enterprise SSD is nearly instantaneous.
Data Sovereignty and Latency
For developers targeting the Nordic market, physical location is paramount. Hosting your Redis instance in a datacenter in Germany or the US adds 30-100ms of latency to every single page load (since the session must be read before the page renders).
By deploying on VPS Norway infrastructure, you ensure:
- Low Latency: Sub-5ms ping times to Oslo via NIX (Norwegian Internet Exchange).
- Compliance: Adherence to the Personopplysningsloven (Personal Data Act) and the EU Data Protection Directive. Keeping user session data within Norwegian jurisdiction satisfies the Datatilsynet's strict requirements for data handling.
Conclusion
Moving sessions to Redis is one of the highest ROI changes you can make for a LAMP stack application in 2012. It removes the I/O bottleneck, stabilizes load averages, and provides a snappier experience for your end users.
However, putting a high-performance database on low-performance infrastructure is a recipe for disaster. You need guaranteed RAM and fast I/O to handle the persistence logs.
Ready to speed up your stack? Don't let legacy rotating disks hold you back. Deploy a Pure SSD VPS with CoolVDS today and experience the difference raw I/O performance makes. Configure your instance here.