PHP applications that connect to ApsaraDB for Memcache through Apache use short-lived connections by default. Each short-lived connection incurs a socket handshake and a full Simple Authentication and Security Layer (SASL) re-authentication on every request — far more expensive than the cache lookup itself. Switching to persistent connections eliminates this per-request overhead and is the most effective way to improve throughput under load.
Prerequisites
Before you begin, make sure you have:
The PHP Memcached extension installed (not the memcache extension)
An ApsaraDB for Memcache instance endpoint and port
Valid SASL credentials (username and password)
How it works
The PHP Memcached extension achieves connection persistence through the persistent_id constructor parameter, not through a pconnect() method. All instances created with the same persistent_id string share a single connection pool.
From the PHP Memcached documentation:
Memcached::__construct([ string $persistent_id ])
Creates a Memcached instance. By default, the instance is destroyed after the request ends.
Specifying a persistent_id causes the instance — and its underlying connections — to persist
across requests. All instances sharing the same persistent_id share the same connection pool.
Call new Memcached('ocs') from any PHP request and you get a connection from the named pool rather than opening a new socket.
Enable persistent connections
The key pattern is to guard all initialization with a getServerList() check. If the pool already exists (non-empty server list), skip initialization entirely — including addServer() and all setOption() calls. Re-running those calls on an existing persistent pool can cause reconnections or silently convert a persistent connection into a short-lived one.
<?php
$memc = new Memcached('ocs'); // 'ocs' is the persistent_id — the name of the connection pool
if (count($memc->getServerList()) == 0) {
// Pool does not exist yet — initialize it.
// All setOption() calls must be inside this block.
// Calling setOption() on an existing pool can trigger a reconnection
// or silently downgrade the persistent connection to a short-lived one.
echo "New connection" . "<br>";
$memc->setOption(Memcached::OPT_COMPRESSION, false);
$memc->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
// OPT_TCP_NODELAY eliminates a fixed 40 ms latency that occurs when a get
// returns no value, caused by a known bug in the PHP Memcached extension.
$memc->setOption(Memcached::OPT_TCP_NODELAY, true);
// addServer() must also be inside this block.
// Calling addServer() on an existing pool duplicates the server entry
// and can cause client-side exceptions.
$memc->addServer("your_ip", 11212);
$memc->setSaslAuthData("user", "password");
} else {
echo "Now connections is:" . count($memc->getServerList()) . "<br>";
}
$memc->set("key", "value");
echo "Get from OCS: " . $memc->get("key");
// Do not call $memc->quit() here.
// quit() closes the underlying socket and converts the persistent connection
// back into a short-lived one.
?>
Three rules to follow:
getServerList()guard: Wrap all initialization in agetServerList() == 0conditional. Without this check, every request re-runsaddServer(), duplicates the server entry in the'ocs'pool, and causes client-side exceptions.All options inside the guard: Any
setOption()call outside the guard can trigger a reconnection or silently downgrade the persistent connection to a short-lived one. Keep every option call inside theifblock.No
quit()at the end: Calling$memc->quit()closes the underlying socket and converts the persistent connection back into a short-lived one. Remove it.
Verify the result
Place the code at /var/www/html/test.php and open http://your_ip:80/test.php in a browser.
The first eight requests each print:
New connection
Get from OCS: value
Subsequent requests reuse the existing connections — no new socket handshake, no re-authentication. Packet capture confirms this.
The number of "new connection" messages matches Apache's StartServers setting:
# Number of server processes to start
StartServers 8
Apache starts eight subprocesses at startup. Each subprocess initializes one connection under the 'ocs' pool, giving you eight persistent connections total. All subsequent requests across those subprocesses reuse those eight connections.
Persistence across page navigations
To confirm persistence across page navigations, copy the PHP file and keep the same persistent_id ('ocs'). Navigating between pages may switch to a different Apache subprocess — and therefore a different connection — but no socket reconnection or re-authentication occurs. This confirms that PHP Memcached persistent connections are working correctly.
In PHP-FPM mode, the behavior is the same: each FPM worker process holds its own persistent connection to the Memcache server, and that connection lives for the lifetime of the worker process.