Laravel · Databases

Optimizing Eloquent Queries

A practical process for finding slow database access before it becomes a production problem.

By Bipin Paudel · · 6 min read

Developer working on a laptop

Eloquent keeps application code expressive, but an elegant relationship call can conceal dozens of database queries. Performance work starts with measurement: inspect the queries generated by a real page, record query count and time, then fix the largest source of waste before reaching for caching.

Recognize the N+1 pattern

The classic issue occurs when a list loads its parent records and then accesses a relationship inside a loop. Instead of one query for orders and one for customers, the application runs one query per order. Load the relationship up front with with() or load(), and select only the relationship fields the view needs.

Fetch only what the screen uses

Large models frequently contain columns the current view does not need. Use select() for focused lists and withCount() when you need a count instead of a full relationship. This reduces database work, response payloads, and memory use without making the code difficult to understand.

Paginate intentionally

Never load an unbounded result set for an admin table or API list. Use pagination for navigable pages and cursor pagination for large, continuously changing datasets. Ensure sorting uses indexed columns and keep filters aligned with the indexes your database can use.

Measure after every change

Use Laravel’s query tooling locally and slow-query logs in production to verify the improvement. An optimization that reduces query count but adds a costly join may not help. Compare response time, rows scanned, and memory use against a representative dataset.

The durable habit is simple: eager-load known relationships, constrain selected fields, paginate large collections, and use measurements to guide the next change. These practices make Eloquent predictable even as an application grows.