memcache: A memcached client library.

[ bsd3, database, library ] [ Propose Tags ] [ Report a vulnerability ]

A client library for a Memcached cluster. Memcached is an in-memory key-value store typically used as a distributed and shared cache. Clients connect to a group of Memcached servers and perform out-of-band caching for things like SQL results, rendered pages, or third-party APIs.

It uses the Memcached Meta Text protocol and requires memcached 1.6.0 or newer. Username/password authentication is supported through memcached's -Y authfile mode; the binary protocol and SASL authentication are no longer supported. It supports connecting to a single, or a cluster of Memcached servers. When connecting to a cluster, consistent hashing is used for routing requests to the appropriate server. Timeouts, retrying failed operations, and failover to a different server are all supported, as is Amazon ElastiCache auto discovery.

Multi-get is supported through the pipelined getMany. Keys containing whitespace or control bytes are sent using the protocol's base64 binary-key mode.

Basic usage is:

{-# LANGUAGE OverloadedStrings #-}

import qualified Database.Memcache.Client as M

main :: IO ()
main = do
    mc <- M.newClient [M.ServerSpec "localhost" "11211" M.NoAuth] M.def
    _ <- M.set mc "key" "value" 0 0
    v <- M.get mc "key"
    print v

You should only need to import Database.Memcache.Client, but other modules are exposed for lower-level use. Version 0.4 is a breaking change from 0.3; see the changelog for details.


[Skip to Readme]

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 0.0.0, 0.0.1, 0.1.0.0, 0.1.0.1, 0.2.0.0, 0.2.0.1, 0.3.0.0, 0.3.0.1, 0.3.0.2, 0.4.0.0, 0.4.2.0
Change log CHANGELOG.md
Dependencies base (>=4.16 && <5), base64-bytestring (>=1.2.1.0), bytestring (>=0.11.4.0), data-default (>=0.7.1.1), hashable (>=1.4.2.0), network (>=3.1.4.0), network-uri (>=2.6.4.2), resource-pool (>=0.2.3.2), text (>=1.2.5.0), time (>=1.11.1.1), unliftio (>=0.2.25.0), vector (>=0.12.3.1) [details]
Tested with ghc >=9.2 && <9.3 || >=9.4 && <9.5 || >=9.6 && <9.7 || >=9.8 && <9.9 || >=9.10 && <9.11 || >=9.12 && <9.13 || >=9.14 && <9.15
License BSD-3-Clause
Copyright 2012-2026 David Terei.
Author David Terei <code@davidterei.com>
Maintainer David Terei <code@davidterei.com>
Uploaded by DavidTerei at 2026-10-20T06:50:17Z
Category Database
Home page https://github.com/dterei/memcache-hs#readme
Bug tracker https://github.com/dterei/memcache-hs/issues
Source repo head: git clone https://github.com/dterei/memcache-hs
Distributions LTSHaskell:0.3.0.2, Stackage:0.4.2.0
Reverse Dependencies 6 direct, 2 indirect [details]
Downloads 5662 total (19 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2026-10-20 [all 1 reports]

Readme for memcache-0.4.2.0

[back to package description]

memcache: Haskell Memcached Client

Hackage BSD3 License CI

A client library for a memcached cluster.

It supports the Meta Text memcached protocol and username/password authentication. Keys containing whitespace or control bytes are sent using its base64 binary-key mode. The encoded key must still fit within 250 bytes. It supports connecting to a single, or a cluster of memcached servers. When connecting to a cluster, consistent hashing is used for routing requests to the appropriate server.

This library requires memcached 1.6.0 or newer, the first release with the meta commands. Against older servers every operation is rejected with ERROR.

Authentication uses a memcached auth file with -Y authfile, an experimental ASCII-protocol auth mode added in memcached 1.5.15; the old binary protocol -S SASL mode is not supported. Enabling -Y also disables binary and UDP protocols on the server. getMany uses quiet misses, so a server connection failure can be indistinguishable from a cache miss.

The client operations, including getMany, use direct Meta Text encoders and the Response type; the former request and response wrapper types are no longer provided.

Usage

Add memcache to your package's build-depends. Everything most programs need is exported from Database.Memcache.Client:

{-# LANGUAGE OverloadedStrings #-}

module Main (main) where

import qualified Database.Memcache.Client as M

main :: IO ()
main = do
  -- Connect to memcached on 127.0.0.1:11211 with the default options.
  mc <- M.newClient [M.def] M.def

  -- Store a value with flags 0 that never expires, then read it back along
  -- with its flags and CAS version.
  _ <- M.set mc "greeting" "hello" 0 0
  hit <- M.get mc "greeting"
  case hit of
    Nothing -> putStrLn "miss"
    Just (value, _flags, version) -> do
      print value
      -- Only overwrite the value if it hasn't changed since we read it.
      updated <- M.cas mc "greeting" "hello again" 0 0 version
      putStrLn (maybe "changed by someone else" (const "updated") updated)

  -- Create the counter as 1 if it is missing, otherwise add 1 to it.
  visits <- M.increment mc "visits" 1 1 0 0
  print (fst <$> visits)

  M.quit mc

Keys and values are strict ByteStrings. Misses are returned as Nothing, while unexpected failures are thrown as a MemcacheError or a network IOException. Operations that take a CAS Version skip the check when it is 0. increment and decrement create a missing key with the given initial value, unless the expiration is maxBound. The Database.Memcache.Client documentation covers every operation, along with the timeouts, retries and failover configured through Options.

Servers and authentication

newClient takes one ServerSpec per server, and routes each key to one of them. Credentials are set per server:

  mc <- M.newClient
    [ M.ServerSpec "cache1.internal" "11211" (M.Auth "user" "secret")
    , M.ServerSpec "cache2.internal" "11211" (M.Auth "user" "secret")
    ]
    M.def

parseServerSpec, from Database.Memcache.Types, reads a server from a memcached://[user:password@]host[:port] URI instead. The host defaults to 127.0.0.1 and the port to 11211:

import Database.Memcache.Types (parseServerSpec)

  spec <- either fail pure (parseServerSpec "memcached://user:secret@cache1.internal:11211")
  mc <- M.newClient [spec] M.def

The server must be started with -Y <authfile>, where the auth file holds one username:password line per user. This library connects without TLS, so credentials and all data are sent unencrypted; only rely on them within a trusted network.

Amazon ElastiCache

Database.Memcache.ElastiCacheClient creates a client from an ElastiCache configuration endpoint (the address containing .cfg). It discovers the cluster's nodes, then refreshes the node list in a background thread on the given interval, in microseconds as for threadDelay:

import qualified Database.Memcache.ElastiCacheClient as EC

  endpoint <- either fail pure $
    EC.parseConfigurationEndpoint "memcached://mycluster.abc123.cfg.use1.cache.amazonaws.com:11211"
  mc <- EC.newClient M.def (60 * 1000000) endpoint

Licensing

This library is BSD-licensed.

Tools

This library also includes a few tools for manipulating and experimenting with memcached servers.

  • OpGen -- A load generator for memcached. Doesn't collect timing statistics, other tools like mutilate already do that very well. This tool is useful in conjunction with mutilate.
  • Loader -- A tool to load random data of a certain size into a memcached server. Useful for priming a server for testing.

Architecture Notes

We're relying on Data.Pool for thread safety right now. Each server has its own pool, and grabbing a connection from it (withResource) blocks other requests using that connection until the operation completes. getMany is the exception: it pipelines quiet Meta Text requests over one pooled connection.

By default each server's pool holds a single connection (soNumResources = 1), so concurrent operations against the same server wait for each other. Raising soNumResources in the ServerOptions set through optsServerOptions allows concurrent operations without requiring a separate pool implementation.

Either way, a pool is fine for now.

Other clients

Get involved!

We are happy to receive bug reports, fixes, documentation enhancements, and other improvements.

Please report bugs via the github issue tracker, and security issues as described in the security policy.

Master git repository:

  • git clone https://github.com/dterei/memcache-hs.git

Development

The package builds with Stack or cabal, on GHC 9.2 or newer:

stack build
stack test

cabal build
cabal test all

stack.yaml uses Stackage LTS 22.14 (GHC 9.6). The oldest and newest snapshots CI tests against have their own files, for example stack --stack-yaml stack-lts-20.26.yaml test for GHC 9.2.

There are two test suites:

  • spec holds the unit and property tests, which run against an in-process mock server and need nothing installed.
  • integration starts its own memcached servers on free local ports and tests against them, so it needs memcached 1.6 or newer on your PATH. Without it, the suite reports a single pending test instead of failing. memcached refuses to run as root without -u, so run the suite as an ordinary user.

CI lints with HLint 3.10, so please check that hlint . prints No hints before opening a pull request. For any user-visible change, add a line to CHANGELOG.md under an Unreleased heading at the top, adding the heading if it isn't there.

CI runs both build tools on every pull request. The CI workflow builds and tests with Stack against each stack*.yaml snapshot, and runs HLint and weeder. The Cabal workflow builds and tests with cabal on GHC 9.2 to 9.14, builds the library against the oldest dependency versions its bounds allow, and builds and tests the source distribution; it also runs every Monday, so a new dependency release that breaks the build shows up without a push. Both install memcached, so the integration suite runs in full.

Authors

This library is written and maintained by David Terei (code@davidterei.com).

Contributions have been made by the following great people: