Tuesday, April 21, 2026
3 changes · saas-19.2
Enhancements to existing features
This change speeds up the validation of stock transfers that involve many move lines by grouping database actions instead of processing them one by one. It reduces delays and helps avoid timeouts on very large deliveries, improving reliability for busy operations.
Original PR description
Before this PR, `button_validate` was using a `write()` call per matched stock move. On every `write()` there is a Command.create and Command.delete which is resulting in N database round-trips for…
Before this PR, `button_validate` was using a `write()` call per matched stock move. On every `write()` there is a Command.create and Command.delete which is resulting in N database round-trips for the unlinks and N for the creates, followed by N separate `_apply_putaway_strategy()` calls. This is problematic for pickings with many move_ids. This PR attempts to accumulates all move lines to delete and to create. Then performs a single `unlink()` and `create()`, followed by a single `_apply_putaway_strategy()` for all pickings. Unlink is done using `.sudo()` to preserve the superuser context that was previously inherited implicitly through the `purchase_order.sudo().search` that produced the recordset used to obtain the `receipt_move`(s). Benchmarks: | No. move lines in delivery | Before | After | | -------------------------- | ------- | ----- | | 7579 | Timeout | < 200 s | opw-5826905 Forward-Port-Of: odoo/enterprise#110587 Forward-Port-Of: odoo/enterprise#110153
Assigning a chart of accounts or fiscal localization now uses much less memory and completes much faster on large databases. The update reduces the chance of failures during setup by moving heavy filtering work to the database and avoiding unnecessary data loading.
Original PR description
## Summary This PR optimizes memory consumption and execution time when assigning a **Chart of Accounts** or **Fiscal Localization**. By moving filtering logic to the database and preventing…
## Summary This PR optimizes memory consumption and execution time when assigning a **Chart of Accounts** or **Fiscal Localization**. By moving filtering logic to the database and preventing expensive field prefetching, we've achieved a **60% reduction in peak memory** and cut execution time by more than half on large datasets. ## The Problem Assigning a chart template was hitting memory limits on databases with a high volume of products (e.g., 2M+). Two main bottlenecks were identified: * **Inefficient filtering**: Loading all `product.template` <-> `tax` relations into the cache and filtering in-memory using python instead of using SQL. * **Excessive prefetching**: Accessing `product.product` fields (like `write_date`) inside the compute function triggered a cache miss that prefetched all product fields, consuming significant memory. ## Improvements * **SQL Filtering:** Pushed the `product_template` filtration logic to the SQL layer to reduce the amount of data loaded into the memory. * **Prefetching Prevention:** Optimized the compute logic to avoid triggering unnecessary field prefetching on `product.product`. --- ## Benchmarks *Tested using `memray` on a customer database with ~2 million products.* | Scenario | Duration | Peak Memory | Total Allocations | | :--- | :--- | :--- | :--- | | **Baseline (Before)** | 10:23.4 | 3.6 GB | 9,954,480 | | **Optimized Prefetching Only** | 10:21.0 | 2.3 GB | 9,292,271 | | **SQL Filtering Only** | 06:30.2 | 3.0 GB | 8,865,050 | | **Combined (Final Result)** | **04:59.6** | **1.4 GB** | **8,213,374** | ### Key Results: * **Memory Saved:** ~2.2 GB (61% reduction) * **Time Saved:** ~5.5 minutes (52% faster) OPW-6070666 Forward-Port-Of: odoo/odoo#259304
We improved how inventory valuation is calculated for past dates, especially for AVCO products. The system now limits unnecessary historical quantity checks, which makes large inventory calculations much faster without changing the result.
Original PR description
When computing Inventory Valuation with a past `As of` date for AVCO products, `_run_average_batch()` reads `qty_available` for each manual `product.value` entry with `product.with_context(to_date=manual_value.date).qty_available`. On large databases, products can carry a broad prefetch set through the `product.value` browsing path. As a result, each distinct `to_date` may compute `qty_available` for more products than necessary. This change narrows the prefetch ids to the products sharing the same manual value date before reading `qty_available`. This keeps the same `to_date`, the same quantity computation, and the same per-product result, while reducing the amount of historical quantity computation done for each date. | Stock moves | Before PR | After PR | | --- | ---: | ---: | | 785k | fails after ~900s | 183s | opw-5944584 Forward-Port-Of: odoo/odoo#256684