redis-py

raw JSON →
7.4.0 verified Tue May 12 auth: no python install: verified quickstart: stale

Official Python client for Redis. Install is 'redis', import is 'redis'. Current version: 7.4.0 (Mar 2026). aioredis was merged into redis-py 4.2+ — use 'redis.asyncio' for async, not separate aioredis package. By default all responses are bytes — set decode_responses=True for strings. StrictRedis renamed to Redis in v3 but alias still works.

pip install redis
error ModuleNotFoundError: No module named 'redis.asyncio'
cause The 'redis.asyncio' module is not found, possibly due to an outdated 'redis' package or incorrect import.
fix
Ensure you have 'redis' version 4.2.0 or higher installed and import using 'import redis.asyncio as redis'.
error AttributeError: module 'redis' has no attribute 'asyncio'
cause The 'redis' package version is below 4.2.0, which does not include the 'asyncio' module.
fix
Upgrade the 'redis' package to version 4.2.0 or higher using 'pip install --upgrade redis'.
error AttributeError: module 'aioredis' has no attribute 'create_redis'
cause The 'create_redis' method was removed in 'aioredis' version 2.0.0.
fix
Use 'aioredis.from_url' instead of 'create_redis' to establish a connection.
error AttributeError: 'Redis' object has no attribute 'pubsub'
cause The 'pubsub' method is not available in the 'Redis' object due to incorrect usage or version incompatibility.
fix
Ensure you are using the correct version of 'aioredis' and refer to the updated documentation for the correct usage of 'pubsub'.
error AttributeError: module 'redis' has no attribute 'client'
cause The 'redis' package structure has changed, and the 'client' module is no longer directly accessible.
fix
Update your code to use 'from redis import Redis' instead of accessing 'redis.client' directly.
gotcha decode_responses defaults to False. All values returned as bytes (b'value') not strings. Silently breaks string comparisons, JSON parsing, and any code expecting str.
fix Always pass decode_responses=True unless you specifically need bytes: Redis(host='localhost', decode_responses=True)
breaking aioredis separate package is abandoned (last release 2021). 'import aioredis' still installs but is dead. Use 'import redis.asyncio as aioredis' from redis >= 4.2.
fix Replace 'import aioredis' with 'import redis.asyncio as aioredis'. API is compatible.
gotcha SSL connections require 'rediss://' (double s) URL scheme, not 'redis://'. Using wrong scheme silently connects without TLS or raises ConnectionError.
fix redis.from_url('rediss://host:6380') for TLS. 'redis://' is plaintext.
gotcha Upstash Redis requires TLS — always use rediss:// with Upstash URLs. Using redis:// with Upstash raises ConnectionError.
fix r = redis.from_url(os.environ['UPSTASH_REDIS_URL'], decode_responses=True) — Upstash provides rediss:// URLs automatically.
gotcha StrictRedis renamed to Redis in v3. StrictRedis still works as an alias but generates confusion in docs. Use Redis directly.
fix from redis import Redis not StrictRedis
gotcha Connection pool is shared by default. Do not call r.close() in web request handlers — it closes the pool. Use aclose() in async or let the pool manage connections.
fix Create one Redis client at app startup and reuse it. Only close on app shutdown.
gotcha ZADD argument order changed in v3. Old: zadd(name, member, score). New: zadd(name, {member: score}). Old order raises TypeError silently or produces wrong results.
fix r.zadd('leaderboard', {'player1': 100.0})
breaking Connection refused. This usually means the Redis server is not running or is not accessible at the specified host and port.
fix Ensure the Redis server is running and accessible from where the client is executing. Check firewall rules, network configuration, and that the Redis server is listening on the expected host/port.
breaking The client failed to connect to the Redis server because the connection was refused. This typically means the Redis server is not running, is not listening on the specified host/port, or a firewall is blocking the connection.
fix Ensure the Redis server is running and accessible at the specified host and port (default: localhost:6379). Check firewall rules if connecting remotely.
pip install 'redis[hiredis]'
python os / libc variant status wheel install import disk
3.10 alpine (musl) hiredis - - 0.32s 22.0M
3.10 alpine (musl) redis - - 0.32s 21.6M
3.10 slim (glibc) hiredis - - 0.23s 23M
3.10 slim (glibc) redis - - 0.22s 22M
3.11 alpine (musl) hiredis - - 0.43s 24.5M
3.11 alpine (musl) redis - - 0.43s 24.1M
3.11 slim (glibc) hiredis - - 0.35s 25M
3.11 slim (glibc) redis - - 0.38s 25M
3.12 alpine (musl) hiredis - - 0.63s 16.2M
3.12 alpine (musl) redis - - 0.60s 15.8M
3.12 slim (glibc) hiredis - - 0.59s 17M
3.12 slim (glibc) redis - - 0.63s 16M
3.13 alpine (musl) hiredis - - 0.58s 15.8M
3.13 alpine (musl) redis - - 0.62s 15.4M
3.13 slim (glibc) hiredis - - 0.55s 16M
3.13 slim (glibc) redis - - 0.55s 16M
3.9 alpine (musl) hiredis - - 0.28s 20.9M
3.9 alpine (musl) redis - - 0.27s 20.5M
3.9 slim (glibc) hiredis - - 0.23s 21M
3.9 slim (glibc) redis - - 0.23s 21M

Minimal redis-py 7.x sync operations with decode_responses.

# pip install redis
import redis

r = redis.Redis(
    host='localhost',
    port=6379,
    db=0,
    decode_responses=True  # str not bytes
)

# Basic operations
r.set('name', 'Alice')
print(r.get('name'))  # 'Alice'

# Expiry
r.setex('session', 3600, 'token123')  # TTL 1 hour

# Hash
r.hset('user:1', mapping={'name': 'Alice', 'age': '30'})
print(r.hgetall('user:1'))  # {'name': 'Alice', 'age': '30'}

# List
r.lpush('queue', 'task1', 'task2')
print(r.lrange('queue', 0, -1))

r.close()