fakeredis is a drop-in replacement for redis-py and valkey-py that runs entirely in-memory. Write tests that depend on Redis, Valkey, DragonflyDB, KeyDB, or KiviDB — without spinning up a real server, a container, or a network connection.
import fakeredis
r = fakeredis.FakeStrictRedis()
r.set("foo", "bar")
r.get("foo") # b'bar'That's it. No server to install, no port to manage, no teardown.
- 🚀 Zero setup — no Redis server, Docker, or network required. Pure Python.
- 🔌 Drop-in compatible — same API as
redis.Redisandredis.asyncio.Redis. - ⚡ Fast & isolated — in-memory, so tests run quickly and start from a clean slate.
- 🧩 Multi-backend — emulate Redis, Valkey, DragonflyDB, KeyDB, or KiviDB, and pin a specific server version.
- 📦 Redis Stack support — JSON, Bloom/Cuckoo filters, Count-Min Sketch, Top-K, T-Digest, TimeSeries, and vector sets.
- 🤝 Share or isolate state — one shared in-memory server across clients, or independent servers per test.
- 🌐 Real TCP mode — expose the fake server over a socket with
TcpFakeServer, for clients you can't inject.
pip install fakeredisOptional extras enable additional command families:
pip install "fakeredis[lua]" # EVAL / EVALSHA scripting
pip install "fakeredis[json]" # JSON.* commands
pip install "fakeredis[bf]" # Bloom / Cuckoo / Count-Min / Top-K filters
pip install "fakeredis[probabilistic]" # alias for the probabilistic filters
pip install "fakeredis[valkey]" # Valkey client compatibility
pip install "fakeredis[digest]" # DIGEST and DELEX IFDEQ / IFDNE (XXH3 digests)
pip install "fakeredis[vectorset]" # vector set (V*) commands, Python 3.11+Use it like redis.Redis:
import fakeredis
r = fakeredis.FakeStrictRedis()
r.lpush("queue", "a", "b", "c")
r.lrange("queue", 0, -1) # [b'c', b'b', b'a']Share one in-memory server between clients:
server = fakeredis.FakeServer()
r1 = fakeredis.FakeStrictRedis(server=server)
r2 = fakeredis.FakeStrictRedis(server=server)
r1.set("greeting", "hello")
r2.get("greeting") # b'hello' — same underlying dataAsync is supported too:
import fakeredis
async def main():
r = fakeredis.FakeAsyncRedis()
await r.set("foo", "bar")
await r.get("foo") # b'bar'Pin a server type and version:
# Behave like Redis 6 — which is what KeyDB is compatible with...
r = fakeredis.FakeStrictRedis(version=6)
# ...or like Valkey, DragonflyDB or KiviDB
r = fakeredis.FakeStrictRedis(server_type="valkey")
r = fakeredis.FakeStrictRedis(server_type="dragonfly")
r = fakeredis.FakeStrictRedis(server_type="kividb")import pytest
import fakeredis
@pytest.fixture
def redis_client():
return fakeredis.FakeStrictRedis()
def test_cache_set(redis_client):
redis_client.set("user:1", "alice")
assert redis_client.get("user:1") == b"alice"The fake clients above only help when you can hand one to the code under test. When the code opens its own
connection — or isn't Python at all — TcpFakeServer serves the same in-memory server over a real TCP socket, so
anything that speaks the Redis protocol can connect to it:
from threading import Thread
import redis
from fakeredis import TcpFakeServer
server = TcpFakeServer(("127.0.0.1", 6379), server_type="redis")
thread = Thread(target=server.serve_forever, daemon=True)
thread.start()
r = redis.Redis(host="127.0.0.1", port=6379) # a regular client, not a fake one
r.set("foo", "bar")
r.get("foo") # b'bar'
# When you are done:
r.close()
server.shutdown()
server.server_close()
thread.join()- Any client —
redis-py,valkey-py,redis-cli, or a client in another language. All connections share oneFakeServer, so they see the same data. - RESP2 and RESP3 — connections start in RESP2 and switch when the client sends
HELLO 3, as with a real server. Pub/sub and blocking commands work over the socket too. - Server type and version — pass
server_type("redis","valkey","dragonfly","kividb") andserver_version(defaults to(8, 0)), e.g.TcpFakeServer(address, server_type="valkey", server_version=(8, 1)). - Free port — bind to port
0to let the OS choose one, then read it back fromserver.server_address.
TcpFakeServer is a standard-library ThreadingTCPServer, handling each client connection
on its own thread. It is meant for tests and local development, not as a production Redis replacement.
See the official documentation for the full list of supported commands and configuration options.
fakeredis-py is developed and maintained for free. If it saves you time, please consider becoming a sponsor — it directly supports continued development.
Contributions are welcome! Check out the contributing guide and the open issues to get started.