Install Memcached on VPS to Speed Up PHP and Database
Memcached is an in-memory key-value store used to cache results from databases or time-consuming computations in RAM. The next time you request the same data, it responds in microseconds instead of querying the database again. It works great with WordPress, Laravel, CodeIgniter, and applications with heavy read workloads.
Install Memcached on Ubuntu/Debian
# Install Memcached daemon + PHP extension
apt update
apt install memcached libmemcached-tools -y
# Install PHP extension matching your version
apt install php8.2-memcached -y
# or php8.1-memcached / php8.0-memcached
# Enable it
systemctl enable --now memcached
# Check status
systemctl status memcached
Configure Memcached
nano /etc/memcached.conf
# Listen on localhost only (do not expose to internet)
-l 127.0.0.1
# Amount of RAM to use (MB) — recommend 10-20% of total RAM
-m 256
# Default port
-p 11211
# Number of concurrent connections
-c 1024
# Threads
-t 4
systemctl restart memcached
# Test with telnet
echo -e "stats\nquit" | nc 127.0.0.1 11211 | head -20
Using Memcached in PHP
<?php
$mc = new Memcached();
$mc->addServer('127.0.0.1', 11211);
// Store a value (TTL = 3600 seconds = 1 hour)
$mc->set('user_100', ['name' => 'Alice', 'email' => '[email protected]'], 3600);
// Retrieve a value
$user = $mc->get('user_100');
if ($user === false) {
// Not in cache → query DB
$user = $db->query("SELECT * FROM users WHERE id = 100")->fetch();
$mc->set('user_100', $user, 3600);
}
// Delete a cache entry
$mc->delete('user_100');
// Clear everything (careful!)
$mc->flush();
Cache Database Query Results with a Popular Pattern
<?php
function getCachedQuery(Memcached $mc, PDO $db, string $key, string $sql, array $params = [], int $ttl = 300): array
{
$result = $mc->get($key);
if ($mc->getResultCode() === Memcached::RES_NOTFOUND) {
$stmt = $db->prepare($sql);
$stmt->execute($params);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
$mc->set($key, $result, $ttl);
}
return $result ?: [];
}
// Usage
$products = getCachedQuery(
$mc, $db,
'products_featured',
'SELECT * FROM products WHERE featured = 1 ORDER BY id DESC LIMIT 20',
[],
600 // cache for 10 minutes
);
Enable Memcached in WordPress
Install W3 Total Cache or WP Super Cache plugin and select Object Cache = Memcached, or use a drop-in directly:
# Method 1: Use a drop-in from WordPress (free, no plugin needed)
# Create wp-content/object-cache.php
# Several projects available, such as memcached-redux
# Method 2: Add to wp-config.php
define('WP_CACHE', true);
define('MEMCACHE_HOST', '127.0.0.1');
define('MEMCACHE_PORT', 11211);
View Usage Statistics
# General stats
echo "stats" | nc 127.0.0.1 11211
# Check hit rate — should be above 80% to be worthwhile
echo "stats" | nc 127.0.0.1 11211 | grep -E "get_hits|get_misses"
# Using memcstat tool
memcstat --servers=127.0.0.1:11211
Memcached vs Redis — Which One to Choose?
- Memcached: Slightly faster for simple string cache, multi-threaded, uses less RAM
- Redis: Supports diverse data structures (list, hash, set), persistence, pub/sub, Lua scripting, cluster mode
- If you only need object cache / query cache → Memcached is sufficient
- If you need session store, queue, rate limiting → Redis is better
Memcached is easy to install, works fast, and noticeably reduces database load, especially for WordPress or PHP apps that query the same data repeatedly. The key is designing cache keys well and setting an appropriate TTL so that cached data doesn't become stale.
Verify Memcached is Working Correctly
# Check service status
systemctl status memcached
# Test connection and view stats
echo "stats" | nc 127.0.0.1 11211 | head -20
# Check hit rate (should be > 80%)
echo "stats" | nc 127.0.0.1 11211 | grep -E "get_hits|get_misses"
# hit_rate = get_hits / (get_hits + get_misses) * 100
# Using memcstat tool
memcstat --servers=127.0.0.1:11211
Common Issues & Troubleshooting
Error: "Connection refused" when connecting to port 11211
This happens when Memcached is not running or bound to the wrong address. Check with:
systemctl status memcached
# If not running, start it
systemctl start memcached
# Verify it's bound to 127.0.0.1
grep "^-l" /etc/memcached.conf
# Should show: -l 127.0.0.1
Error: PHP cannot find Memcached extension ("Class 'Memcached' not found")
You need to install the PHP extension and enable it matching your PHP version:
# Check your current PHP version
php -v
# Install the extension matching your version
apt install php8.2-memcached -y # or php8.1-memcached
# Reload PHP-FPM
systemctl reload php8.2-fpm
# Verify the extension is loaded
php -m | grep -i memcached
Error: Hit rate is low — Memcached isn't helping
This might be caused by TTL being too short or cache keys not being consistent, causing misses every time. Check:
# View evictions (if high, it means not enough RAM)
echo "stats" | nc 127.0.0.1 11211 | grep evictions
# View number of cached items
echo "stats" | nc 127.0.0.1 11211 | grep curr_items
# If evictions are high, increase -m in /etc/memcached.conf
Error: "SERVER_ERROR object too large for cache"
The value you're trying to store is larger than the 1 MB default limit. You need to increase the item size limit:
# Add to /etc/memcached.conf
-I 10m # Expand max item size to 10 MB
systemctl restart memcached
Error: WordPress Object Cache isn't working
The drop-in file must be in wp-content/ and the PHP extension must be loaded before WordPress can use it:
# Check if object-cache.php exists
ls /var/www/html/wp-content/object-cache.php
# Check if wp-config.php has WP_CACHE
grep "WP_CACHE" /var/www/html/wp-config.php
# Should show: define('WP_CACHE', true);
Frequently Asked Questions
What TTL should I set?
It depends on how often the data changes: product/category data that rarely changes → 1-24 hours, user-specific data → 5-15 minutes, query results that update hourly → 30-60 minutes. If you're unsure, start with 300 seconds and adjust based on the hit rate you observe.
How much RAM should I allocate to Memcached?
Recommend 10-25% of total RAM. For a 2GB VPS, allocate 256-512MB (-m 256 or -m 512). Check your stats to see how often evictions occur. If they happen frequently, increase -m or reduce TTL so old items expire faster.
Memcached or Redis for WordPress?
Both work well for WordPress Object Cache, but Redis has advantages in persistence (data doesn't disappear after restart) and more diverse data structures. If your server has plenty of RAM and you need session storage too, choose Redis. If you only need simple query/object cache and RAM is limited, Memcached is sufficient.