← ClaudeAtlas

odoo-perflisted

Making Odoo fast — recordset hygiene (no query-in-loop, search-once-with-in, mapped/filtered/sorted), the ORM cache & prefetching, stored vs non-stored computed fields (write amplification, exhaustive @api.depends), database indexes (index=True and typed indexes), _read_group aggregation, batch create/write, and justified raw SQL with correct cache invalidation. Use whenever an Odoo page/list/report/cron is slow, an N+1 query pattern appears, you're about to add store=True or an index, or you're writing a loop that search()es or browses one record at a time. Measure real SQL counts from the running instance — don't guess. Targets Odoo 17/18/19.
tuanle96/odoo-ai-skills · ★ 4 · AI & Automation · score 62
Install: claude install-skill tuanle96/odoo-ai-skills
# Odoo performance In Odoo, wall-clock is dominated by **SQL query count**, not Python. The ORM already batches writes, prefetches relations, and caches reads across a whole recordset — almost all slowness is *fighting* it: a `search` or `browse` inside a loop turns one query into N. **Measure the real count first**, then fix the hot path. Delegate measurement to the **`odoo-introspect`** skill — `trace_flow` reports `total_sql` and per-call `sql_count`: ```bash odoo-ai --db <DB> trace <model> <record_id> <method> # total_sql + sql_count per call ``` **Version floor: Odoo 17/18, through Odoo 19 (current LTS).** The `_read_group` tuple API and the `flush_*` / `invalidate_*` cache methods are v16/17+; pre-16 uses `read_group` (dicts) and `flush()` / `invalidate_cache()`. Note `read_group` is **deprecated in 18.2** (use `_read_group`, or `formatted_read_group` for formatted public output), and the field aggregate attribute `group_operator` was renamed **`aggregator` in 17.2** — see `skills/odoo-introspect/references/version-matrix.md`. ## Use the built-in, don't hand-roll it | Need | Use | Not | |------|-----|-----| | Count / sum / group per key | `_read_group(domain, groupby, aggregates)` | `search` + count in a loop | | Load N records' relations | one recordset + `mapped` / prefetch | `browse(id)` per row | | Filter / sort already-loaded recs | `recs.filtered(...)`, `recs.sorted(...)` | re-`search` with a tweaked domain | | Update many rows the same way | `recs.write({.