DEV Community

1xApi
1xApi

Posted on • Originally published at 1xapi.com

5 API Caching Strategies That Will 10x Your Response Times

5 API Caching Strategies That Will 10x Your Response Times

Slow APIs kill user experience. If your endpoints are hitting the database on every single request, you're leaving massive performance gains on the table.

Here are 5 caching strategies you can implement today — from simplest to most powerful.


1. HTTP Cache Headers (The Free Win)

The easiest caching strategy requires zero infrastructure changes. Just set the right response headers:

app.get('/api/products', (req, res) => {
  // Cache for 5 minutes in browser, 10 minutes in CDN
  res.set('Cache-Control', 'public, max-age=300, s-maxage=600')
  res.set('ETag', generateETag(data))
  res.json(data)
})
Enter fullscreen mode Exit fullscreen mode

Key headers:

  • Cache-Control: Controls who caches and for how long
  • ETag: Enables conditional requests (304 Not Modified)
  • Vary: Tells caches which request headers affect the response

Best for: Public, read-heavy endpoints like product listings or blog posts.


2. In-Memory Caching (The Quick Fix)

For single-server setups, an in-memory cache like node-cache is dead simple:

import NodeCache from 'node-cache';

const cache = new NodeCache({ stdTTL: 120 }); // 2 min default

app.get('/api/stats', async (req, res) => {
  const cached = cache.get('stats')
  if (cached) return res.json(cached)

  const stats = await db.getExpensiveStats()
  cache.set('stats', stats)
  res.json(stats)
})
Enter fullscreen mode Exit fullscreen mode

Pros: Near-zero latency, no external dependencies.

Cons: Not shared across instances, lost on restart.

Best for: Expensive computations on single-server apps.


3. Redis Caching (The Industry Standard)

When you need shared caching across multiple servers, Redis is the go-to:

import Redis from 'ioredis';
const redis = new Redis();

async function cachedQuery(key, ttl, queryFn) {
  const cached = await redis.get(key)
  if (cached) return JSON.parse(cached)

  const result = await queryFn()
  await redis.setex(key, ttl, JSON.stringify(result))
  return result
}

// Usage
app.get('/api/users/:id', async (req, res) => {
  const user = await cachedQuery(
    `user:${req.params.id}`,
    300,
    () => db.users.findById(req.params.id)
  )
  res.json(user)
})
Enter fullscreen mode Exit fullscreen mode

Pro tip: Use a cache-aside pattern with invalidation on writes:

app.put('/api/users/:id', async (req, res) => {
  const user = await db.users.update(req.params.id, req.body)
  await redis.del(`user:${req.params.id}`) // Invalidate
  res.json(user)
})
Enter fullscreen mode Exit fullscreen mode

Best for: Multi-instance deployments, session data, frequently accessed records.


4. Edge Caching / CDN (The Global Boost)

Push your API responses to the edge using Cloudflare Workers, Vercel Edge, or AWS CloudFront:

// Cloudflare Worker example
export default {
  async fetch(request, env) {
    const cache = caches.default
    let response = await cache.match(request)

    if (!response) {
      response = await fetch(request)
      response = new Response(response.body, response)
      response.headers.set('Cache-Control', 's-maxage=600')
      await cache.put(request, response.clone())
    }

    return response
  }
}
Enter fullscreen mode Exit fullscreen mode

This serves responses from data centers closest to users — often cutting latency from 200ms to under 20ms.

Best for: Global APIs, public data, read-heavy workloads.


5. Request Deduplication (The Hidden Gem)

When multiple users request the same data simultaneously, don't hit the database N times. Deduplicate in-flight requests:

const inFlight = new Map()

async function deduped(key, queryFn) {
  if (inFlight.has(key)) return inFlight.get(key)

  const promise = queryFn().finally(() => inFlight.delete(key))
  inFlight.set(key, promise)
  return promise
}

app.get('/api/trending', async (req, res) => {
  const data = await deduped('trending', () => db.getTrending())
  res.json(data)
})
Enter fullscreen mode Exit fullscreen mode

This is especially powerful for endpoints that spike during traffic bursts (e.g., a product going viral).

Best for: Hot endpoints, traffic spikes, expensive queries.


Which Strategy Should You Use?

Scenario Strategy
Public, static-ish data HTTP Headers + CDN
Single server, simple app In-memory cache
Multi-server production Redis
Global audience Edge caching
Traffic spikes Request deduplication

The best approach? Layer them. Use HTTP headers as your first line, Redis for hot data, and edge caching for global reach. Add request deduplication on your most hammered endpoints.


Quick Wins to Start Today

  1. Add Cache-Control headers to your read endpoints — takes 5 minutes
  2. Wrap your slowest query in a Redis cache with a 60s TTL
  3. Measure first — use your APM tool to find which endpoints actually need caching

Caching isn't premature optimization. It's the difference between a 500ms API and a 5ms API. Start with the simplest strategy that fits, and layer up as you scale.


Building APIs? 1xAPI provides ready-to-use API services so you can focus on your product instead of infrastructure.

Top comments (0)