Skip to main content

Redis Configuration

Connect to Redis for caching, session storage, real-time analytics, and in-memory data structures.

Connection Parameters

Required Fields

  • Host: Redis hostname
  • Port: 6379 (default)

Optional Fields

  • Password: Optional (for authenticated instances)
  • Database Number: Redis DB index (default: 0)
  • Use SSL/TLS: Enable for encrypted connections

Configuration Example

When creating a Redis data source, provide the following information:

FieldExample ValueNotes
Nameprod-redisUnique identifier
LabelProduction RedisDisplay name
Hostredis.example.comRedis hostname
Port6379Default Redis port
Password••••••••Optional, encrypted
Database Number0Default database
Use SSL/TLS✓ EnabledRecommended

Usage in Applications

Python Example (redis-py)

import os, json
import redis

# Parse STRONGLY_SERVICES environment variable
services = json.loads(os.getenv('STRONGLY_SERVICES', '{}'))
datasources = services.get('datasources', {})

# Get Redis data source
redis_config = datasources['prod-redis']
creds = redis_config['credentials']

# Create Redis connection
r = redis.Redis(
host=creds['host'],
port=creds['port'],
password=creds.get('password'),
db=creds.get('database', 0),
ssl=creds.get('ssl', False),
decode_responses=True # Automatically decode bytes to strings
)

# Basic operations
# Set value
r.set('user:1000', 'John Doe')

# Get value
name = r.get('user:1000')
print(name) # "John Doe"

# Set with expiration (in seconds)
r.setex('session:abc123', 3600, 'session_data')

# Check if key exists
exists = r.exists('user:1000')

# Delete key
r.delete('user:1000')

Python with Connection Pool

import redis

# Create connection pool for better performance
pool = redis.ConnectionPool(
host=creds['host'],
port=creds['port'],
password=creds.get('password'),
db=creds.get('database', 0),
ssl=creds.get('ssl', False),
decode_responses=True,
max_connections=10
)

# Use pool for connections
r = redis.Redis(connection_pool=pool)

Node.js Example (ioredis)

const Redis = require('ioredis');

// Parse STRONGLY_SERVICES environment variable
const services = JSON.parse(process.env.STRONGLY_SERVICES || '{}');
const datasources = services.datasources || {};

// Get Redis data source
const redisConfig = datasources['prod-redis'];
const creds = redisConfig.credentials;

// Create Redis connection
const redis = new Redis({
host: creds.host,
port: creds.port,
password: creds.password || null,
db: creds.database || 0,
tls: creds.ssl ? {} : undefined
});

// Basic operations
// Set value
await redis.set('user:1000', 'John Doe');

// Get value
const name = await redis.get('user:1000');
console.log(name); // "John Doe"

// Set with expiration
await redis.setex('session:abc123', 3600, 'session_data');

// Check if key exists
const exists = await redis.exists('user:1000');

// Delete key
await redis.del('user:1000');

Go Example (go-redis)

package main

import (
"context"
"encoding/json"
"fmt"
"os"
"time"

"github.com/go-redis/redis/v8"
)

func main() {
ctx := context.Background()

// Parse STRONGLY_SERVICES environment variable
var services map[string]interface{}
json.Unmarshal([]byte(os.Getenv("STRONGLY_SERVICES")), &services)

datasources := services["datasources"].(map[string]interface{})
redisConfig := datasources["prod-redis"].(map[string]interface{})
creds := redisConfig["credentials"].(map[string]interface{})

// Create Redis client
rdb := redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("%s:%v", creds["host"], creds["port"]),
Password: creds["password"].(string),
DB: int(creds["database"].(float64)),
})

// Basic operations
// Set value
err := rdb.Set(ctx, "user:1000", "John Doe", 0).Err()
if err != nil {
panic(err)
}

// Get value
val, err := rdb.Get(ctx, "user:1000").Result()
if err != nil {
panic(err)
}
fmt.Println(val)

// Set with expiration
err = rdb.Set(ctx, "session:abc123", "session_data", 1*time.Hour).Err()

// Check if key exists
exists, err := rdb.Exists(ctx, "user:1000").Result()
fmt.Printf("Key exists: %v\n", exists)

// Delete key
err = rdb.Del(ctx, "user:1000").Err()
}

Common Redis Operations

String Operations

# Set multiple key-value pairs
r.mset({
'user:1001': 'Alice',
'user:1002': 'Bob'
})

# Get multiple values
values = r.mget('user:1001', 'user:1002')

# Increment counter
r.incr('page:views')
r.incrby('page:views', 10)

# Decrement counter
r.decr('inventory:items')

Hash Operations

# Set hash field
r.hset('user:1000', 'name', 'John Doe')
r.hset('user:1000', 'email', 'john@example.com')

# Set multiple hash fields
r.hmset('user:1000', {
'name': 'John Doe',
'email': 'john@example.com',
'age': 30
})

# Get hash field
name = r.hget('user:1000', 'name')

# Get all hash fields
user = r.hgetall('user:1000')

# Get multiple hash fields
fields = r.hmget('user:1000', 'name', 'email')

List Operations

# Push to list
r.lpush('messages', 'Hello')
r.rpush('messages', 'World')

# Pop from list
message = r.lpop('messages')

# Get list range
messages = r.lrange('messages', 0, -1)

# Get list length
length = r.llen('messages')

Set Operations

# Add to set
r.sadd('tags', 'python', 'redis', 'cache')

# Get all members
tags = r.smembers('tags')

# Check membership
is_member = r.sismember('tags', 'python')

# Remove from set
r.srem('tags', 'cache')

# Set operations
r.sadd('set1', 'a', 'b', 'c')
r.sadd('set2', 'b', 'c', 'd')
intersection = r.sinter('set1', 'set2') # {'b', 'c'}
union = r.sunion('set1', 'set2') # {'a', 'b', 'c', 'd'}

Sorted Set Operations

# Add to sorted set (with scores)
r.zadd('leaderboard', {
'player1': 100,
'player2': 200,
'player3': 150
})

# Get rank
rank = r.zrank('leaderboard', 'player1')

# Get score
score = r.zscore('leaderboard', 'player1')

# Get top scores
top_players = r.zrevrange('leaderboard', 0, 9, withscores=True)

Caching Patterns

Simple Cache

def get_user(user_id):
# Try cache first
cached = r.get(f'user:{user_id}')
if cached:
return json.loads(cached)

# Cache miss - fetch from database
user = fetch_user_from_db(user_id)

# Store in cache (1 hour expiration)
r.setex(f'user:{user_id}', 3600, json.dumps(user))

return user

Cache-Aside Pattern

def get_product(product_id):
cache_key = f'product:{product_id}'

# Check cache
product = r.get(cache_key)
if product:
return json.loads(product)

# Load from database
product = db.query('SELECT * FROM products WHERE id = ?', product_id)

# Update cache
if product:
r.setex(cache_key, 3600, json.dumps(product))

return product

Write-Through Cache

def update_user(user_id, data):
# Update database
db.update('users', user_id, data)

# Update cache immediately
cache_key = f'user:{user_id}'
r.setex(cache_key, 3600, json.dumps(data))

Session Management

# Store session
def create_session(session_id, user_data):
r.setex(
f'session:{session_id}',
3600, # 1 hour expiration
json.dumps(user_data)
)

# Get session
def get_session(session_id):
session = r.get(f'session:{session_id}')
if session:
# Refresh expiration
r.expire(f'session:{session_id}', 3600)
return json.loads(session)
return None

# Delete session (logout)
def delete_session(session_id):
r.delete(f'session:{session_id}')

Pub/Sub Messaging

# Publisher
def publish_message(channel, message):
r.publish(channel, message)

# Subscriber
def subscribe_to_channel(channel):
pubsub = r.pubsub()
pubsub.subscribe(channel)

for message in pubsub.listen():
if message['type'] == 'message':
print(f"Received: {message['data']}")

Common Issues

Connection Refused

  • Verify host and port are correct
  • Check firewall rules allow connections
  • Ensure Redis is running: redis-cli ping
  • Check Redis is listening on correct interface in redis.conf

Authentication Failed

  • Verify password is correct
  • Check Redis configuration requires authentication: requirepass in redis.conf
  • Ensure password is set if Redis expects it

NOAUTH Error

  • Redis requires authentication but no password provided
  • Set password in Redis configuration or provide password in connection

Wrong Database Number

  • Redis has 16 databases by default (0-15)
  • Verify database number is within range
  • Use database 0 if unsure

Connection Timeout

  • Check network connectivity
  • Verify Redis is not overloaded
  • Increase timeout in client configuration
  • Check Redis max clients configuration

Best Practices

  1. Use Connection Pooling: Reuse connections for better performance
  2. Set Expiration: Always set TTL for cache keys to prevent memory bloat
  3. Key Naming Convention: Use consistent naming like prefix:id:field
  4. Enable Persistence: Configure RDB or AOF for data durability
  5. Monitor Memory: Track memory usage and set maxmemory policy
  6. Use Pipelining: Batch multiple commands for better performance
  7. Enable SSL/TLS: Use encryption for production environments
  8. Limit Key Size: Keep keys and values reasonably sized
  9. Use Appropriate Data Structures: Choose the right data type for your use case
  10. Handle Connection Errors: Implement retry logic and error handling

Performance Optimization

Pipelining

Execute multiple commands in one round trip:

# Without pipelining (multiple round trips)
for i in range(1000):
r.set(f'key:{i}', f'value:{i}')

# With pipelining (one round trip)
pipe = r.pipeline()
for i in range(1000):
pipe.set(f'key:{i}', f'value:{i}')
pipe.execute()

Transactions

Execute commands atomically:

pipe = r.pipeline()
pipe.multi()
pipe.incr('counter')
pipe.set('last_updated', time.time())
pipe.execute()

Monitoring

Check Connection

# Ping Redis
response = r.ping()
print(f"Redis is {'connected' if response else 'disconnected'}")

# Get server info
info = r.info()
print(f"Version: {info['redis_version']}")
print(f"Used memory: {info['used_memory_human']}")
print(f"Connected clients: {info['connected_clients']}")

Monitor Commands

# Get stats
stats = r.info('stats')
print(f"Total commands processed: {stats['total_commands_processed']}")
print(f"Instantaneous ops/sec: {stats['instantaneous_ops_per_sec']}")