PR Review Lab · Cache Product Pages in Redis

30:00left of 30:00

Cache Product Pages in Redis

Product pages are our most requested route, and every view runs a database read plus a pricing call. This caches the rendered page in Redis for 5 minutes and invalidates it when a product is updated. On staging the p95 for product pages dropped from 180 ms to 12 ms.

Asrc/catalog/productCache.ts1 of 3

Files Changed

src/catalog/

src/catalog/productCache.ts

TypeScript · Click a line number to comment · Tap a line to comment
@@ -0,0 +1,29 @@
Added: import type { Redis } from "ioredis";
Added: import type { ProductPage } from "./types";
Added:
Added: const TTL_SECONDS = 300;
Added:
Added: /** Cache-aside store for rendered product pages. */
Added: export class ProductCache {
Added: constructor(private readonly redis: Redis) {}
Added:
Added: private key(productId: string): string {
Added: return `product-page:${productId}`;
Added: }
Added:
Added: async getOrLoad(
Added: productId: string,
Added: load: () => Promise<ProductPage | null>,
Added: ): Promise<ProductPage | null> {
Added: const cached = await this.redis.get(this.key(productId));
Added: if (cached !== null) return JSON.parse(cached) as ProductPage | null;
Added:
Added: const page = await load();
Added: await this.redis.set(this.key(productId), JSON.stringify(page), "EX", TTL_SECONDS);
Added: return page;
Added: }
Added:
Added: async invalidate(productId: string): Promise<void> {
Added: await this.redis.del(this.key(productId));
Added: }
Added: }