Skip to content
Peter Goldstein edited this page Nov 15, 2021 · 1 revision

Default Behavior

By default a Dalli::Client instance is safe to share between threads. The execution of commands against the underlying servers is gated by locks, such that a lock is acquired and released each time a request is made to the memcached server and the corresponding response is processed. This prevents concurrent access to the underlying socket by multiple threads.

For some operations that may involve multiple requests and responses, but still require exclusive access to the memcached connection, - for example, when performing a multiget operation - the locking may be coarser. A multiget operation will hold locks on all

All of this locking comes with a non-trivial cost. Even access to uncontended locks can have a performance impact, and that impact can increase when there is meaningful contention on the lock. Since the locking is fairly fine grained - essentially every client API call acquires and then releases a lock.

In many cases this cost won't matter - it's dwarfed by other considerations. But in some instances - especially in circumstances where the Dalli::Client instance is being held by a thread for a long time and performing a large number of operations - this locking can have a meaningful performance impact.

Disabling Thread Safety and Using a Connection Pool

It is possible to disable this locking by setting the threadsafe option to false when initializing the Dalli::Client instance. A Dalli::Client instance that is created this way should not be freely shared between threads.

Instead, one should use a connection pool to control access to the Dalli::Client instances. The connection_pool gem is a good choice for this. Here is an example of how one might create such a pool:

require 'dalli'
require 'connection_pool'

pool_options = { size: 10 }
client_options = { ... }
servers_configuration = ...
pool = ConnectionPool.new(pool_options) { Dalli::Client.new(servers_configuration, client_options.merge(threadsafe: false)) }

Please consult the connection_pool gem documentation for more information.