ORMs complicate your application

I remember the first time I was introduced to an Object-Relational Mapper (ORM). It was Perl’s DBIx::Class, which was the default database access layer with Catalyst MVC framework.

At first it seemed cool. It was sexy! I could magically convert my boring relational data into native Perl objects!

But within a year or so, I was bumping into some problems. A typical conversation between my and my work colleague would go something like this:

Me: I have this SQL query that works perfectly. But the ORM is making it really slow. How do I get the ORM to do the right thing?

Colleague: Don’t use the ORM.

Me: Yeah, but…

I’m a stubborn guy. It took a while. But eventually I gave in. I started writing these performance-sensitive queries in straight SQL. Of course, I’d still use the ORM everywhere else.

Then one day I was debugging why the home page of our web app took minutes to load for one customer.

The culprit? The ORM was doing a separate query for every item in a database table, rather than a single join.

I eventually came around to my current view on ORMs, which I summarize as:

ORMs make easy things easy, and difficult things impossible.

In other words: The places where where ORMs are easy to use are already easy without an ORM. These are things like SELECT * FROM users or INSERT INTO users VALUES (?,?,?,?).

And when the needs are more complex, you end up either doing the wrong thing (like making thousands of queries instead of one), or writing very convoluted ORMish (the language/syntax used to interact with your ORM library) to get your ORM to do the right thing.

As a rule, I now avoid ORMs, and have for the last 10+ years. I’ve never missed an ORM. Not once.


Ted Neward has expanded on this at much greater length, if you enjoy pain, and/or US warfare history, in his article The Vietnam of Computer Science. For a much shorter summary, you can read Jeff Atwood’s summary, Object-Relational Mapping is the Vietnam of Computer Science.

Share this