As33
@periodic/
arsenic
unbounded_query
🔴 Critical

Query missing LIMIT — potential unbounded data fetch

This query does not include a LIMIT clause and may return an unexpectedly large dataset, causing memory spikes and performance degradation. On large collections, this can return millions of records.

Common Causes

  • Missing LIMIT clause on find/select queries
  • No default limit set at ORM level
  • Pagination not implemented

How to Fix

  1. 1.Always add LIMIT clauses to find queries
  2. 2.Implement cursor-based pagination
  3. 3.Add default limits at ORM level
  4. 4.Use .lean() in Mongoose for read-only queries

Silent in development, fatal in production

Your dev database has 50 rows. Production has 2 million. An unbounded query works fine locally and takes down prod.

Example

typescript
// BAD — unbounded query
const users = await User.find({ status: 'active' });

// GOOD — always limit
const users = await User.find({ status: 'active' }).limit(100);

// GOOD — cursor-based pagination
const users = await User.find({
  status: 'active',
  _id: { $gt: lastSeenId }
}).limit(20);

Enforcing limits globally

typescript
// Mongoose — global query middleware to enforce a max
mongoose.plugin((schema) => {
  schema.pre('find', function () {
    if (!this.getOptions().limit) {
      this.limit(100); // safe default
    }
  });
});

// Prisma — wrapper utility
async function safeFindMany<T>(
  model: { findMany: (args: any) => Promise<T[]> },
  args: any = {}
): Promise<T[]> {
  return model.findMany({ take: 100, ...args }); // args.take overrides
}