Connect to Redis
How to connect to Redis and perform basic operations in Python, JavaScript, and Java.
Overview
Redis is an in-memory data structure store used for caching, session management, real-time analytics, and message brokering. Connecting to Redis and using its core data types efficiently is a foundational backend skill. The following demonstrates how to basic operations in Python, JavaScript, and Java.
When to Use
Use this resource when:
- Implementing caching layers to reduce database load
- Building session stores for stateless web applications
- Creating real-time leaderboards, rate limiters, or message queues
Solution
Python
import redis
r = redis.Redis(
host='localhost',
port=6379,
db=0,
decode_responses=True
)
# Strings
r.set('user:1:name', 'Alice', ex=3600)
name = r.get('user:1:name')
# Lists
r.lpush('queue:tasks', 'task_1')
task = r.brpop('queue:tasks', timeout=5)
# Hashes
r.hset('user:1', mapping={'email': 'alice@example.com', 'role': 'admin'})
user = r.hgetall('user:1')
JavaScript
const Redis = require('ioredis');
const redis = new Redis({
host: 'localhost',
port: 6379,
db: 0
});
// Strings
await redis.set('user:1:name', 'Alice', 'EX', 3600);
const name = await redis.get('user:1:name');
// Lists
await redis.lpush('queue:tasks', 'task_1');
const task = await redis.brpop('queue:tasks', 5);
// Hashes
await redis.hset('user:1', 'email', 'alice@example.com', 'role', 'admin');
const user = await redis.hgetall('user:1');
Java
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class RedisExample {
private final JedisPool pool = new JedisPool("localhost", 6379);
public void stringOps() {
try (Jedis jedis = pool.getResource()) {
jedis.setex("user:1:name", 3600, "Alice");
String name = jedis.get("user:1:name");
}
}
public void listOps() {
try (Jedis jedis = pool.getResource()) {
jedis.lpush("queue:tasks", "task_1");
var task = jedis.brpop(5, "queue:tasks");
}
}
public void hashOps() {
try (Jedis jedis = pool.getResource()) {
jedis.hset("user:1", "email", "alice@example.com");
jedis.hset("user:1", "role", "admin");
Map<String, String> user = jedis.hgetAll("user:1");
}
}
}
Explanation
Redis stores data in memory, making reads and writes extremely fast (sub-millisecond). Strings are the simplest type, often used for caching serialized objects. Lists implement queues (LPUSH + BRPOP for blocking consumption). Hashes store objects with multiple fields compactly. All three examples use solid connection management: Python redis.Redis handles reconnections, JavaScript ioredis supports clustering and pub/sub, and Java JedisPool reuses connections via pooling.
Variants
| Technology | Approach | Notes |
|---|---|---|
| Python | redis-py | Official client, supports async via aredis |
| JavaScript | node-redis | Alternative to ioredis, native Promise support |
| Java | Lettuce | Reactive, async Redis client for Spring |
What Works
- Use connection pooling in all languages to avoid connection exhaustion
- Set explicit expiration (
EX,PX,EXAT) on cache keys to prevent unbounded memory growth - Use
decode_responses=Truein Python to get strings instead of bytes - Prefer
BRPOP/BLPOPfor queue consumption to avoid busy-waiting - Use Redis pipelines (
.pipeline()/.multi()) to batch multiple commands and reduce RTT
Common Mistakes
- Storing large objects (>1 MB) in single keys, causing latency spikes
- Not handling connection failures, causing cascading app errors when Redis is unavailable
- Using Redis as a primary database instead of a cache or transient store
- Forgetting to set TTLs, leading to memory exhaustion and OOM kills
- Using
KEYScommand in production, which blocks the entire Redis instance
Performance Tips
-
Use
PIPELINEfor bulk operations. Reduces network round-trips by sending multiple commands in one batch. -
Use
MGET/MSETfor multiple key operations. Faster than individualGET/SETcalls:
values = r.mget('key1', 'key2', 'key3')
r.mset({'key1': 'val1', 'key2': 'val2'})
- Use
HGETALLsparingly on large hashes. If a hash has many fields, useHSCANto iterate:
for field, value in r.hscan_iter('large_hash', count=100):
print(field, value)
- Enable
lazyfree-lazy-evictionin Redis 4.0+. Async deletion prevents latency spikes during key eviction:
# redis.conf
lazyfree-lazy-eviction yes
lazyfree-lazy-expire yes
lazyfree-lazy-server-del yes
- Use
OBJECT ENCODINGto inspect storage. Redis uses compact encodings for small data structures. Check if your keys are using efficient encodings:
encoding = r.object('encoding', 'mykey')
print(f"Encoding: {encoding}") # e.g., ziplist, hashtable, int Frequently Asked Questions
Should I use Redis as my primary database?
No. Redis is an in-memory store best suited for caching, sessions, queues, and real-time data. Use it alongside a persistent database like PostgreSQL or MySQL.
How do I handle Redis cluster mode?
Use cluster-aware clients: redis-py-cluster (Python), ioredis with new Redis.Cluster() (JS), or JedisCluster / Lettuce (Java).
What is the difference between EX and PX in Redis?
EX sets expiration in seconds. PX sets expiration in milliseconds. Both achieve the same goal; use whichever fits your precision requirements.
Python with pipelines and transactions
import redis
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
# Pipeline: batch multiple commands to reduce RTT
pipe = r.pipeline()
pipe.set('user:1:name', 'Alice', ex=3600)
pipe.set('user:1:email', 'alice@example.com', ex=3600)
pipe.hset('user:1', mapping={'name': 'Alice', 'email': 'alice@example.com'})
results = pipe.execute()
print(results) # [True, True, 1]
# Transaction with MULTI/EXEC
pipe = r.pipeline(transaction=True)
pipe.multi()
pipe.set('counter', 0)
pipe.incr('counter')
pipe.incr('counter')
results = pipe.execute()
print(results) # [True, 1, 2]
JavaScript with sorted sets and pub/sub
const Redis = require('ioredis');
const redis = new Redis({ host: 'localhost', port: 6379 });
// Sorted sets: leaderboards
await redis.zadd('leaderboard', 100, 'alice', 85, 'bob', 120, 'charlie');
const topPlayers = await redis.zrevrange('leaderboard', 0, 9, 'WITHSCORES');
// ['charlie', '120', 'alice', '100', 'bob', '85']
// Pub/Sub
const subscriber = new Redis({ host: 'localhost', port: 6379 });
const publisher = new Redis({ host: 'localhost', port: 6379 });
await subscriber.subscribe('notifications');
subscriber.on('message', (channel, message) => {
console.log(`Received on ${channel}: ${message}`);
});
await publisher.publish('notifications', JSON.stringify({ event: 'user_joined', userId: 42 }));
Java with JedisPool and Lua scripting
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import java.util.List;
public class RedisAdvanced {
private final JedisPool pool;
public RedisAdvanced(String host, int port) {
this.pool = new JedisPool(host, port);
}
public void rateLimit(String userId, int maxRequests, int windowSeconds) {
try (Jedis jedis = pool.getResource()) {
String key = "rate:" + userId;
String luaScript =
"local current = redis.call('INCR', KEYS[1]) " +
"if current == 1 then " +
" redis.call('EXPIRE', KEYS[1], ARGV[2]) " +
"end " +
"return tonumber(current) <= tonumber(ARGV[1])";
Object allowed = jedis.eval(
luaScript, 1, key,
String.valueOf(maxRequests), String.valueOf(windowSeconds)
);
System.out.println("Request allowed: " + allowed);
}
}
public void pipelineExample() {
try (Jedis jedis = pool.getResource()) {
var pipe = jedis.pipelined();
pipe.set("key1", "value1");
pipe.set("key2", "value2");
pipe.sync();
}
}
}
Python async with redis-py
import asyncio
import redis.asyncio as aioredis
async def main():
r = aioredis.Redis(host='localhost', port=6379, decode_responses=True)
# Async string operations
await r.set('async:key', 'value', ex=60)
value = await r.get('async:key')
# Async pipeline
pipe = r.pipeline()
pipe.set('a', 1)
pipe.set('b', 2)
pipe.get('a')
results = await pipe.execute()
print(results) # [True, True, b'1']
await r.close()
asyncio.run(main())
Related Resources
Connect to MySQL
How to connect to MySQL databases in Python, JavaScript, and Java.
RecipeConnect to PostgreSQL
How to connect to PostgreSQL databases in Python, JavaScript, and Java.
PatternCache-Aside Pattern
Load data into the cache on demand from the backing store. A caching pattern that gives the application full control over what and when to cache.
RecipeRedis Cache Patterns for High-Performance Applications
How to implement cache-aside, write-through, and write-behind patterns with Redis to reduce database load and improve response times
PatternAbstract Factory Pattern
Create families of related objects without specifying concrete classes. A creational design pattern for consistent object families.
RecipeExecute Raw SQL
How to execute raw SQL queries safely with parameterized statements.