Skip to Content

Odoo Development

Odoo Related Fields and When They Hurt Performance

A related field is a computed field wearing a shortcut. That single fact explains its performance behaviour, its storage behaviour, and why a stored related field is a copy of data rather than a view of it.

Part of our guide to Odoo Development

What a related field really is

class SaleOrderLine(models.Model):
    _inherit = "sale.order.line"

    customer_country_id = fields.Many2one(
        "res.country",
        related="order_id.partner_id.country_id",
        store=True,
    )

Odoo turns that into a computed field. It generates the compute method that walks the path, and it generates the depends from the path itself.

So there is nothing separate to learn about how they recompute or when they are stale. Everything true of computed fields is true here, which is the most useful thing to know about them.

Unstored: a join on every read

An unstored related field reads through the chain each time it is accessed. order_id.partner_id.country_id means reaching the order, then the partner, then the country.

For one record on a form, that is nothing. Odoo's prefetching makes it efficient across a recordset too, because it batches the reads rather than doing them one at a time.

The cost appears when the field is on a list view over a long path. Every displayed row walks the chain, and while prefetching keeps it to a few queries rather than thousands, the work is still proportional to the depth of the path and the size of the page.

The limitation that usually forces a decision is different: an unstored related field cannot be searched, sorted or grouped, because there is no column for the database to work with.

Stored: a copy, not a view

Setting store=True creates a real column that Odoo keeps synchronised. That buys searching, sorting and grouping, and it makes reads free.

It also has consequences people underestimate.

It duplicates data. The country now exists on the country record, on the partner, and on every order line. That is a legitimate trade, but it should be a deliberate one.

It writes back through the chain. Change a partner's country and Odoo must update every stored related field that depends on it. On a partner with thousands of order lines, one edit on a form becomes thousands of row updates inside the user's save. This is a genuine and frequently reported cause of slow writes.

It is only correct while every write goes through the ORM. A stored related field is maintained by Odoo, not by the database. Raw SQL, a restore that touched the source table, or a migration script that wrote directly all leave the copy stale with nothing reporting it.

Choosing

Store it when you need to search, filter, sort or group by it. That is the case that genuinely requires a column, and it is the only one that clearly justifies the cost.

Leave it unstored for display. A field that only appears on a form or is read occasionally does not need a column, and leaving it unstored means it can never be stale.

Think twice when the source changes often and has many dependent records. A stored related field on order lines pointing at partner data is fine if partner data is static and painful if it is edited daily.

Depth is the thing to watch

related="order_id.partner_id.country_id.currency_id.symbol" is legal and is a bad idea.

Every segment is a dependency. A change anywhere along that chain triggers recomputation at the end of it, and when the field is stored, the write amplification follows the whole path. Long chains are also brittle: rename or restructure any link and the field breaks, and the error message points at your field rather than at the change that caused it.

Two segments is comfortable. Three deserves a reason. Beyond that, consider a computed field with an explicit depends you control, which at least makes the cost visible in the code.

Alternatives worth considering

A plain Many2one plus dot access in views. If you only need to display it, referencing partner_id.country_id in a form works without any field at all.

An explicit computed field. When the logic is more than a straight path, or when you want a narrower depends than the path implies, write it out. More code, but the dependency set is yours rather than inferred.

Nothing. The most common unnecessary related field exists so a developer could avoid typing a dot in one view. It costs a column, a dependency and an upgrade concern permanently.

Diagnosing a slow save

When saving a record becomes slow, related fields are one of the first places to look, alongside computed chains.

Look for stored related fields pointing at the model being written, then count how many dependent records exist. One partner with ten thousand order lines carrying stored related fields is a slow save, and the method body is not the problem, so profiling it will tell you nothing useful.

The fix is usually to unstore the field and solve the original searching need another way, such as searching the source model directly.

FAQ

Questions, answered.

What is the difference between a related field and a computed field in Odoo?

None structurally. A related field is a computed field whose compute method and depends are generated for you from the dotted path. Anything true of computed fields regarding storage, dependencies and recomputation is equally true of related fields.

Should a related field be stored?

Store it only if you need to search, sort or group by it. A stored related field is a physical copy that Odoo keeps in sync, so it costs a write on the source model whenever the source changes, and it duplicates the data.

Why is my stored related field showing an old value?

Usually because the source changed through a path that did not trigger recomputation, such as raw SQL or a data import bypassing the ORM. Unlike an ordinary column, a stored related field is only correct as long as every write goes through Odoo.

With CODEerts

Need something built properly?

We are certified Odoo partners. We build custom Odoo modules that extend the framework rather than fight it, and we publish our own apps on the Odoo Store.

See how we can helpBook a call