Stop Letting /var/lib/php/sessions Kill Your Throughput
I watched a perfectly good Magento deployment hit the wall last week. It wasn't the database, and the Apache memory footprint was fine. The load average, however, was skyrocketing past 20 on a quad-core box. The culprit? iowait.
Every time a user clicked a link, PHP was locking a session file on the disk. When you have fifty concurrent users, that's manageable. When you have five hundred, the disk heads (even on 15k RPM SAS drives) physically cannot move fast enough to handle the stat(), lock(), read(), and write() system calls for every single HTTP request. Your fancy application is being strangled by the filesystem.
If you are serious about high-availability hosting, you need to move state out of the filesystem and into memory. In 2012, the battle is between Memcached and Redis. While Memcached is great, Redis gives us persistence and richer data types, making it the superior choice for session management in my book.
The Architecture: Why RAM Wins
Disk I/O is the most expensive operation in computing. Accessing RAM takes nanoseconds; accessing disk takes milliseconds. That is a magnitude of difference that optimization cannot fix. By moving sessions to Redis, we achieve two things:
- Eliminate IO Blocking: PHP no longer waits for the disk to spin up or seek.
- Decoupling: If you add a second web server behind a load balancer (like HAProxy), both servers can read sessions from a central Redis instance. You cannot do that easily with file-based sessions without a slow NFS share.
Pro Tip: Many providers oversell their RAM on OpenVZ containers using "burst" memory that isn't actually there when you need it. For Redis, you need guaranteed physical RAM. This is why we rely on KVM virtualization at CoolVDS—if you pay for 4GB RAM, that memory block is reserved for your kernel, not shared with the noisy neighbors next door.
Step-by-Step Implementation
Let's assume you are running a standard CentOS 6.3 or Ubuntu 12.04 LTS environment. Here is how we switch from disk to Redis.
1. Install Redis
On Ubuntu 12.04 (Precise), it is straightforward:
apt-get update
apt-get install redis-server
On CentOS 6, you will need the EPEL repository first:
rpm -Uvh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-7.noarch.rpm
yum install redis
chkconfig redis on
service redis start
2. Configure Redis for LRU (Least Recently Used)
You don't want your Redis instance to crash because it filled up with old sessions. We need to tell Redis to evict old keys when it hits a memory limit. Edit /etc/redis/redis.conf:
# Set a limit, e.g., 256mb for sessions
maxmemory 256mb
# Tell Redis to remove the oldest keys when full
maxmemory-policy allkeys-lru
Restart Redis to apply the changes: /etc/init.d/redis-server restart.
3. The PHP Driver
We need the phpredis extension. It compiles faster and is more stable than using a pure PHP client library.
Ubuntu:
apt-get install php5-redis
CentOS (via PECL):
yum install php-devel php-pear make gcc
pecl install redis
Once installed, make sure to add extension=redis.so to your php.ini or /etc/php.d/redis.ini.
The Switch: Configuring php.ini
Now, tell PHP to stop looking at the file system. Locate your php.ini file (usually /etc/php5/apache2/php.ini or /etc/php.ini) and find the [Session] block.
Change these two lines:
; session.save_handler = files
session.save_handler = redis
; session.save_path = "/var/lib/php/session"
session.save_path = "tcp://127.0.0.1:6379"
If you are using a remote Redis server (highly recommended for load balancing), replace 127.0.0.1 with the internal IP of your CoolVDS Redis instance.
Finally, restart your web server:
service apache2 restart
Or for Nginx/PHP-FPM users:
service php-fpm restart
Verifying the Performance Gain
To ensure it's working, log into your server and use the redis-cli tool. Generate some traffic to your site, then run:
redis-cli monitor
You should see a stream of GET and SETEX commands flying by. This is the sound of your disk not being thrashed.
| Metric | File System Session | Redis Session |
|---|---|---|
| Latency per Request | 2-50ms (variable on load) | < 0.5ms (consistent) |
| Locking Issues | High (flock blocking) | Low (atomic operations) |
| Scalability | Single Server Only (or slow NFS) | Multi-Server Ready |
Data Sovereignty & Latency in Norway
Since we are operating under Norwegian jurisdiction, complying with the Personopplysningsloven (Personal Data Act) is mandatory. Sessions often contain user identifiers or cart data. Storing this data in a US-based cloud can introduce legal headaches regarding Safe Harbor frameworks.
Furthermore, latency is a killer. If your web server is in Oslo and your database is in Frankfurt, you are adding 20-30ms to every single session start. That adds up.
This is where infrastructure location matters. Hosting your Redis instance on a CoolVDS server in Oslo ensures you are physically close to the NIX (Norwegian Internet Exchange). We see latency between local instances as low as 0.2ms. When you are doing hundreds of Redis calls per page load, that proximity keeps your Time-To-First-Byte (TTFB) exceptionally low.
Final Thoughts
Moving sessions to Redis is one of the highest ROI changes you can make to a PHP stack in 2012. It reduces CPU wait times, lowers load averages, and prepares your architecture for horizontal scaling.
Don't let your infrastructure be the bottleneck. If you need a sandbox to test this configuration, spin up a CoolVDS instance today. Our SSD-backed storage and KVM architecture provide the stable baseline required for high-performance data stores.