ORMs Are Useful Until You Stop Looking at the SQL_
ORMs can speed up product development, but they become expensive when teams stop inspecting generated queries and understanding database access patterns.
The problem starts when a team treats the ORM as a database abstraction layer instead of a query generator that still needs to be understood, measured, and occasionally bypassed.
That distinction matters.
What ORMs Are Actually Good At
ORMs are good at:
standard CRUD paths
schema modeling
migrations
reducing repetitive mapping code
They are usually bad at hiding the cost model of relational databases.
If a team never looks at the SQL, the ORM becomes a latency generator with nice autocomplete.
The Failure Mode Everyone Eventually Sees
The classic example is the N+1 query problem:
const users = await db.user.findMany({ take: 50 });for (const user of users) { console.log(user.invoices[0]?.status);}
At the application level, this looks harmless.
At the database level, it often means:
one query to fetch users
fifty more queries to fetch related records
That is not an ORM bug. It is the result of relationship access that hides query boundaries.
Eager Loading Is Not a Universal Fix
The usual reaction is to load everything up front: