Every Odoo database gets bigger. That is normal, and for most of its life it does not matter. The trouble is that growth is not evenly distributed across tables, and the parts that grow fastest are usually the parts nobody looks at. By the time size becomes visible it rarely arrives as a size complaint. It arrives as a backup that takes twice as long as it used to, a staging copy that is no longer worth waiting for, and an upgrade window that no longer fits into a weekend.
This is a practical look at what actually grows inside an Odoo instance, why it matters operationally before it matters for speed, and what you can reduce without breaking your own records.
What actually grows
In most instances, four things account for the bulk of the growth.
- Attachments and the filestore. Scanned invoices, delivery photos, contract PDFs, product images, generated reports. These do not live in a table you would notice, and in a system where every user attaches documents freely, they usually become the largest single component. Attachments generated by the system, such as saved report PDFs, add up quietly on top of what people upload.
- Messages and tracking. Every chatter message, every logged note, every field-change tracking entry, and every follower record is a row. A workflow-heavy module with tracking enabled on a dozen fields can generate more rows per document than the document itself has lines.
- Transactional lines. Accounting entries, stock moves, and their child records grow with real business volume. This is the growth you want. It is also the growth you must not delete, because it is your legal and financial record.
- Background residue. Log tables, integration payload records, queued job history, and anything an automation writes on every run. A single misconfigured scheduled action writing a record every five minutes produces over 100,000 rows a year for no business reason at all.
Why size matters before speed does
Teams usually expect database size to show up as a slow screen. More often it shows up first in operations.
Backups take longer and cost more to store. Restoring becomes a real decision rather than a routine one, because a restore that takes four hours changes how you think about recovery. Cloning production into a staging environment stops being something you do casually before every change, which quietly erodes the discipline of testing changes outside production. Version upgrades stretch, because the upgrade process has to work through everything in the database, including the rows that carry no business value. And large tables make certain reports and list views heavier even when the underlying code is unchanged.
Speed problems do follow eventually, but by then you have usually been paying an operational tax for months.
What to measure
Two numbers are worth knowing and almost nobody tracks them: the size of your filestore versus the size of your database, and your five largest tables by row count. Take both quarterly and keep the history. A single reading tells you nothing useful. Three readings over a year tell you your growth rate, and the growth rate is what lets you plan a resize or a cleanup before it becomes urgent.
If one table is growing far faster than your transaction volume, that is your signal. Real business growth is proportional. A table growing out of proportion is usually an automation or a tracking configuration, not your business.
What you can safely reduce
The safe wins are almost always outside the accounting and inventory records.
- Turn off field tracking that nobody reads. Tracking is useful on approval fields and status changes. On a description field it is noise you pay to store forever.
- Set a retention policy for log and integration tables, then enforce it with a scheduled cleanup rather than a manual one that happens once and is forgotten.
- Stop generating and storing report PDFs that are never opened again. Regenerating a report on demand is usually cheaper than keeping every copy.
- Review which scheduled actions write records, and how often. This is the highest-yield check on the list and the one most often skipped.
What not to do
Do not delete accounting entries, stock moves, or anything with a legal retention requirement, and do not run manual SQL deletes against an Odoo database to reclaim space. Odoo's ORM maintains relationships, computed values, and constraints that raw SQL will happily ignore, and the damage from a bad delete usually surfaces weeks later in a report that no longer balances. If a cleanup cannot be expressed through Odoo itself, it needs a proper migration script and a tested restore point, not a quick query.
Archiving is not deleting, and it is often the right answer. An archived record still exists and still reports correctly. It just stops appearing in the default views.
Where hosting fits
Managed hosting does not stop a database from growing, and no honest provider will tell you otherwise. What it does is make growth survivable: automated backups, point-in-time recovery, monitoring, and staging environments you can create without a project of their own. Plemo provides managed Odoo hosting on that model, so cloning production to test a cleanup is a routine step rather than a reason to postpone it.
The configuration side, deciding what to track, what to retain, and what an automation should write, is a consulting question rather than an infrastructure one. If you would rather have someone look at it with you, our managed support and SLA service covers exactly this kind of ongoing health work.
Database growth is not a problem to solve once. It is a number to watch, twice a year, for as long as the system is running.
