Skip to content

knaus94/prisma-extension-cache-manager

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

69 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@knaus94/prisma-extension-cache-manager

A caching extension for Prisma with cache-manager.

Features

  • cache-manager compatibility
  • Only model queries can be cacheable (no $query or $queryRaw)
  • Cache stampede protection:
    • Local in-flight deduplication (single process)
    • Distributed lock via Valkey/Redis (SET NX PX) for multi-instance apps

Installation

Install:

npm i @knaus94/prisma-extension-cache-manager cache-manager

For Valkey/Redis store and distributed lock:

npm i keyv @keyv/valkey

Usage

import { PrismaClient } from "@prisma/client";
import { createCache } from "cache-manager";
import Keyv from "keyv";
import KeyvValkey from "@keyv/valkey";
import cacheExtension from "@knaus94/prisma-extension-cache-manager";

async function main() {
  const cache = createCache({
    stores: [new Keyv({ store: new KeyvValkey("redis://localhost:6379") })],
  });

  const prisma = new PrismaClient().$extends(
    cacheExtension({
      cache,
      lock: {
        ttl: 5000,
        waitTimeout: 2000,
        retryDelay: 40,
        retryJitter: 20,
        prefix: "prisma-cache-lock",
      },
    })
  );

  await prisma.user.findUniqueOrThrow({
    where: {
      email: user.email,
    },
    cache: true,
  });

  await prisma.user.findMany({
    cache: 5000,
  });

  await prisma.user.count({
    cache: {
      ttl: 2000,
      key: "user_count",
    },
  });

  await prisma.user.update({
    data: {},
    cache: {
      ttl: 2000,
      key: (result) => `user-${user.id}`,
    },
  });

  await prisma.user.create({
    data: {},
    uncache: `user_count`,
  });

  await prisma.user.create({
    data: {},
    cache: {
      ttl: 2000,
      key: (result) => `user-${user.id}`,
    },
    uncache: [`user_count`, `users`],
  });
}

main().catch(console.error);

For distributed lock, extension will use the first store with a Redis client at cache.stores[*].store.redis. If such store is missing, extension automatically falls back to local in-process single-flight.

Disable distributed lock if needed:

cacheExtension({
  cache,
  lock: false,
});

Learn more

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors