Prevent Database Query Performance Regressions

Catches N+1 queries, unbounded list endpoints, missing pagination, per-row writes in loops, and over-fetching before they slow down production.

What it flags

Flaggedsrc/orders/list-orders.ts
import { prisma } from './db';

export async function listOrders(customerId: string) {
  // Unbounded list, plus one items query per order
  const orders = await prisma.order.findMany({
    where: { customerId },
  });

  return Promise.all(
    orders.map(async (order) => ({
      ...order,
      items: await prisma.orderItem.findMany({ where: { orderId: order.id } }),
    })),
  );
}
Passessrc/orders/list-orders.ts
import { prisma } from './db';

const PAGE_SIZE = 50;

export async function listOrders(customerId: string, cursor?: string) {
  return prisma.order.findMany({
    where: { customerId },
    orderBy: [{ createdAt: 'desc' }, { id: 'desc' }],
    take: PAGE_SIZE,
    ...(cursor ? { cursor: { id: cursor }, skip: 1 } : {}),
    select: {
      id: true,
      status: true,
      total: true,
      createdAt: true,
      items: { select: { sku: true, quantity: true } },
    },
  });
}

Why it matters

Query problems scale with data, so they pass tests and staging on small tables and surface in production as slow pages, timeouts, and exhausted connection pools. An N+1 loop that runs a handful of queries against a test fixture runs one query per row against a large customer account. They slip through review because an ORM call inside a map, or a findMany without a limit, reads like ordinary code.

Agent instructions

cubic checks every pull request against these instructions. Paste them into AGENTS.md or Cursor rules and your AI coding tool follows them while it writes code.

AGENTS.md

Add this section to AGENTS.md at the repository root. Codex, Cursor, and other AI coding tools read it.

## Prevent Database Query Performance Regressions

Flag database access patterns that can degrade production performance, including N+1 queries, unbounded list endpoints, missing pagination, full-table scans, missing indexes on selective filters, per-row writes in loops, and queries that load more columns or rows than needed. Prefer bounded reads, batching, selective indexes, and query shapes that scale with table size.

Checks every changed file.

Related agents

Included in the Next.js, Node.js, Python, Django, Ruby on Rails, Go, Spring Boot, and PostgreSQL code review standards.

Run this agent on every pull request

cubic reviews every pull request against the agents you turn on and comments on the lines that break them.

Catch this in your code