Memcached Compatibility
Swytch provides a memcached-compatible server that can serve as a drop-in replacement for memcached in most use cases. This page documents the supported features and known differences.
# Start with defaults (64MB memory, port 11211)
swytch memcached
# Production setup with 4GB memory
swytch memcached -m 4096 -t 8 -c 10000
# Listen on specific address
swytch memcached -l 127.0.0.1 -p 11211
# Unix socket mode
swytch memcached -s /tmp/memcached.sock
| Command | Syntax | Description |
|---|---|---|
set | set <key> <flags> <exptime> <bytes> [noreply]\r\n<data>\r\n | Store a key unconditionally |
add | add <key> <flags> <exptime> <bytes> [noreply]\r\n<data>\r\n | Store only if key doesn’t exist |
replace | replace <key> <flags> <exptime> <bytes> [noreply]\r\n<data>\r\n | Store only if key exists |
append | append <key> <flags> <exptime> <bytes> [noreply]\r\n<data>\r\n | Append data to existing value |
prepend | prepend <key> <flags> <exptime> <bytes> [noreply]\r\n<data>\r\n | Prepend data to existing value |
cas | cas <key> <flags> <exptime> <bytes> <cas> [noreply]\r\n<data>\r\n | Check-and-set (compare-and-swap) |
| Command | Syntax | Description |
|---|---|---|
get | get <key> [<key> ...] | Retrieve one or more keys |
gets | gets <key> [<key> ...] | Retrieve with CAS token |
gat | gat <exptime> <key> [<key> ...] | Get and touch (update expiration) |
gats | gats <exptime> <key> [<key> ...] | Get and touch with CAS token |
| Command | Syntax | Description |
|---|---|---|
delete | delete <key> [noreply] | Delete a key |
flush_all | flush_all [<exptime>] [noreply] | Invalidate all items |
| Command | Syntax | Description |
|---|---|---|
incr | incr <key> <value> [noreply] | Increment numeric value |
decr | decr <key> <value> [noreply] | Decrement numeric value (floor at 0) |
| Command | Syntax | Description |
|---|---|---|
touch | touch <key> <exptime> [noreply] | Update expiration time |
| Command | Syntax | Description |
|---|---|---|
stats | stats | Get server statistics |
stats reset | stats reset | Reset statistics counters |
version | version | Get server version |
quit | quit | Close connection |
shutdown | shutdown | Shutdown server (requires -A flag) |
| Option | Default | Description |
|---|---|---|
-p <port> | 11211 | TCP port to listen on (0 = off) |
-l <addr> | 127.0.0.1 | Interface to listen on |
-s <path> | - | Unix socket path (disables TCP) |
-a <perms> | 0700 | Unix socket permissions (octal) |
-m <MB> | 64 | Memory limit in megabytes |
-c <num> | 1024 | Max simultaneous connections |
-t <num> | 4 | Sets GOMAXPROCS |
-b <num> | 1024 | Listen backlog queue limit |
-I <size> | 1m | Max item size (e.g., 1k, 1m, 1G) |
-C | - | Disable CAS (saves 8 bytes per item) |
-F | - | Disable flush_all command |
-A | - | Enable shutdown command |
-v | - | Verbose output (-v, -vv, -vvv) |
-P <file> | - | Write PID to file |
-k | - | Lock memory pages (mlockall) |
-r | - | Enable core dumps (setrlimit) |
-h | - | Show help |
-V | - | Show version |
| Option | Default | Description |
|---|---|---|
--dashboard | - | Enable web dashboard |
--dashboard-addr | :8080 | Dashboard HTTP address |
--metrics-port | - | Enable Prometheus metrics on this port |
--pprof | - | Enable pprof HTTP server on :6060 |
The stats command returns standard memcached statistics:
STAT pid <process_id>
STAT uptime <seconds>
STAT time <unix_timestamp>
STAT version <version_string>
STAT curr_connections <count>
STAT total_connections <count>
STAT cmd_get <count>
STAT cmd_set <count>
STAT cmd_flush <count>
STAT cmd_touch <count>
STAT get_hits <count>
STAT get_misses <count>
STAT get_expired <count>
STAT get_flushed <count>
STAT delete_hits <count>
STAT delete_misses <count>
STAT incr_hits <count>
STAT incr_misses <count>
STAT decr_hits <count>
STAT decr_misses <count>
STAT cas_hits <count>
STAT cas_misses <count>
STAT cas_badval <count>
STAT touch_hits <count>
STAT touch_misses <count>
STAT evictions <count>
STAT bytes_read <bytes>
STAT bytes_written <bytes>
STAT limit_maxbytes <bytes>
STAT bytes <current_bytes>
STAT curr_items <count>
STAT total_items <count>
STAT threads <count>
END
The following memcached features are not currently supported:
The newer meta text protocol commands are not implemented:
| Command | Name | Description |
|---|---|---|
mg | MetaGet | Get with optional metadata flags (TTL, hit status, etc.) |
ms | MetaSet | Set with metadata control (stale marking, CAS override) |
md | MetaDelete | Delete with invalidation/stale marking options |
mn | MetaNoop | No-op for pipeline completion signaling |
ma | MetaArithmetic | Increment/decrement with extended options |
me | MetaDebug | Debug/examine item metadata |
Extstore (-o ext_path=...) is not supported. Swytch has its own tiered storage implementation available in Redis
mode, but the memcached interface is memory-only.
- Binary protocol - Only ASCII/text protocol is supported
- SASL authentication - The
-Sflag is accepted but ignored - TLS/SSL - Not supported
stats cachedump- Disabled by default (security)stats slabs- Slabs are not used in this implementationstats items- Not implementedstats sizes- Not implementedstats conns- Not implementedstats settings- Not implementedwatch- Log watcher not implementedlru_crawler- LRU crawler commands not implemented (different eviction model)lru- LRU tuning commands not implementedcache_memlimit- Runtime memory limit adjustment not implementedverbosity- Runtime verbosity adjustment not implemented
- Daemon mode (
-d) - Use a process manager (systemd, supervisord) instead - User switching (
-u) - Run container/process as desired user instead - Disable evictions (
-M) - Memory-based eviction is always enabled - Multiple listen addresses - Only first address is used if multiple provided
- UDP (
-U) - Accepts the flag but UDP support is limited - Extstore options (
-o ext_path, etc.) - Not supported
Swytch uses a self-tuning frequency-based eviction algorithm comparable to S3-FIFO instead of memcached’s LRU. This typically results in better hit rates for workloads with frequency skew.
Unlike memcached’s slab allocator, Swytch uses Go’s memory allocator with a background goroutine that enforces memory limits. This simplifies configuration (no slab tuning) but means memory usage patterns differ.
Keys are limited to 250 bytes, matching memcached’s limit.
- Expiration times are interpreted the same way as memcached:
0= never expire1-2592000(30 days) = relative seconds from now>2592000= absolute Unix timestamp
- Expired items are lazily cleaned up on access
flush_all with a delay marks items created before the command as flushed once the delay passes. New items created
after the flush command are not affected.
# Connect with netcat
$ nc localhost 11211
# Store a value
set mykey 0 3600 5
hello
STORED
# Retrieve it
get mykey
VALUE mykey 0 5
hello
END
# Increment a counter
set counter 0 0 1
0
STORED
incr counter 5
5
# Check and set with CAS
gets mykey
VALUE mykey 0 5 42
hello
END
cas mykey 0 3600 5 42
world
STORED
# Get statistics
stats
STAT pid 12345
...
END
# Quit
quit
Enable the dashboard for real-time monitoring:
swytch memcached --dashboard --dashboard-addr :8080
Access at http://localhost:8080 to see:
- Hit/miss rates
- Memory usage
- Connection counts
- Per-shard cache statistics
Enable Prometheus metrics:
swytch memcached --metrics-port 9091
Scrape metrics from http://localhost:9091/metrics.
Swytch handles POSIX signals for graceful shutdown:
| Signal | Behavior |
|---|---|
SIGTERM | Graceful shutdown. Completes in-flight requests, flushes pending writes, exits |
SIGINT | Same as SIGTERM (Ctrl+C) |
SIGHUP | Not handled (no config reload) |
For container orchestration (Kubernetes, Docker), send SIGTERM to gracefully stop the server. Swytch will:
- Stop accepting new connections
- Complete in-flight commands
- Exit cleanly
There is no drain period configuration; shutdown completes as fast as pending work allows.
If you encounter issues or need features not listed here (such as meta-commands), please report them at the issue tracker.