By KFSys
System Administrator
Redis is an open-source, in-memory data structure store used as a database, cache, message broker, and streaming engine. It supports various data structures including strings, hashes, lists, sets, and sorted sets. Redis delivers sub-millisecond response times, making it ideal for real-time applications, caching layers, session storage, and message queues.
In this tutorial, you’ll learn how to install Redis on Ubuntu 24.04, configure it for production use, and integrate it with popular web frameworks including Laravel (PHP), Django (Python), and Express.js (Node.js). You’ll also learn how to use DigitalOcean’s Managed Redis database service as an alternative to self-hosting, which provides automatic backups, monitoring, and high availability without the operational overhead.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Accepted Answer
Before you begin this guide, you’ll need:
First, update your package index and install Redis from the Ubuntu repository.
sudo apt update
sudo apt install redis-server -y
After installation, verify that Redis is running:
sudo systemctl status redis-server
You should see output indicating that the service is active and running.
Open the Redis configuration file:
sudo nano /etc/redis/redis.conf
Make the following important security and performance changes:
Find the line with # requirepass foobared and uncomment it, replacing foobared with a strong password:
requirepass your_strong_password_here
Find the supervised directive and set it to systemd:
supervised systemd
Add or modify these lines to prevent Redis from consuming all available memory:
maxmemory 256mb
maxmemory-policy allkeys-lru
Save and close the file, then restart Redis:
sudo systemctl restart redis-server
Test your Redis connection:
redis-cli
Once inside the Redis CLI, authenticate with your password:
AUTH your_strong_password_here
Test with a simple command:
ping
You should receive PONG as a response. Exit with exit.
Laravel provides excellent built-in support for Redis through its cache and session systems.
sudo apt install php-redis -y
Navigate to your Laravel project directory:
cd /path/to/your/laravel/project
composer require predis/predis
Open your .env file and update the following values:
CACHE_DRIVER=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=your_strong_password_here
REDIS_PORT=6379
Here’s how to use Redis caching in your Laravel controllers:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;
class ProductController extends Controller
{
public function index()
{
// Cache data for 1 hour
$products = Cache::remember('products', 3600, function () {
return \App\Models\Product::all();
});
return view('products.index', compact('products'));
}
public function clearCache()
{
Cache::forget('products');
return response()->json(['message' => 'Cache cleared']);
}
// Using Redis directly
public function storeViewCount($productId)
{
Redis::incr("product:{$productId}:views");
$views = Redis::get("product:{$productId}:views");
return response()->json(['views' => $views]);
}
}
Create a job:
php artisan make:job ProcessOrder
Edit the job file:
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessOrder implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $order;
public function __construct($order)
{
$this->order = $order;
}
public function handle()
{
// Process the order
logger('Processing order: ' . $this->order->id);
}
}
Dispatch the job:
ProcessOrder::dispatch($order);
Run the queue worker:
php artisan queue:work redis
Django can use Redis for caching, session storage, and as a message broker for Celery.
pip install redis django-redis celery
Open your settings.py file and add the following configuration:
# settings.py
# Cache Configuration
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
'PASSWORD': 'your_strong_password_here',
}
}
}
# Session Configuration
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'default'
# Celery Configuration
CELERY_BROKER_URL = 'redis://127.0.0.1:6379/0'
CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/0'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
# views.py
from django.core.cache import cache
from django.shortcuts import render
from .models import Article
def article_list(request):
# Try to get from cache
articles = cache.get('article_list')
if articles is None:
# If not in cache, query database
articles = Article.objects.all()
# Store in cache for 15 minutes
cache.set('article_list', articles, 60 * 15)
return render(request, 'articles/list.html', {'articles': articles})
def clear_article_cache(request):
cache.delete('article_list')
return JsonResponse({'message': 'Cache cleared'})
# Using low-level Redis operations
import redis
def increment_page_views(request, page_id):
r = redis.Redis(
host='127.0.0.1',
port=6379,
password='your_strong_password_here',
db=0
)
r.incr(f'page:{page_id}:views')
views = r.get(f'page:{page_id}:views')
return JsonResponse({'views': int(views)})
Create a celery.py file in your project directory:
# celery.py
import os
from celery import Celery
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_project.settings')
app = Celery('your_project')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
Create a task:
# tasks.py
from celery import shared_task
from django.core.mail import send_mail
@shared_task
def send_email_task(subject, message, recipient_list):
send_mail(
subject,
message,
'from@example.com',
recipient_list,
fail_silently=False,
)
return f'Email sent to {len(recipient_list)} recipients'
Use the task in your views:
from .tasks import send_email_task
def register_user(request):
# ... user registration logic ...
# Send email asynchronously
send_email_task.delay(
'Welcome!',
'Thank you for registering.',
[user.email]
)
return JsonResponse({'message': 'Registration successful'})
Start the Celery worker:
celery -A your_project worker -l info
Node.js applications commonly use Redis for session management, caching, and real-time features.
npm install redis express-session connect-redis
Create a Redis client:
// redis.js
const redis = require('redis');
const client = redis.createClient({
host: '127.0.0.1',
port: 6379,
password: 'your_strong_password_here'
});
client.on('error', (err) => {
console.error('Redis error:', err);
});
client.on('connect', () => {
console.log('Connected to Redis');
});
module.exports = client;
// app.js
const express = require('express');
const session = require('express-session');
const RedisStore = require('connect-redis').default;
const redis = require('redis');
const app = express();
// Create Redis client
const redisClient = redis.createClient({
host: '127.0.0.1',
port: 6379,
password: 'your_strong_password_here'
});
redisClient.connect().catch(console.error);
// Configure session middleware
app.use(session({
store: new RedisStore({ client: redisClient }),
secret: 'your-secret-key',
resave: false,
saveUninitialized: false,
cookie: {
secure: false, // Set to true if using HTTPS
httpOnly: true,
maxAge: 1000 * 60 * 60 * 24 // 24 hours
}
}));
app.get('/login', (req, res) => {
req.session.userId = '12345';
req.session.username = 'john_doe';
res.send('Session created');
});
app.get('/profile', (req, res) => {
if (req.session.userId) {
res.json({
userId: req.session.userId,
username: req.session.username
});
} else {
res.status(401).send('Not authenticated');
}
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
// cacheMiddleware.js
const redisClient = require('./redis');
const cacheMiddleware = (duration) => {
return async (req, res, next) => {
const key = `cache:${req.originalUrl}`;
try {
const cachedData = await redisClient.get(key);
if (cachedData) {
return res.json(JSON.parse(cachedData));
}
// Store original res.json
const originalJson = res.json.bind(res);
// Override res.json
res.json = (data) => {
redisClient.setEx(key, duration, JSON.stringify(data));
originalJson(data);
};
next();
} catch (err) {
console.error('Cache error:', err);
next();
}
};
};
module.exports = cacheMiddleware;
Use the cache middleware:
// routes.js
const express = require('express');
const router = express.Router();
const cacheMiddleware = require('./cacheMiddleware');
const Product = require('./models/Product');
// Cache for 10 minutes
router.get('/products', cacheMiddleware(600), async (req, res) => {
const products = await Product.find();
res.json(products);
});
module.exports = router;
// rateLimiter.js
const redisClient = require('./redis');
const rateLimiter = (maxRequests, windowSeconds) => {
return async (req, res, next) => {
const ip = req.ip;
const key = `ratelimit:${ip}`;
try {
const requests = await redisClient.incr(key);
if (requests === 1) {
await redisClient.expire(key, windowSeconds);
}
if (requests > maxRequests) {
return res.status(429).json({
error: 'Too many requests, please try again later'
});
}
next();
} catch (err) {
console.error('Rate limiter error:', err);
next();
}
};
};
module.exports = rateLimiter;
Apply rate limiting:
const rateLimiter = require('./rateLimiter');
// Allow 100 requests per 15 minutes
app.use('/api/', rateLimiter(100, 900));
Here are some useful Redis patterns that work across all frameworks:
# Increment page views
INCR page:123:views
# Get current count
GET page:123:views
# Increment by specific amount
INCRBY user:456:points 10
# Add scores to sorted set
ZADD leaderboard 1500 "player1"
ZADD leaderboard 2300 "player2"
ZADD leaderboard 1800 "player3"
# Get top 10 players
ZREVRANGE leaderboard 0 9 WITHSCORES
# Get player rank
ZREVRANK leaderboard "player2"
# Subscribe to a channel
SUBSCRIBE notifications
# Publish to a channel
PUBLISH notifications "New message received"
# Set key with expiration (seconds)
SETEX temporary_token 3600 "abc123"
# Check remaining time
TTL temporary_token
# Set expiration on existing key
EXPIRE user_session 1800
DigitalOcean’s Managed Redis provides a fully managed, production-ready Redis cluster with automatic backups, monitoring, scaling, and high availability. This eliminates the need to manually configure, secure, and maintain your Redis instance.
production-redis)Once your database is ready, you’ll see the connection details:
Host: your-redis-cluster-do-user-123456-0.b.db.ondigitalocean.com
Port: 25061
Username: default
Password: your-generated-password
DigitalOcean also provides:
rediss://default:password@host:portFor enhanced security, add your application server to the trusted sources:
Update your .env file with the connection details:
CACHE_DRIVER=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis
REDIS_HOST=your-redis-cluster-do-user-123456-0.b.db.ondigitalocean.com
REDIS_PASSWORD=your-generated-password
REDIS_PORT=25061
REDIS_CLIENT=phpredis
# For TLS/SSL connections
REDIS_SCHEME=tls
If using TLS (recommended), update config/database.php:
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
'scheme' => env('REDIS_SCHEME', 'tcp'),
'ssl' => [
'verify_peer' => true,
'verify_peer_name' => true,
],
],
],
Update your settings.py:
# settings.py
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'rediss://default:your-generated-password@your-redis-cluster.db.ondigitalocean.com:25061/0',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
'CONNECTION_POOL_KWARGS': {
'ssl_cert_reqs': None, # For production, configure proper SSL verification
}
}
}
}
# Session Configuration
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'default'
# Celery Configuration
CELERY_BROKER_URL = 'rediss://default:your-generated-password@your-redis-cluster.db.ondigitalocean.com:25061/0'
CELERY_RESULT_BACKEND = 'rediss://default:your-generated-password@your-redis-cluster.db.ondigitalocean.com:25061/0'
CELERY_BROKER_USE_SSL = {
'ssl_cert_reqs': None
}
For production with proper SSL verification, download the CA certificate from DigitalOcean and configure:
import ssl
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'rediss://default:password@host:25061/0',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
'CONNECTION_POOL_KWARGS': {
'ssl_cert_reqs': ssl.CERT_REQUIRED,
'ssl_ca_certs': '/path/to/ca-certificate.crt',
}
}
}
}
Update your Redis client configuration:
// redis.js
const redis = require('redis');
const client = redis.createClient({
socket: {
host: 'your-redis-cluster-do-user-123456-0.b.db.ondigitalocean.com',
port: 25061,
tls: true,
rejectUnauthorized: false // For development; use proper certs in production
},
username: 'default',
password: 'your-generated-password'
});
client.on('error', (err) => {
console.error('Redis error:', err);
});
client.on('connect', () => {
console.log('Connected to DigitalOcean Managed Redis');
});
client.connect().catch(console.error);
module.exports = client;
For production with certificate verification:
const fs = require('fs');
const redis = require('redis');
const client = redis.createClient({
socket: {
host: 'your-redis-cluster.db.ondigitalocean.com',
port: 25061,
tls: true,
rejectUnauthorized: true,
ca: fs.readFileSync('/path/to/ca-certificate.crt')
},
username: 'default',
password: 'your-generated-password'
});
Update your Express session configuration for Managed Redis:
const express = require('express');
const session = require('express-session');
const RedisStore = require('connect-redis').default;
const redis = require('redis');
const app = express();
const redisClient = redis.createClient({
socket: {
host: 'your-redis-cluster.db.ondigitalocean.com',
port: 25061,
tls: true
},
username: 'default',
password: 'your-generated-password'
});
redisClient.connect().catch(console.error);
app.use(session({
store: new RedisStore({ client: redisClient }),
secret: 'your-secret-key',
resave: false,
saveUninitialized: false,
cookie: {
secure: true, // Required for production
httpOnly: true,
maxAge: 1000 * 60 * 60 * 24
}
}));
Automatic Backups: Daily backups with point-in-time recovery options
High Availability: Automatic failover with standby nodes (on Business and Professional plans)
Monitoring: Built-in metrics for memory usage, connections, CPU, and throughput
Scaling: Easy vertical scaling by upgrading your plan without downtime
Security: Encrypted connections via TLS, VPC networking support, and automatic security updates
Maintenance: Automatic patch management and version updates
Access monitoring from the DigitalOcean control panel:
Set up alerts for critical metrics:
DigitalOcean automatically creates daily backups. To restore:
Choose the right plan based on your needs:
Monitor your memory usage and scale accordingly. If you consistently use less than 50% of allocated memory, consider downsizing your plan.
View real-time commands:
redis-cli monitor
Get server statistics:
redis-cli INFO
Check memory usage:
redis-cli INFO memory
Enable RDB snapshots in redis.conf:
save 900 1
save 300 10
save 60 10000
Manually create a snapshot:
redis-cli BGSAVE
redis-cli FLUSHALL
You now have a solid foundation for using Redis with Laravel, Django, and Node.js applications, whether self-hosted on Ubuntu 24.04 or using DigitalOcean’s Managed Redis service. Redis excels at caching frequently accessed data, managing user sessions, handling background job queues, implementing rate limiting, and building real-time features.
When to choose self-hosted Redis:
When to choose DigitalOcean Managed Redis:
As you develop your applications, remember to monitor Redis memory usage, implement appropriate eviction policies, secure your Redis instance with strong passwords and firewall rules, and regularly backup your data if using Redis for persistent storage.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
Sign up and get $200 in credit for your first 60 days with DigitalOcean.*
*This promotional offer applies to new accounts only.