Avoiding the ORM N+1 Problem in Odoo

A common cause of slow Odoo code is the N+1 problem. What it is and how to avoid it.

A common, recognisable cause of slow Odoo code has a name: the N+1 problem. This piece is about what it is and how to avoid it.

What the N+1 problem is

The N+1 problem is a recognisable pattern of inefficient code. It happens when code, working with a set of records, queries the database separately for each record, one record at a time, in a loop, rather than working with the set efficiently. So instead of one efficient operation for the whole set, there is a query for each of the many records. With many records, that is many separate queries where there should have been few, and the result is code that is slow, slower the more records there are. The N+1 problem is, in essence, doing record by record what should be done for the set together.

Why it matters

The N+1 problem matters because it is a common cause of slow Odoo code, and a particularly insidious one. It is insidious because code with an N+1 problem can seem fine when it is written and tested with few records, the many-queries pattern is not noticeably slow with little data, but the same code, in genuine use with many records, is slow, and slower as the data grows. So the N+1 problem is a fault that can hide until the code is genuinely used at scale. A developer who understands and avoids the N+1 problem writes code that stays efficient as the data grows; a developer who does not can write code that quietly becomes slow.

Avoiding it: work with sets, not record by record

Avoiding the N+1 problem is, in principle, a matter of working with sets of records efficiently rather than record by record. Odoo's data layer, the ORM, is designed to work with sets of records, and used as intended, it lets a developer do, for a whole set of records together, what the N+1 pattern does inefficiently record by record. So avoiding the N+1 problem means a developer working with records the Odoo way, working with the set, using the ORM's ability to operate on sets, rather than falling into the pattern of looping and querying for each record separately. The developer should be conscious, when working with a set of records, of doing the work for the set efficiently, not record by record.

It is a matter of writing code the Odoo way

An honest point. Avoiding the N+1 problem is, in large part, a matter of writing Odoo code the Odoo way, working with the ORM as it is designed to be worked with, working with sets of records. A developer who genuinely works with the ORM the way it is meant to be used naturally tends to avoid the N+1 problem, because the ORM's intended way is the set-oriented way. The N+1 problem tends to come from not working with the framework's set-oriented design. So avoiding it is, like much of writing good Odoo code, a matter of working genuinely with the framework.

The takeaway

The ORM N+1 problem in Odoo is a common, recognisable cause of slow code: code that queries the database separately for each record, in a loop, rather than working with the set of records efficiently, so there are many queries where there should be few. It matters because it can hide until the code is used at scale, then be slow and slower as data grows. Avoid it by working with sets of records efficiently, using the ORM as it is designed, the set-oriented way, rather than record by record. It is, in large part, a matter of writing code the Odoo way. For how we approach Odoo, see our ERP practice.

All posts

Got a Topic Worth Posting?

Suggest a Topic

If a question keeps coming up in your operations, it might be worth its own post.