Skip to content
vetkitChecksChangelogDocumentation

vetkit.data-access.query-in-loop

A database query runs inside a loop, once per item (the N+1 query pattern). The number of round trips grows with the data, so code that is fast on a development database becomes slow and holds connections for longer once real tables and lists grow.

Last updated:

Suite: Production readiness

javascript, typescript

A database query runs inside a loop, once per item (the N+1 query pattern). The number of round trips grows with the data, so code that is fast on a development database becomes slow and holds connections for longer once real tables and lists grow.

Category: DATABASE · Engine rule severity: WARNING

How to fix it

Load what the loop needs with one query before it (for example findMany({ where: { id: { in: ids } } }), Drizzle inArray(...), Supabase .in('id', ids), a join or an include) and look rows up in a Map inside the loop. Batch writes with the bulk API (createMany, insert(...).values([...]), insertMany, bulkCreate, an array upsert) or a single deleteMany / DELETE … WHERE id IN (…).

References

Source: packages/engine/rules/data-access/javascript.yml.

python

A database query runs inside a loop, once per item (the N+1 query pattern). The number of round trips grows with the data, so code that is fast on a development database becomes slow and holds connections for longer once real tables and lists grow.

Category: DATABASE · Engine rule severity: WARNING

How to fix it

Load the rows before the loop (Django filter(id__in=ids) / in_bulk, select_related / prefetch_related for relations; SQLAlchemy where(Model.id.in_(ids)), selectinload / joinedload) and look them up in a dict inside it. Batch writes with bulk_create / bulk_update, executemany, insert_many or one UPDATE … WHERE id IN (…), and commit once after the loop.

References

Source: packages/engine/rules/data-access/python.yml.

ruby

A database query runs inside a loop, once per item (the N+1 query pattern). The number of round trips grows with the data, so code that is fast on a development database becomes slow and holds connections for longer once real tables and lists grow.

Category: DATABASE · Engine rule severity: WARNING

How to fix it

Load the records before the loop (Model.where(id: ids).index_by(&:id), includes / preload for associations) and look them up inside it. Insert rows with one insert_all / upsert_all instead of a create per item.

References

Source: packages/engine/rules/data-access/ruby.yml.

Generated from shipped rule definitions at build time. Matching is a review signal, not proof of exploitability. “generic” denotes text matching, not complete language or framework coverage. Runtime configuration and available tools affect whether a rule runs.