Caching

15 questions found

What is multi-tier caching (combining an in-memory L1 cache with a distributed L2 cache), and what problem does it solve?

Advanced
Multi-tier caching layers a fast, small in-memory (L1) cache on each application instance in front of a larger, shared distributed (L2) cache like Redis -- a read first checks L1 (fastest), falling back to L2 on a miss, and finally to the actual data source, giving both the raw speed of in-memory access for hot data and the consistency/capacity of a shared cache.
const l1Cache = new Map();

async function getData(key) {
  if (l1Cache.has(key)) return l1Cache.get(key);
  const l2Value = await redis.get(key);
  if (l2Value) { l1Cache.set(key, JSON.parse(l2Value)); return JSON.parse(l2Value); }
  const fresh = await db.fetch(key);
  l1Cache.set(key, fresh);
  await redis.set(key, JSON.stringify(fresh), { EX: 300 });
  return fresh;
}
Real-world example A high-traffic API serving the same handful of extremely popular product pages adds a small in-memory L1 cache in front of its existing Redis cache, cutting typical response latency further for those hot items.

Common follow-ups: How do you keep L1 caches on different instances from serving inconsistent stale data relative to each other after an invalidation?;What's an appropriate L1 cache size given it exists on every application instance?

Caching with Redis;Performance Optimization & Profiling

What is the risk of caching sensitive or user-specific data with a shared cache key, and how do you avoid it?

Intermediate
If a cache key doesn't incorporate the identity of the requesting user (or tenant, or permission context), one user's request could be served another user's cached, personalized data -- a serious privacy bug. The fix is ensuring cache keys always include every dimension the response varies by (user ID, locale, permission level), the same principle behind the HTTP 'Vary' header.
// Bug: cache key doesn't include the user
const cacheKey = 'dashboard-data';

// Fixed: cache key scoped to the specific user
const cacheKey = `dashboard-data:${userId}`;
Real-world example A security audit discovers a dashboard-caching layer used a single shared cache key regardless of the logged-in user, meaning the first user to load the dashboard after expiration had their personalized data served to every subsequent user until the entry expired.

Common follow-ups: What other dimensions besides user ID commonly need to be included in a cache key (locale, currency, permission role)?;How does the HTTP 'Vary' header address this same class of problem for CDN and browser caching?

Security;HTTP & HTTPS Modules

How would you implement a write-behind (write-back) caching strategy, and what durability risk does it introduce?

Advanced
Write-behind caching writes changes to the cache immediately and defers the actual write to the durable database to a later batched operation, improving write throughput significantly, but introducing a durability risk: if the process crashes before the deferred write happens, that data is permanently lost, so this pattern is only appropriate when losing a small, recent window of writes is genuinely acceptable.
const writeBuffer = new Map();

function recordPageView(pageId) {
  writeBuffer.set(pageId, (writeBuffer.get(pageId) || 0) + 1);
}

setInterval(async () => {
  for (const [pageId, count] of writeBuffer) {
    await db.pageViews.increment(pageId, count);
  }
  writeBuffer.clear();
}, 30000);
Real-world example An analytics system tracking page-view counts buffers increments in memory and flushes them to the database every 30 seconds, accepting a small window of possible data loss on crash since exact real-time counts aren't business-critical.

Common follow-ups: What data would be completely inappropriate to cache using a write-behind strategy given this durability risk?;How would you reduce the durability risk without giving up the throughput benefit entirely, such as more frequent flushing?

Databases & ORMs (MongoDB/Mongoose SQL/Sequelize);Performance Optimization & Profiling

What is negative caching, and why might you deliberately cache the fact that a lookup returned 'not found'?

Intermediate
Negative caching stores the result of a lookup that found nothing, preventing repeated identical lookups for something known not to exist from hitting the database every time -- without it, requests probing for non-existent resources could generate significant unnecessary load on the underlying data source.
async function getUser(id) {
  const cached = await redis.get(`user:${id}`);
  if (cached === 'NOT_FOUND') return null;
  if (cached) return JSON.parse(cached);
  const user = await db.users.findById(id);
  if (!user) { await redis.set(`user:${id}`, 'NOT_FOUND', { EX: 60 }); return null; }
  await redis.set(`user:${id}`, JSON.stringify(user), { EX: 3600 });
  return user;
}
Real-world example A public API repeatedly queried for invalid or deleted user IDs by a misconfigured integration adds negative caching with a short TTL, absorbing the repeated invalid lookups without hitting the database each time.

Common follow-ups: Why does a negative cache entry typically need a much shorter TTL than a positive cache entry?;Could negative caching be exploited or cause a functional bug if a resource is created shortly after being negatively cached?

Security;Databases & ORMs (MongoDB/Mongoose SQL/Sequelize)

What is the difference between res.set('Cache-Control', 'no-cache') and 'no-store' in an Express response?

Beginner
'no-cache' allows a cache to store the response, but requires it to revalidate with the origin server before reusing the cached copy on every subsequent request. 'no-store' is much stricter: it forbids storing the response at all, anywhere, appropriate for genuinely sensitive responses that must never be cached in any form.
// Allows caching but forces revalidation every time
res.set('Cache-Control', 'no-cache');

// Forbids storing this response anywhere at all
res.set('Cache-Control', 'no-store');
Real-world example A banking API sets Cache-Control: no-store on every endpoint returning account balance data, ensuring browsers, proxies, or any intermediate cache never retain a copy of that sensitive information.

Common follow-ups: How does a client know when a 'no-cache' response is safe to reuse versus needing to refetch it entirely?;Why would an application choose 'no-cache' over 'no-store' when it still wants some caching-related benefit?

Security;HTTP & HTTPS Modules

Showing 11–15 of 15