Skip to Content
Odoo Menu
  • Sign in
  • Try it free
  • Apps
    Finance
    • Accounting
    • Invoicing
    • Expenses
    • Spreadsheet (BI)
    • Documents
    • Sign
    Sales
    • CRM
    • Sales
    • POS Shop
    • POS Restaurant
    • Subscriptions
    • Rental
    Websites
    • Website Builder
    • eCommerce
    • Blog
    • Forum
    • Live Chat
    • eLearning
    Supply Chain
    • Inventory
    • Manufacturing
    • PLM
    • Purchase
    • Maintenance
    • Quality
    Human Resources
    • Employees
    • Recruitment
    • Time Off
    • Appraisals
    • Referrals
    • Fleet
    Marketing
    • Social Marketing
    • Email Marketing
    • SMS Marketing
    • Events
    • Marketing Automation
    • Surveys
    Services
    • Project
    • Timesheets
    • Field Service
    • Helpdesk
    • Planning
    • Appointments
    Productivity
    • Discuss
    • Approvals
    • IoT
    • VoIP
    • Knowledge
    • WhatsApp
    Third party apps Odoo Studio Odoo Cloud Platform
  • Industries
    Retail
    • Book Store
    • Clothing Store
    • Furniture Store
    • Grocery Store
    • Hardware Store
    • Toy Store
    Food & Hospitality
    • Bar and Pub
    • Restaurant
    • Fast Food
    • Guest House
    • Beverage Distributor
    • Hotel
    Real Estate
    • Real Estate Agency
    • Architecture Firm
    • Construction
    • Property Management
    • Gardening
    • Property Owner Association
    Consulting
    • Accounting Firm
    • Odoo Partner
    • Marketing Agency
    • Law firm
    • Talent Acquisition
    • Audit & Certification
    Manufacturing
    • Textile
    • Metal
    • Furnitures
    • Food
    • Brewery
    • Corporate Gifts
    Health & Fitness
    • Sports Club
    • Eyewear Store
    • Fitness Center
    • Wellness Practitioners
    • Pharmacy
    • Hair Salon
    Trades
    • Handyman
    • IT Hardware & Support
    • Solar Energy Systems
    • Shoe Maker
    • Cleaning Services
    • HVAC Services
    Others
    • Nonprofit Organization
    • Environmental Agency
    • Billboard Rental
    • Photography
    • Bike Leasing
    • Software Reseller
    Browse all Industries
  • Community
    Learn
    • Tutorials
    • Documentation
    • Certifications
    • Training
    • Blog
    • Podcast
    Empower Education
    • Education Program
    • Scale Up! Business Game
    • Visit Odoo
    Get the Software
    • Download
    • Compare Editions
    • Releases
    Collaborate
    • Github
    • Forum
    • Events
    • Translations
    • Become a Partner
    • Services for Partners
    • Register your Accounting Firm
    Get Services
    • Find a Partner
    • Find an Accountant
      • Get a Tailored Demo
    • Implementation Services
    • Customer References
    • Support
    • Upgrades
    Github Youtube Twitter Linkedin Instagram Facebook Spotify
    +32 2 290 34 90
    • Get a Tailored Demo
  • Pricing
  • Help
  1. APPS
  2. Inventory
  3. BambooForge Stock Performance: Fix Slow Inventory on Large Databases v 19.0
  4. Sales Conditions FAQ

BambooForge Stock Performance: Fix Slow Inventory on Large Databases

by BambooForge Labs
Odoo

$ 227.34

v 19.0 Third Party
Apps purchases are linked to your Odoo account, please sign in or sign up first.
Versions 16.0 17.0 18.0 19.0
You bought this module and need support? Click here!
Versions 16.0 17.0 18.0 19.0
  • Description
  • Manifest
  • Documentation
  • License
BambooForge Stock Performance
BambooForge Stock Performance by BambooForge Labs · Large-database performance
Odoo 19.0 License OPL-1 No Enterprise required
Stock Performance for Odoo 19
No upgrade required No data migration Identical results Multi-company safe Read-only diagnostic Uninstall-clean
The problem

Aged databases make stock moves crawl

After years of serial tracking, backorders and multi-level manufacturing, Odoo’s stock_move_move_rel link table grows into a dense web — hundreds of millions of edges, single moves linked to thousands of others. The standard code walks that web through the ORM, so Mark as Done, Check Availability and opening a Manufacturing Order take tens of seconds or time out with a 504. Upgrading Odoo does not fix it — the schema and the chaining algorithm are unchanged from 16 to 19. The fix is algorithmic, and it can be applied in place.

Measured speed-up: MTO availability 14.8s to 1.7s, roll-up 6.7s to 0.9s
9×faster Mark-as-Done on a 210M-link database
210Mmove-links handled without materialising them
0changes to reservations or quantities
0schema changes — uninstall-clean
Safe by construction

Faster, and provably the same result

This is a performance change, not a behaviour change. The SQL helpers only gather a set of move ids; those ids are re-resolved through Odoo’s own search(), which re-applies every record rule (including multi-company) and returns them in the exact model order the standard code relies on. The grouping and quantity logic is copied verbatim from standard Odoo. The bundled automated tests assert this equivalence directly.

What gets faster

Mark as Done / Check Availability

The MTO availability traversal walked on every _action_assign is pushed into two bounded SQL queries. The heaviest call on a real database dropped from ~15 s to under 2 s.

Move-chain roll-up

Upstream/downstream chain walks become a set-based breadth-first search over the link table — one query per graph layer instead of one Many2many read per node.

Quant availability

On-hand availability is summed with one grouped query instead of loading every quant of a fragmented (product, location) — the check that fires constantly during reservation.

Verify it yourself

A reproducible benchmark ships with the module (tests/benchmark_move_graph.py): it builds a dense move graph and times the standard traversal against the bounded SQL, asserting identical results.

Record-rule safe

Move ids are re-resolved through search(), so multi-company and every other record rule apply exactly as before. No access bypass.

Move Graph Health diagnostic

A read-only report (Inventory » Reporting) X-rays your link table — size, density, worst-offending moves and how much only traces closed history. It never modifies data.

Drop-in and reversible

Pure method overrides — no schema change, no new stored column, no configuration. Install, and it works. Uninstall, and standard behaviour returns.

See the problem

Measure before you act

The built-in Move Graph Health report quantifies exactly how dense your move graph is — safe to run on production.

Move Graph Health diagnostic report

Who it’s for

Manufacturers and heavy-inventory operations on Odoo 16 with a large stock-move history — especially serial/lot tracking with frequent backorders — whose validations and MO screens have become slow, and who cannot or will not upgrade or migrate hundreds of millions of link rows.

Questions, answered

Will my reservations or quantities change?

No. Only how the move sets are gathered changes; the reservation and quantity logic is untouched and the automated tests assert identical results.

Does it work on multi-company databases?

Yes. Ids are re-resolved through search(), so the multi-company record rule applies exactly as before.

Do I need to upgrade Odoo or migrate data?

No — that is the whole point. It is an in-place algorithmic fix for a problem upgrading does not solve.

What happens on uninstall?

Standard behaviour returns. There is no schema change to reverse.

BambooForge Labs · bambooforge.labs@gmail.com
Odoo 19.0 · License OPL-1 · No Enterprise modules required
Documentation-first — the built-in manual (this page & doc/index.rst) covers install, verification and troubleshooting, so you can run it without a support subscription.
Availability
Odoo Online
Odoo.sh
On Premise
Odoo Apps Dependencies • Inventory (stock)
• Manufacturing (mrp)
• Discuss (mail)
Lines of code 242
Technical Name bambooforge_stock_move_perf
LicenseOPL-1

BambooForge Stock Performance

Make Mark as Done, Check Availability and opening a Manufacturing Order fast again on databases with a large stock-move history — without upgrading Odoo and without migrating your data. This module rewrites the hottest move-graph traversals as bounded SQL that returns the identical result the standard code returns, and ships a read-only diagnostic that shows you exactly how bad the problem is before and after.

This page is the complete manual. Follow it top to bottom and you can install, verify the speed-up and understand precisely what changed without contacting support.

  • The problem
  • What this module does
  • Why the numbers stay identical
  • Installation
  • The Move Graph Health diagnostic
  • Frequently asked questions
  • Support

The problem

Odoo links stock moves to each other through the stock_move_move_rel many-to-many table (move_orig_ids ↔ move_dest_ids). On a young database this table is small. On a database that has run for years — especially with serial/lot tracking, repeated backorders and multi-level manufacturing — it grows a combinatorial, bipartite structure: shared components link to many serial-tracked orders, each backorder keeps chains open, and procurement groups fan out. Link counts in the hundreds of millions and per-move fan-out in the thousands are real.

The standard code walks this graph through the ORM. Every hop (move_orig_ids.move_dest_ids.move_orig_ids) materialises hundreds of thousands of records and re-reads the company-rule-wrapped M2M. The result:

  • Mark as Done on a manufacturing/MTO move calls _action_assign, which calls _get_available_move_lines_in / _out — a single such call has been measured at ~15 seconds on a real 210-million-link database.
  • Opening a Manufacturing Order computes the source/child smart-button counts, which walk the whole procurement group — this can time out or never render the form.
  • Under load these long calls pin worker processes and produce 504 Gateway Timeout.

Upgrading Odoo does not fix this: the stock_move_move_rel schema and the chaining algorithm are unchanged from 16 through 19, and migrating hundreds of millions of link rows is itself slow and risky. The fix is algorithmic, and it can be applied in place.

What this module does

It overrides five methods on stock.move and mrp.production so the graph traversal happens once, in the database, instead of node-by-node in Python:

stock.move._get_available_move_lines_in / _out
The MTO availability traversal walked on every _action_assign. The 2-hop and 3-hop move-id sets are produced by one bounded SQL statement each (DISTINCT collapses the explosion), then re-resolved through search().
stock.move._rollup_move_origs / _rollup_move_dests
The upstream/downstream chain walk, rewritten as a set-based breadth-first search over the link table (one query per graph layer) instead of per-record ORM recursion.
mrp.production._get_children / _get_sources
Manufacturing-order parent/child navigation and the source/child smart-button counts, pushed down to a single bounded query that returns the same MO ids.

It also narrows the dependencies of the mrp_production_child_count / mrp_production_source_count smart-button fields so that writing to a move no longer recomputes them across the entire procurement group.

stock.quant._get_available_quantity
On-hand availability is summed with one grouped SQL query over core's gather domain instead of loading every quant of a fragmented (product, location). Reservation itself is untouched.

Why the numbers stay identical

This is a performance change, not a behaviour change. Three properties keep the results bit-identical to standard Odoo:

  1. Same records. The SQL helpers only produce a set of move ids; those ids are re-resolved with search([('id', 'in', ids)]), which re-applies the stock.move record rules — including the multi-company rule. Nothing bypasses access control.
  2. Same order. search() returns rows in the model order (sequence, id), which is exactly the order the standard ORM chain yields, so the order-dependent itertools.groupby in the availability functions produces the identical grouping. No sorted() is introduced.
  3. Same grouping. The grouping and quantity-summation bodies are copied verbatim from standard Odoo — only the traversal that feeds them is replaced.

The bundled automated tests assert this equivalence directly: for a constructed move graph they check that each SQL helper returns the same id-set as the ORM chain it replaces, that search() re-resolution preserves order, and that a done receipt is summed to the correct quantity.

Installation

  1. Copy bambooforge_stock_move_perf into your addons path.
  2. Update the apps list and install BambooForge Stock Performance.
  3. No configuration and no data migration are required. The overrides are active immediately.

Dependencies: stock and mrp (both standard). No Enterprise modules are needed. There is no schema change and no new stored column, so the module is uninstall-clean.

The Move Graph Health diagnostic

Go to Inventory ▸ Reporting ▸ Move Graph Health. The report runs read-only SQL and shows:

  • Size — the stock_move_move_rel table size and row count, and the number of stock moves.
  • Density — average links per move and the worst single-move fan-out.
  • Prune opportunity — how many links only connect moves that are already in a done or cancel state (i.e. trace closed history), as a share of all links. This is an estimate only; the diagnostic never modifies data.
  • Worst offenders — the twenty highest fan-out moves, with their business reference, product and state, so you can see the real orders behind the numbers.

Use it to quantify the problem before installing elsewhere, and to show stakeholders the density of the graph. It is safe to run on production: every query is read-only and uses planner statistics for the big numbers so it does not full-scan a huge table.

Frequently asked questions

Will my reservations or quantities change?
No. See Why the numbers stay identical above — the change is limited to how the move sets are gathered; the reservation and quantity logic is untouched.
Does it work on multi-company databases?
Yes. Because the move ids are re-resolved through search(), the standard multi-company record rule is applied exactly as before.
Do I need to upgrade Odoo or migrate data?
No. That is the point of the module — it is an in-place algorithmic fix for a problem that upgrading does not solve.
What happens on uninstall?
The overrides are removed and standard behaviour returns. There is no schema change to reverse.
My real bottleneck is disk size, not speed.
This module addresses speed. The Move Graph Health report will also tell you how much of the link table only traces closed history — useful input for a separate slimming effort — but this module never deletes data.

Support

BambooForge Labs — bambooforge.labs@gmail.com

Odoo Proprietary License v1.0

This software and associated files (the "Software") may only be used (executed,
modified, executed after modifications) if you have purchased a valid license
from the authors, typically via Odoo Apps, or if you have received a written
agreement from the authors of the Software (see the COPYRIGHT file).

You may develop Odoo modules that use the Software as a library (typically
by depending on it, importing it and using its resources), but without copying
any source code or material from the Software. You may distribute those
modules under the license of your choice, provided that this license is
compatible with the terms of the Odoo Proprietary License (For example:
LGPL, MIT, or proprietary licenses similar to this one).

It is forbidden to publish, distribute, sublicense, or sell copies of the Software
or modified copies of the Software.

The above copyright notice and this permission notice must be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

Please log in to comment on this module

  • The author can leave a single reply to each comment.
  • This section is meant to ask simple questions or leave a rating. Every report of a problem experienced while using the module should be addressed to the author directly (refer to the following point).
  • If you want to start a discussion with the author or have a question related to your purchase, please use the support page.
Community
  • Tutorials
  • Documentation
  • Forum
Open Source
  • Download
  • Github
  • Runbot
  • Translations
Services
  • Odoo.sh Hosting
  • Support
  • Upgrade
  • Custom Developments
  • Education
  • Find an Accountant
  • Find a Partner
  • Become a Partner
About us
  • Our company
  • Brand Assets
  • Contact us
  • Jobs
  • Events
  • Podcast
  • Blog
  • Customers
  • Legal • Privacy
  • Security

Odoo is a suite of open source business apps that cover all your company needs: CRM, eCommerce, accounting, inventory, point of sale, project management, etc.

Odoo's unique value proposition is to be at the same time very easy to use and fully integrated.

Website made with