- Byte Legions
- Odoo Technical
Introduction to Database Performance in Odoo 19
Odoo 19 brings new power and flexibility for enterprises, but when the data grows into millions of records, performance becomes a real concern. The connection between Odoo and PostgreSQL defines how fast your business operations run. Proper tuning ensures faster loading times, efficient resource use, and an overall smoother experience for users and developers alike.
Why Performance Tuning Matters for Growing Businesses
When data expands, unoptimized systems start showing slow dashboards, delayed reports, and heavy queries. Database tuning in Odoo 19 directly impacts customer experience and employee productivity. Performance tuning helps keep large-dataset handling in Odoo & PostgreSQL responsive and reliable.
Common Challenges in Large-Dataset Handling in Odoo & PostgreSQL
Issues like table bloat, long-running transactions, and inefficient queries arise when data management is neglected. Handling them early prevents database locks, random slowdowns, and resource overconsumption.
Understanding PostgreSQL Architecture for Odoo Developers
How Odoo Communicates with PostgreSQL
Odoo uses its ORM layer to talk with PostgreSQL. Each model corresponds to a table, and each operation triggers SQL queries. When the ORM grows complex, query optimization becomes essential for efficiency.
Key Components Affecting Speed and Efficiency
Key PostgreSQL components such as buffer cache, WAL logs, and background workers all affect how quickly data is processed. A well-configured shared_buffers and effective_cache_size configuration can drastically improve query response time.
Table Partitioning for Performance Enhancement
Range, List, and Hash Partitioning Explained
One of the standout features of Odoo 19 is its updated REST API and JSON-RPC API. These APIs now allow for more robust integrations with third-party systems, including real-time data syncing
Table partitioning (range, list, hash) for performance divides large tables into smaller logical units. This reduces index scan size and speeds up queries.
Example:
CREATE TABLE sale_orders_2025 PARTITION OF sale_orders
FOR VALUES FROM ('2025-01-01') TO ('2025-12-31');
and asynchronous data handling. Developers can now call APIs from external applications and receive responses much faster, with improved error handling mechanisms, making integrations smoother and more reliable.
Implementing Partition-Aware Indexing in PostgreSQL
When indexes are applied to partitions separately, PostgreSQL only scans relevant partitions, improving performance for analytical queries.
Real Case: Reducing Query Time with Table Partitioning
A Byte Legions client saw a 70% reduction in report generation time after switching to monthly partitions for transaction tables.
Memory Configuration for Optimal Query Execution
shared_buffers and effective_cache_size Configuration
Start by assigning 25–40% of RAM to shared_buffers and around 75% for effective_cache_size. This ensures queries make use of in-memory cache instead of disk.
Example:
shared_buffers = 4GB
effective_cache_size = 12GB
work_mem and maintenance_work_mem for Complex Queries
Increasing work_mem and maintenance_work_mem for complex queries helps speed up sorting and joins.
work_mem = 64MB
maintenance_work_mem = 512MB
Tuning Autovacuum for High-Volume Tables
Preventing Bloat and Locking with Proper Settings
autovacuum tuning for high-volume tables is critical. If it runs too slowly, tables grow unnecessarily large.
Example Code for Custom Autovacuum Parameters
ALTER TABLE res_partner SET (
autovacuum_vacuum_scale_factor = 0.1,
autovacuum_analyze_scale_factor = 0.05
);
WAL and Checkpoint Optimization
checkpoint_timeout and WAL Sizing to Reduce IO Spikes
Checkpoint tuning smooths disk writes and reduces latency.checkpoint_timeout = 15min
max_wal_size = 4GB
Adjusting fsync and synchronous_commit for Balance
Set fsync and synchronous_commit to “off” during bulk imports, then re-enable them to ensure durability.
Leveraging Parallel Query Execution
Configuring max_parallel_workers for Multi-Core CPUs
Parallel queries reduce time for heavy computations.
max_parallel_workers = 8
max_parallel_workers_per_gather = 4
Measuring Real Performance Gains
Use EXPLAIN ANALYZE to measure before-and-after query times. Developers at Byte Legions achieved 40% faster analytics reports using this method.
Odoo Worker Configuration and Scaling
Fine-Tuning HTTP, Cron, and Long-Poll Workers
Odoo worker configuration (HTTP, cron, long-poll) defines concurrency and response.workers = 8
limit_memory_hard = 1024 * 1024 * 1024
Practical Setup for High Traffic Environments
Deploying a balanced number of workers ensures efficient CPU use while preventing overload during peak business hours.
Efficient Connection Management
Using Connection Pooling (PgBouncer)
PgBouncer reduces PostgreSQL overhead by reusing connections efficiently.
Limiting max_connections for Stability
max_connections = 200
This avoids connection storms during concurrent user activity.
Data Lifecycle and Archiving Strategies
Archive Inactive Data for Performance Gains
Old records slow queries. Move inactive records to archive tables or external storage.
Automating Data Lifecycle Management with Scripts
env.cr.execute("""
INSERT INTO archive_sales SELECT * FROM sales WHERE order_date < NOW() - INTERVAL '1 year';
DELETE FROM sales WHERE order_date < NOW() - INTERVAL '1 year';
""")
Hardware-Level Optimization Tips
SSD/NVMe I/O Tuning Techniques
Fast disks lower latency. Set random_page_cost=1.1 to reflect SSD speed.
Adjusting random_page_cost and effective_io_concurrency
random_page_cost = 1.1
effective_io_concurrency = 200
Query Optimization and ORM Rewriting
Identifying Slow Queries in Odoo Logs
Enable Odoo’s SQL logging to catch inefficient ORM calls.
Rewriting ORM Queries to Use Partitioning
orders = env['sale.order'].search([('date_order', '>=', '2025-01-01')])
Target partitioned tables to ensure PostgreSQL scans minimal data.
Enhancing Performance with Redis Caching
Session Offloading and Front-End Response Improvement
Redis caching & session offloading for Odoo front-end frees up PostgreSQL from managing session data. This reduces response lag under heavy user load.
Monitoring and Alerting Best Practices
Tools for Tracking Query Performance and Bloat
Use tools like pg_stat_statements, Prometheus, and Grafana to monitor queries and storage growth.
Building an Alert System for Locking and Delays
Automate alerts when deadlocks or long transactions appear, preventing downtime before it affects users.
For a step-by-step guide on building tailored Odoo solutions, check out our detailed article: How to Create a Custom Odoo 19 Module from Scratch
Conclusion: The Road to Scalable Odoo Deployments
Performance tuning is an ongoing discipline, not a one-time task. By continuously monitoring configurations, optimizing queries, and maintaining your PostgreSQL setup, you ensure Odoo 19 scales seamlessly as data grows.
Ready to boost your Odoo performance? Contact Byte Legions today to schedule a professional database optimization session.
FAQs on PostgreSQL & Odoo 19 Performance Tuning
How often should I run VACUUM and ANALYZE on large databases?
Run them weekly for high-volume tables or automate using autovacuum tuning parameters.
Does PgBouncer help when Odoo has multiple workers?
Yes, PgBouncer manages idle connections efficiently, improving performance in multi-worker setups.
Can partitioning affect ORM-based queries?
Proper partition-aware indexing ensures ORM queries automatically use only relevant partitions.
Should I increase work_mem for all queries?
No, apply higher memory only for sessions running large analytical queries.
What’s the best way to monitor query locks?
Use pg_locks view and Grafana dashboards for real-time insights.






Comments are closed