Skip to main content
Back to Home

What Zelsis checks · Performance

Performance problems Zelsis catches before users feel them

Slow pages rarely come from one big mistake. They come from a loop that queries the database, or a migration that holds a lock during a deploy.

Checked on every pull request

  • A database query run once per item in a list (N+1)
  • Deep offset pagination and unbounded in-memory sorting
  • Migrations that take a blocking lock on an existing table
  • A new formatter (Intl) created for every row of a table
  • Lists keyed by array index
  • Images that download at full screen width

Caught in real code

Our test suite scans these examples on every release.

One database query per item in a list

DB-PERF-01

Each post is loaded in its own query inside the loop, so a page of 50 posts makes 50 round trips.

lib/posts.ts
Flagged
import { prisma } from './db';

export async function getAuthors(postIds: string[]) {
  const authors = [];
  for (const id of postIds) {
    const post = await prisma.post.findUnique({ where: { id }, include: { author: true } });
    authors.push(post?.author);
  }
  return authors;
}
Passes
import { prisma } from './db';

export async function getAuthors(postIds: string[]) {
  const posts = await prisma.post.findMany({ where: { id: { in: postIds } }, include: { author: true } });
  return posts.map((post) => post.author);
}