As33
@periodic/
arsenic

Prisma Adapter

The Prisma adapter instruments any database supported by Prisma — PostgreSQL, MySQL, SQLite, and CockroachDB. It uses Prisma's middleware API to observe all queries.

Setup

typescript
import { PrismaClient } from '@prisma/client';
import Fastify from 'fastify';
import { createMonitor, fastifyContext, prismaAdapter } from '@periodic/arsenic';

const app = Fastify();
const prisma = new PrismaClient();

const monitor = createMonitor({
  slowQueryThresholdMs: 200,
  exporter: (event) => {
    if (event.severity === 'critical') sendToPagerDuty(event);
  },
});

// 1. Register Fastify context plugin
app.register(fastifyContext(monitor, {
  attachUser: (req) => req.user?.id,
}));

// 2. Attach Prisma adapter
prismaAdapter(monitor, prisma);

await app.listen({ port: 3000 });

Supported databases

DatabaseStatusNotes
PostgreSQL✅ Full supportAll query types monitored
MySQL✅ Full supportAll query types monitored
SQLite✅ Full supportAll query types monitored
CockroachDB✅ Full supportCompatible via pg wire protocol
MongoDB⚠️ PartialUse mongooseAdapter instead

Overfetching detection

typescript
// BAD — triggers overfetching signal
const users = await prisma.user.findMany();
// Returns all fields including password hash, large blobs, etc.

// GOOD — select only what you need
const users = await prisma.user.findMany({
  select: { id: true, name: true, email: true, createdAt: true },
});

N+1 detection with Prisma

typescript
// BAD — N+1 query
const posts = await prisma.post.findMany();
for (const post of posts) {
  const author = await prisma.user.findUnique({ where: { id: post.authorId } });
}

// GOOD — include in single query
const posts = await prisma.post.findMany({
  include: { author: true },
});

Use select everywhere

Prisma makes it easy to select exactly the fields you need. Make it a habit — Arsenic will reward you with low_memory and fast_query signals.