DEV Community

Alex Spinov
Alex Spinov

Posted on

Redis Has a Free Cloud API — Here's How to Build Lightning-Fast Caching in Minutes

A SaaS founder told me their API response time was 2.3 seconds. Users were leaving. They added Redis caching in front of their database — response time dropped to 12ms. Same server, same database, just one cache layer.

What Redis Cloud Offers for Free

Redis Cloud free tier (redis.com):

  • 30 MB storage — enough for 100K+ cached items
  • 30 connections — handles moderate traffic
  • All Redis data structures — strings, hashes, lists, sets, sorted sets, streams
  • Pub/Sub messaging
  • Redis Search and JSON modules
  • No credit card required

Quick Start

# Sign up at redis.com/try-free
# Create a free database
# Grab your connection details

# Connect with redis-cli
redis-cli -h redis-12345.c1.us-east-1-2.ec2.cloud.redislabs.com -p 12345 -a your_password
Enter fullscreen mode Exit fullscreen mode

Caching Pattern (Node.js)

const Redis = require('ioredis');
const redis = new Redis(process.env.REDIS_URL);

async function getCached(key, fetchFn, ttl = 3600) {
  // Try cache first
  const cached = await redis.get(key);
  if (cached) return JSON.parse(cached);

  // Cache miss — fetch from source
  const data = await fetchFn();
  await redis.setex(key, ttl, JSON.stringify(data));
  return data;
}

// Usage
app.get('/api/products/:id', async (req, res) => {
  const product = await getCached(
    `product:${req.params.id}`,
    () => db.query('SELECT * FROM products WHERE id = $1', [req.params.id]),
    1800 // 30 min TTL
  );
  res.json(product);
});
Enter fullscreen mode Exit fullscreen mode

Session Storage

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

app.use(session({
  store: new RedisStore({ client: redis }),
  secret: 'your-secret',
  resave: false,
  saveUninitialized: false,
  cookie: { maxAge: 86400000 } // 24h
}));
Enter fullscreen mode Exit fullscreen mode

Rate Limiting

async function rateLimit(userId, limit = 100, window = 3600) {
  const key = `ratelimit:${userId}`;
  const current = await redis.incr(key);

  if (current === 1) {
    await redis.expire(key, window);
  }

  return {
    allowed: current <= limit,
    remaining: Math.max(0, limit - current),
    resetIn: await redis.ttl(key)
  };
}

// Middleware
app.use(async (req, res, next) => {
  const { allowed, remaining } = await rateLimit(req.ip);
  res.set('X-RateLimit-Remaining', remaining);
  if (!allowed) return res.status(429).json({ error: 'Too many requests' });
  next();
});
Enter fullscreen mode Exit fullscreen mode

Real-Time Leaderboard

// Add scores
await redis.zadd('leaderboard', 1500, 'alice');
await redis.zadd('leaderboard', 2300, 'bob');
await redis.zadd('leaderboard', 1800, 'charlie');

// Get top 10
const top10 = await redis.zrevrange('leaderboard', 0, 9, 'WITHSCORES');
// ['bob', '2300', 'charlie', '1800', 'alice', '1500']

// Get player rank
const rank = await redis.zrevrank('leaderboard', 'alice'); // 2 (0-based)
Enter fullscreen mode Exit fullscreen mode

Pub/Sub Messaging

// Publisher
await redis.publish('notifications', JSON.stringify({
  userId: '123',
  message: 'Your order shipped!'
}));

// Subscriber (separate connection)
const sub = new Redis(process.env.REDIS_URL);
sub.subscribe('notifications');
sub.on('message', (channel, message) => {
  const data = JSON.parse(message);
  sendPushNotification(data.userId, data.message);
});
Enter fullscreen mode Exit fullscreen mode

Common Patterns

Pattern Use Case TTL
Cache-aside Database query caching 5-60 min
Session store User sessions 24h
Rate limiter API protection 1h window
Leaderboard Gaming, rankings Permanent
Pub/Sub Real-time notifications N/A
Queue Background jobs Until processed

Need to scrape and cache web data? Check out my web scraping actors on Apify — automated data collection with built-in caching.

Need a custom caching solution? Email me at spinov001@gmail.com — I build high-performance data pipelines.

Top comments (0)