Insights·Hosting·4 min read

Odoo performance: what actually slows an instance down as it grows

Odoo instances rarely slow down because of the server. A practical look at where the time actually goes, how to measure it, and what hosting can and cannot fix.

Most Odoo instances feel fast on day one. A year later the same screens take several seconds to open, a month-end report times out, and someone asks whether the server needs more memory. Sometimes it does. More often the memory gets bought and the problem stays, because the slowdown was never about the server.

This is what usually changes between the fast month and the slow one.

Row count matters less than you think

An Odoo database with two million journal items can be perfectly responsive. One with forty thousand sales orders can feel unusable. What separates them is not size, it is what the system is asked to compute while a user waits. A list view that reads stored columns stays fast as it grows. A list view that recomputes a value for every row on every page load gets slower in a straight line, and nobody notices until that line crosses the patience threshold.

Where the weight accumulates

  • Attachments. Emails with PDFs, scanned delivery notes, and product images all land in the filestore. They rarely affect query speed, but they drive backup size and restore time, which is what you feel on the day you actually need a restore.
  • Chatter history. Every message, log note, and tracked field change is a row. On a heavily automated instance, tracking tables can outgrow the business tables they describe.
  • Records nobody cleaned up. Duplicate partners from an old import, test products from go-live, draft orders from a process someone abandoned. All of them are searched every time a user opens a dropdown.
  • Scheduled actions. Added one at a time over two years, then all firing inside the same ten minute window because everyone picked a round number.
  • Custom computed fields. The single most common cause of a slow list view in a customized Odoo, especially when the field is not stored and the view sorts or filters on it.

Three patterns behind most complaints

In practice, slow Odoo screens tend to trace back to one of three things.

First, a view doing per-record work: a non-stored compute, a related field crossing three models, or an onchange that triggers a search. Eighty rows on screen means eighty round trips.

Second, custom code written record by record. A loop calling a method inside itself, a create inside a for statement, a search executed per line instead of once per batch. This is fine at ten records and painful at ten thousand.

Third, heavy work at the wrong time. A full inventory valuation report, a large export, or a bulk update run in the middle of the working day while forty people are entering orders. The report is not wrong, the timing is.

Measure before you change anything

Slowness is easy to guess at and cheap to verify, so verify. Write down the exact action, the record count, and the user who hit it. Then check three things: does it happen for every user or only some (that points at record rules and multi-company filters), does it happen on every record or only the large ones (that points at data volume in one specific relation), and does it reproduce on a copy of the database holding the same data (if it does not, the difference is environmental rather than functional).

That last check is why a staging environment earns its keep. Rehearsing a cleanup or an index change against real data tells you whether it helped before you touch production. If you would rather have someone else run that analysis, this is what an ERP health check is for.

What hosting fixes and what it does not

Being honest about that boundary saves everyone a cycle. Infrastructure helps with concurrency: more workers let more people work at once, faster storage shortens backup and restore windows, and correct sizing keeps the database from swapping. Managed Odoo hosting, including Plemo, gives you automated backups, point in time recovery, monitoring, and staging environments, so this work can be rehearsed rather than improvised.

What infrastructure does not do is rewrite a query. If a screen is slow because a computed field runs per row, the same screen will be slow on a bigger server, only slightly less so, and you will have converted a code problem into a recurring bill. Size the instance for real concurrency, then fix the code that is actually doing the work.

A workable order

  • Reproduce the complaint and write down what you measured.
  • Separate environmental from functional by testing against a copy.
  • Fix the per-record work first: store the compute, add the index, batch the loop.
  • Move heavy reports and bulk jobs outside working hours.
  • Archive or delete what nobody uses, once, deliberately, with a backup you have tested.
  • Only then revisit sizing.

Instances rarely get slow all at once. They get slow the way a room gets cluttered, one reasonable decision at a time, which is also how they get fast again.

Let's talk

Let's turn this into a plan.

Book a discovery call and we will map your fastest path to a system that lasts.

Book a discovery call