1. N+1 Queries: The Silent Performance Killer
You display 100 books together with their authors… and your application ends up running 101 SQL queries.
Example:
for book in books:
print(book.author.name) # Potentially one extra query per author
👉 The result can be a page that becomes unnecessarily slow.
Think of it like going to an ATM 100 times to withdraw one dollar each time.
When one well-designed query — or a small number of efficient queries — could retrieve what you need.
Solution: understand your ORM’s eager-loading, projection, join, prefetching, or split-query mechanisms.
The exact solution depends on the ORM and the shape of the data; eager loading does not always mean literally one SQL query.
2. A False Sense of Simplicity
"It looks simple, so it must be efficient."
Not always.
An ORM can do a lot behind the scenes. Sometimes the generated SQL is heavier or more complex than you expect.
"Why is this query taking two seconds?!"
Perhaps the generated query joins several tables, retrieves too many columns, or performs work you did not realize was happening.
👉 Human-to-human advice:
Enable SQL logging or use a profiler during development.
Look at what your ORM actually sends to the database.
You may be surprised by what you find.
3. Complex SQL Can Outgrow the ORM Abstraction
For complex reporting, analytics, recursive queries, vendor-specific features, or performance-critical workloads, the ORM abstraction can sometimes become awkward.
"I just need a custom WITH RECURSIVE query or a specialized GROUP BY…"
Sometimes using well-written SQL is the clearer and more maintainable choice.
That is not a failure. It is pragmatism.
4. Migrations Can Become Risky
Automatic migration generation is extremely convenient in small projects.
But in a long-running system with many tables and important production data, schema changes need careful review.
👉 A bad migration can cause downtime, data loss, long locks, or deployment failures.
"Who renamed user_id to author_id without planning the data migration?!"
Tip:
Review generated migrations instead of trusting them blindly.
Test important migrations against realistic staging data and plan rollback or recovery strategies where appropriate.