DEV Community

Anjali Gurjar
Anjali Gurjar

Posted on

Redis

Let's go through each of these Redis use cases with explanations, why they're useful, and code examples for implementation using Node.js and Redis.


1. Caching: Storing Frequently Accessed Data to Reduce Database Load

Why?

  • Caching improves application performance by reducing database queries for frequently requested data.
  • It minimizes latency and decreases the load on the database.

How?

  • Store the result of expensive database queries in Redis.
  • Return cached data if it exists, otherwise query the database, store the result in Redis, and return it.

Example Code:

const express = require('express');
const redis = require('redis');
const { Sequelize, DataTypes } = require('sequelize');

const app = express();
const redisClient = redis.createClient();
const sequelize = new Sequelize('database', 'username', 'password', {
  host: 'localhost',
  dialect: 'mysql',
});

const Product = sequelize.define('Product', {
  name: DataTypes.STRING,
  price: DataTypes.FLOAT,
});

redisClient.connect();

app.get('/products/:id', async (req, res) => {
  const productId = req.params.id;
  const cacheKey = `product:${productId}`;

  // Check cache
  const cachedData = await redisClient.get(cacheKey);
  if (cachedData) {
    return res.json(JSON.parse(cachedData));
  }

  // If not cached, query database
  const product = await Product.findByPk(productId);
  if (product) {
    // Store in cache and set expiration (e.g., 60 seconds)
    await redisClient.setEx(cacheKey, 60, JSON.stringify(product));
    return res.json(product);
  } else {
    return res.status(404).json({ message: 'Product not found' });
  }
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});
Enter fullscreen mode Exit fullscreen mode

2. Session Management: Storing User Sessions in Web Applications

Why?

  • Redis stores sessions in-memory, allowing for fast access and scalability.
  • It helps maintain user sessions even if the server restarts (when configured with persistence).

How?

  • Use Redis as a session store with express-session to manage user login states.

Example Code:

const session = require('express-session');
const RedisStore = require('connect-redis')(session);

app.use(session({
  store: new RedisStore({ client: redisClient }),
  secret: 'your_secret_key',
  resave: false,
  saveUninitialized: false,
  cookie: { secure: false, maxAge: 60000 }
}));

app.post('/login', (req, res) => {
  // Assuming user authentication is done here
  req.session.user = { id: 1, username: 'Anjai' };
  res.send('Logged in');
});

app.get('/profile', (req, res) => {
  if (req.session.user) {
    res.send(`Welcome ${req.session.user.username}`);
  } else {
    res.send('Please log in');
  }
});
Enter fullscreen mode Exit fullscreen mode

3. Real-time Analytics: High-Speed Data Processing for Dashboards

Why?

  • Redis provides real-time data processing with in-memory storage.
  • Useful for live analytics dashboards (e.g., tracking active users).

How?

  • Store metrics using Redis data structures like counters, lists, or sorted sets.

Example Code:

app.post('/track', (req, res) => {
  const event = req.body.event;
  redisClient.incr(`analytics:${event}`);
  res.send('Event tracked');
});

app.get('/analytics', async (req, res) => {
  const views = await redisClient.get('analytics:page_view');
  res.json({ pageViews: views });
});
Enter fullscreen mode Exit fullscreen mode

4. Rate Limiting: Controlling API Requests Per User

Why?

  • Prevent abuse by limiting the number of API requests per user or IP address.
  • Ensures fair usage and enhances security.

How?

  • Use Redis to keep track of request counts with expiration for rate limits.

Example Code:

app.use(async (req, res, next) => {
  const userIP = req.ip;
  const limit = 100;
  const ttl = 60; // 60 seconds
  const cacheKey = `rate_limit:${userIP}`;

  const requests = await redisClient.get(cacheKey);

  if (requests) {
    if (parseInt(requests) >= limit) {
      return res.status(429).json({ message: 'Too many requests. Try again later.' });
    }
    await redisClient.incr(cacheKey);
  } else {
    await redisClient.setEx(cacheKey, ttl, 1);
  }

  next();
});

app.get('/api', (req, res) => {
  res.send('API response');
});
Enter fullscreen mode Exit fullscreen mode

5. Job Queues: Storing Background Jobs in a Queue for Processing

Why?

  • Offload heavy processing tasks (e.g., email sending, image processing) to background workers.
  • Improves user experience by avoiding long wait times.

How?

  • Use Redis as a queue to manage background jobs with libraries like Bull.

Example Code:

const Queue = require('bull');
const emailQueue = new Queue('email', { redis: { host: '127.0.0.1', port: 6379 } });

// Adding a job to the queue
app.post('/send-email', (req, res) => {
  const { email, message } = req.body;
  emailQueue.add({ email, message });
  res.send('Email will be sent soon.');
});

// Processing the job
emailQueue.process(async (job) => {
  console.log(`Sending email to ${job.data.email}`);
  // Logic to send email
});
Enter fullscreen mode Exit fullscreen mode

Why Use Redis for These Use Cases?

  • Performance: In-memory storage offers ultra-fast read/write speeds.
  • Scalability: Redis clustering and replication allow horizontal scaling.
  • Versatility: Suitable for multiple use cases like caching, sessions, messaging, and analytics.

Top comments (0)