Odoo Performance · intermediate · 10 min read
Database Optimization for Odoo
PostgreSQL tuning for Odoo workloads: indexes on ORM domains, bloat control, connection limits, lock avoidance, and post-migration validation — not generic DBA theory.
Last reviewed 2026-07-30 · Estimated effort: 2–6 weeks typical implementation slice
Table of contents
Odoo database optimization means aligning PostgreSQL with how the ORM queries — indexes on fields in list filters, stored related fields in domains, and foreign keys on high-volume relations — not applying generic warehouse tuning scripts.
Bloat, stale statistics, and autovacuum lag show up as slow stock reports and aging receivables screens after bulk imports or year-end archiving. Routine maintenance windows matter as much as one-time index creation.
Long-running reports and uncommitted transactions block warehouse updates on stock_quant and stock_move. Split heavy reads to replicas or off-peak jobs where architecture allows, and always re-benchmark after Migration upgrades.
Database teams sometimes optimize PostgreSQL without Odoo context — raising shared_buffers while a custom module runs sequential scans on sale_order_line filtered by an unindexed Char field. The fix is application-aware indexing and ORM fixes together.
This article covers PostgreSQL practices tied to Odoo models and operations. Use ORM best practices to reduce query count; use this article to make the queries that remain cheap at scale.
Identify top slow queries from pg_stat_statements and map them to Odoo list views, server actions, and connector searches. Partial indexes help when domains always include state= or company_id= filters.
Custom fields used in search panels and automation domains need explicit index planning — especially Selection and Many2one filters on transaction tables. Coordinate with functional owners before adding indexes on write-heavy columns during peak hours.
- ▸Index foreign keys on line tables touched by picking and invoicing
- ▸Consider pg_trgm for name search on large product and partner tables
- ▸Validate index use with EXPLAIN on staging, not production blindly
- ▸Remove unused indexes that slow writes on hot insert paths
High-churn Odoo tables — mail_message, stock_move, account_move_line — accumulate bloat when autovacuum cannot keep pace. Monitor dead tuple ratios and adjust autovacuum settings for large tables rather than manual vacuum-only firefighting.
Run ANALYZE after large data imports or module updates that add columns used in new reports. Bad row estimates cause nested loop disasters on joins Odoo generates for related fields.
Each Odoo worker holds database connections. Pool sizing must match worker count plus cron and queue workers — excess connections waste memory and increase lock contention.
Reports that open transactions while scanning millions of rows block confirm operations on related records. Prefer read-only reporting replicas, materialized views maintained by scheduled jobs, or export-to-queue patterns for month-end packs.
Odoo version upgrades can change default indexes, ORM SQL, and report queries. Re-run slow query baselines after Migration cutover on the same workflows measured before upgrade.
Data growth without archival strategy eventually dominates query cost. Plan legal retention, message pruning, and attachment storage outside the database when volumes demand it.
- ✓Maintain a living list of top ten slow queries mapped to Odoo modules.
- ✓Index custom fields before they appear in automation and list filters.
- ✓Schedule vacuum and analyze review after bulk imports and upgrades.
- ✓Cap report concurrency during warehouse peak if locks appear on stock tables.
- ✓Use connection pooler settings aligned to actual worker configuration.
- ✓Re-benchmark critical workflows after every major Migration release.
- !Creating indexes on every custom Char field without query evidence.
- !Running REINDEX or full vacuum during operational hours unannounced.
- !Pointing BI tools at primary PostgreSQL with unconstrained ad hoc SQL.
- !Ignoring autovacuum warnings until sequential scans dominate.
- !Assuming Odoo standard indexes cover all custom domain patterns.
- !Increasing max_connections instead of fixing worker and pool mismatch.
PostgreSQL optimization for Odoo is indexing and maintenance aligned to ORM access — plus disciplined reporting that does not hold locks on operational tables.
Next, review caching and worker architecture when the database is healthy but response time still misses targets.
| Option | Best when | Trade-off |
|---|---|---|
| Configure | Standard Odoo covers the need | Limited uniqueness |
| Customize | Differentiating workflow | Upgrade cost |
| Integrate | External system of record | Sync complexity |
Trigger
Business event starts the flow.
Execute
Operate in the system of record.
Validate
Check outcomes and exceptions.
Close
Reconcile and hand off.
Frequently asked questions
Should we add indexes ourselves on production?
Test on staging with EXPLAIN and write-load impact. Use concurrent index creation where supported and schedule during low-traffic windows. Document every custom index for upgrade reviews.
Do read replicas help Odoo UI speed?
Replicas help read-heavy reporting and analytics if queries are routed carefully. Odoo standard UI and writes still hit primary — replicas are not a substitute for ORM fixes on interactive paths.
How often should we prune mail and attachments?
Depends on volume and compliance. mail_message bloat slows chatter and global search — define retention policies and test restore impact before aggressive purge.
What changes after an Odoo upgrade?
Query plans, default indexes, and ORM SQL can shift. Treat upgrade completion as a trigger for full performance regression on named workflows — see the Migration guide for test scope.
Related articles
ORM Performance Best Practices
Odoo ORM patterns that scale: batch operations, prefetch, domain design, computed fields, and avoiding N+1 on sale, stock, and accounting paths.
View →Diagnosing Slow Odoo Systems
A step-by-step audit for slow Odoo: reproduce symptoms, profile requests, inspect SQL, check workers and queues, and isolate custom module cost.
View →Caching Strategies for Odoo
Layered caching for Odoo: ORM cache behavior, HTTP reverse proxy, CDN static assets, session considerations, and safe invalidation when master data changes.
View →Scaling Odoo for Growth
Grow Odoo capacity deliberately: vertical vs horizontal workers, database headroom, read replicas for reporting, multi-company load, and integration scale paths.
View →Related services
Odoo Performance Optimization
Diagnosis and remediation for slow production Odoo — ORM, workers, and operations.
View →Infrastructure & Deployment
Hosting, workers, and deployment practices that keep Odoo responsive under load.
View →Odoo Support
Monitoring, incident response, and AMC for live performance-sensitive systems.
View →PostgreSQL tuning for your Odoo estate?
Share table sizes, custom fields in filters, and recent upgrade timing — we will suggest index and maintenance priorities.
