{"id":4983,"date":"2026-02-11T18:13:22","date_gmt":"2026-02-11T15:13:22","guid":{"rendered":"https:\/\/www.dchost.com\/blog\/vps-hosting-settings-for-odoo-and-erpnext-cpu-ram-workers-and-reverse-proxy\/"},"modified":"2026-02-11T18:13:22","modified_gmt":"2026-02-11T15:13:22","slug":"vps-hosting-settings-for-odoo-and-erpnext-cpu-ram-workers-and-reverse-proxy","status":"publish","type":"post","link":"https:\/\/www.dchost.com\/blog\/en\/vps-hosting-settings-for-odoo-and-erpnext-cpu-ram-workers-and-reverse-proxy\/","title":{"rendered":"VPS Hosting Settings for Odoo and ERPNext: CPU, RAM, Workers and Reverse Proxy"},"content":{"rendered":"<div class=\"dchost-blog-content-wrapper\"><p>When you move Odoo or ERPNext from a test install to a real production system, your <a href=\"https:\/\/www.dchost.com\/vps\">VPS<\/a> suddenly stops being \u201cjust a server\u201d and turns into the backbone of your finance, inventory, sales and HR data. At dchost.com we regularly see the same pattern: the first pilot runs fine, then usage grows, and the application starts feeling slow or unstable. In almost every case, the root cause is not the software itself, but how CPU, RAM, workers and the reverse proxy are sized and tuned.<\/p>\n<p>This guide focuses exactly on those knobs. We will stay practical and opinionated: how many vCPUs and how much RAM per user segment, how to calculate Odoo worker counts, how to think about ERPNext\/Frappe background workers, and how to place Nginx (or another reverse proxy) in front of your stack without breaking long\u2011polling or file uploads. If you already understand why you want Odoo or ERPNext on a VPS and now need production\u2011grade settings, this article is written for you.<\/p>\n<div id=\"toc_container\" class=\"toc_transparent no_bullets\"><p class=\"toc_title\">\u0130&ccedil;indekiler<\/p><ul class=\"toc_list\"><li><a href=\"#Why_Proper_VPS_Tuning_Matters_for_Odoo_and_ERPNext\"><span class=\"toc_number toc_depth_1\">1<\/span> Why Proper VPS Tuning Matters for Odoo and ERPNext<\/a><\/li><li><a href=\"#Choosing_the_Right_VPS_Specs_for_Odoo_and_ERPNext\"><span class=\"toc_number toc_depth_1\">2<\/span> Choosing the Right VPS Specs for Odoo and ERPNext<\/a><ul><li><a href=\"#CPU_Sizing_vCPUs_vs_Concurrent_Users\"><span class=\"toc_number toc_depth_2\">2.1<\/span> CPU Sizing: vCPUs vs Concurrent Users<\/a><\/li><li><a href=\"#RAM_Sizing_Dont_Forget_PostgreSQL_and_Workers\"><span class=\"toc_number toc_depth_2\">2.2<\/span> RAM Sizing: Don\u2019t Forget PostgreSQL and Workers<\/a><\/li><li><a href=\"#Disk_and_IO_NVMe_Really_Helps\"><span class=\"toc_number toc_depth_2\">2.3<\/span> Disk and I\/O: NVMe Really Helps<\/a><\/li><li><a href=\"#Network_Latency_and_Bandwidth\"><span class=\"toc_number toc_depth_2\">2.4<\/span> Network: Latency and Bandwidth<\/a><\/li><\/ul><\/li><li><a href=\"#Configuring_Odoo_Workers_on_a_VPS\"><span class=\"toc_number toc_depth_1\">3<\/span> Configuring Odoo Workers on a VPS<\/a><ul><li><a href=\"#Baseline_Formula_for_Odoo_Workers\"><span class=\"toc_number toc_depth_2\">3.1<\/span> Baseline Formula for Odoo Workers<\/a><\/li><li><a href=\"#MemoryAware_Worker_Calculation\"><span class=\"toc_number toc_depth_2\">3.2<\/span> Memory\u2011Aware Worker Calculation<\/a><\/li><li><a href=\"#Example_odooconf_for_a_4_vCPU_8_GB_VPS\"><span class=\"toc_number toc_depth_2\">3.3<\/span> Example odoo.conf for a 4 vCPU \/ 8 GB VPS<\/a><\/li><li><a href=\"#Mapping_Odoo_Workers_to_Concurrent_Users\"><span class=\"toc_number toc_depth_2\">3.4<\/span> Mapping Odoo Workers to Concurrent Users<\/a><\/li><\/ul><\/li><li><a href=\"#ERPNext_Frappe_Web_Workers_and_Scheduler\"><span class=\"toc_number toc_depth_1\">4<\/span> ERPNext \/ Frappe: Web, Workers and Scheduler<\/a><ul><li><a href=\"#Web_Workers_for_ERPNext\"><span class=\"toc_number toc_depth_2\">4.1<\/span> Web Workers for ERPNext<\/a><\/li><li><a href=\"#Background_Workers_and_Queues\"><span class=\"toc_number toc_depth_2\">4.2<\/span> Background Workers and Queues<\/a><\/li><li><a href=\"#Memory_Planning_for_ERPNext_Workers\"><span class=\"toc_number toc_depth_2\">4.3<\/span> Memory Planning for ERPNext Workers<\/a><\/li><\/ul><\/li><li><a href=\"#Reverse_Proxy_Architecture_for_Odoo_and_ERPNext\"><span class=\"toc_number toc_depth_1\">5<\/span> Reverse Proxy Architecture for Odoo and ERPNext<\/a><ul><li><a href=\"#Key_Nginx_Settings_for_Odoo\"><span class=\"toc_number toc_depth_2\">5.1<\/span> Key Nginx Settings for Odoo<\/a><\/li><li><a href=\"#Nginx_Settings_for_ERPNext\"><span class=\"toc_number toc_depth_2\">5.2<\/span> Nginx Settings for ERPNext<\/a><\/li><li><a href=\"#Running_Multiple_Sites_on_One_Reverse_Proxy\"><span class=\"toc_number toc_depth_2\">5.3<\/span> Running Multiple Sites on One Reverse Proxy<\/a><\/li><\/ul><\/li><li><a href=\"#Memory_Swap_and_Stability_Under_Load\"><span class=\"toc_number toc_depth_1\">6<\/span> Memory, Swap and Stability Under Load<\/a><ul><li><a href=\"#Practical_Memory_Rules_of_Thumb\"><span class=\"toc_number toc_depth_2\">6.1<\/span> Practical Memory Rules of Thumb<\/a><\/li><li><a href=\"#PostgreSQL_Shared_Buffers_and_Work_Mem\"><span class=\"toc_number toc_depth_2\">6.2<\/span> PostgreSQL Shared Buffers and Work Mem<\/a><\/li><\/ul><\/li><li><a href=\"#Concrete_Sizing_Scenarios\"><span class=\"toc_number toc_depth_1\">7<\/span> Concrete Sizing Scenarios<\/a><ul><li><a href=\"#Scenario_1_Small_Team_Pilot_1015_Active_Users\"><span class=\"toc_number toc_depth_2\">7.1<\/span> Scenario 1: Small Team Pilot (10\u201315 Active Users)<\/a><\/li><li><a href=\"#Scenario_2_Growing_Company_3060_Active_Users\"><span class=\"toc_number toc_depth_2\">7.2<\/span> Scenario 2: Growing Company (30\u201360 Active Users)<\/a><\/li><li><a href=\"#Scenario_3_MultiDepartment_MultiCompany_80200_Active_Users\"><span class=\"toc_number toc_depth_2\">7.3<\/span> Scenario 3: Multi\u2011Department \/ Multi\u2011Company (80\u2013200+ Active Users)<\/a><\/li><\/ul><\/li><li><a href=\"#Operations_Monitoring_Alerts_and_Load_Testing\"><span class=\"toc_number toc_depth_1\">8<\/span> Operations: Monitoring, Alerts and Load Testing<\/a><ul><li><a href=\"#Key_Metrics_to_Watch\"><span class=\"toc_number toc_depth_2\">8.1<\/span> Key Metrics to Watch<\/a><\/li><li><a href=\"#Load_Testing_Before_Big_GoLives\"><span class=\"toc_number toc_depth_2\">8.2<\/span> Load Testing Before Big Go\u2011Lives<\/a><\/li><\/ul><\/li><li><a href=\"#Security_and_Access_Basics_for_ERP_VPS_Setups\"><span class=\"toc_number toc_depth_1\">9<\/span> Security and Access Basics for ERP VPS Setups<\/a><\/li><li><a href=\"#Summary_Turning_Your_Odoo_ERPNext_VPS_into_a_Reliable_Platform\"><span class=\"toc_number toc_depth_1\">10<\/span> Summary: Turning Your Odoo \/ ERPNext VPS into a Reliable Platform<\/a><\/li><\/ul><\/div>\n<h2><span id=\"Why_Proper_VPS_Tuning_Matters_for_Odoo_and_ERPNext\">Why Proper VPS Tuning Matters for Odoo and ERPNext<\/span><\/h2>\n<p>Odoo and ERPNext are not simple brochure websites. They are full\u2011stack business applications that combine:<\/p>\n<ul>\n<li>A Python web application (Odoo or Frappe framework)<\/li>\n<li>A relational database (PostgreSQL for both Odoo and ERPNext)<\/li>\n<li>Background workers for emails, reports, scheduled jobs and integrations<\/li>\n<li>Long\u2011polling \/ WebSocket\u2011style connections for notifications and chats<\/li>\n<li>Static files and attachments (documents, images, exports)<\/li>\n<\/ul>\n<p>All of these share the same VPS CPU, RAM, disk and network. When you underestimate just one layer (for example worker memory or disk IOPS), it will usually surface as generic \u201cOdoo is slow\u201d or \u201cERPNext keeps timing out\u201d. A well\u2011sized VPS with correctly tuned workers and a properly configured reverse proxy can often double perceived performance without changing a single line of code.<\/p>\n<p>If you want a broader overview of platform choices and architecture options, we already covered that in <a href=\"https:\/\/www.dchost.com\/blog\/en\/odoo-erpnext-ve-diger-crm-erp-uygulamalari-icin-vps-hosting-rehberi\/\">our earlier guide on VPS hosting for Odoo, ERPNext and other self\u2011hosted CRM\/ERP applications<\/a>. Here we\u2019ll go deeper into concrete CPU, RAM, worker and reverse proxy settings.<\/p>\n<h2><span id=\"Choosing_the_Right_VPS_Specs_for_Odoo_and_ERPNext\">Choosing the Right VPS Specs for Odoo and ERPNext<\/span><\/h2>\n<p>You cannot tune what you don\u2019t have. Before editing configuration files, you need a realistic baseline for vCPU, RAM, disk and network. These recommendations assume modern Linux (Ubuntu, Debian or similar) and PostgreSQL on the same VPS as the application server.<\/p>\n<h3><span id=\"CPU_Sizing_vCPUs_vs_Concurrent_Users\">CPU Sizing: vCPUs vs Concurrent Users<\/span><\/h3>\n<p>For Odoo and ERPNext, CPU is primarily consumed by:<\/p>\n<ul>\n<li>Web workers handling HTTP requests<\/li>\n<li>Background job workers (emails, reports, integrations)<\/li>\n<li>Database queries and indexing<\/li>\n<\/ul>\n<p>A rough but practical mapping we see in real projects:<\/p>\n<ul>\n<li><strong>Small pilot (5\u201315 active users)<\/strong>: 2 vCPU<\/li>\n<li><strong>Growing team (15\u201350 active users)<\/strong>: 4 vCPU<\/li>\n<li><strong>Busy multi\u2011department setup (50\u2013150 active users)<\/strong>: 8 vCPU<\/li>\n<li><strong>Heavier usage (150+ active users)<\/strong>: 8+ vCPU and usually separate DB and app nodes<\/li>\n<\/ul>\n<p>This assumes \u201cactive users\u201d are really clicking around at the same time, not just having a tab open. It also assumes standard usage (sales, inventory, accounting) and not extremely heavy custom reports or huge batch imports.<\/p>\n<p>If you want a more generic methodology that you can apply beyond ERPs, we recommend reading our article on <a href=\"https:\/\/www.dchost.com\/blog\/en\/wordpress-blog-woocommerce-ve-saas-icin-kac-cpu-ne-kadar-ram\/\">how many vCPUs and how much RAM you really need on a VPS<\/a>; the same thinking applies here, only the numbers shift slightly higher because ERPs are heavier than typical CMS workloads.<\/p>\n<h3><span id=\"RAM_Sizing_Dont_Forget_PostgreSQL_and_Workers\">RAM Sizing: Don\u2019t Forget PostgreSQL and Workers<\/span><\/h3>\n<p>CPU makes things fast, RAM keeps them stable. Odoo and ERPNext processes are relatively memory\u2011hungry, and PostgreSQL also needs a decent share. As a practical starting point:<\/p>\n<ul>\n<li><strong>Small pilot (5\u201315 active users):<\/strong> 4 GB RAM minimum (2 GB is possible for pure testing, not recommended for production)<\/li>\n<li><strong>Growing team (15\u201350 active users):<\/strong> 8 GB RAM<\/li>\n<li><strong>Busy multi\u2011department setup (50\u2013150 active users):<\/strong> 16 GB RAM<\/li>\n<\/ul>\n<p>Empirically, you can think in terms of memory budget (numbers are rough but useful):<\/p>\n<ul>\n<li>Odoo\/ERPNext web + background workers: ~150\u2013300 MB per worker process<\/li>\n<li>PostgreSQL: 1\u20133 GB for small\/medium databases, more for large datasets<\/li>\n<li>Redis (often used by ERPNext): 256\u2013512 MB<\/li>\n<li>OS + monitoring + other daemons: 512 MB\u20131 GB<\/li>\n<\/ul>\n<p>We\u2019ll use these numbers later when calculating worker counts. For a deeper dive into how the kernel behaves under memory pressure, including swap and out\u2011of\u2011memory kills, see our guide on <a href=\"https:\/\/www.dchost.com\/blog\/en\/vpste-ram-swap-ve-oom-killer-yonetimi\/\">managing RAM, swap and the Linux OOM killer on VPS servers<\/a>.<\/p>\n<h3><span id=\"Disk_and_IO_NVMe_Really_Helps\">Disk and I\/O: NVMe Really Helps<\/span><\/h3>\n<p>ERPs write lots of small database rows and attachments (PDF invoices, bills, product images). Slow disk means slow everything \u2013 PostgreSQL, background jobs, even login times. For production Odoo\/ERPNext we strongly advise:<\/p>\n<ul>\n<li><strong>NVMe SSD\u2011backed VPS<\/strong> (as provided in dchost.com VPS plans) rather than HDD or very old SATA SSD<\/li>\n<li>At least 50\u2013100 GB of disk to leave headroom for logs and backups<\/li>\n<li>Regular external backups to object storage or another server<\/li>\n<\/ul>\n<p>If you are comparing different disk options for a larger deployment, our general comparison of NVMe vs SATA vs HDD for hosting can help frame your choices.<\/p>\n<h3><span id=\"Network_Latency_and_Bandwidth\">Network: Latency and Bandwidth<\/span><\/h3>\n<p>Odoo and ERPNext are mostly low\u2011bandwidth (database\u2011driven) applications, but latency matters a lot. Place your VPS in a region close to your main office(s), and make sure you have enough outbound bandwidth for backups and potential integrations. At dchost.com we can help align VPS or <a href=\"https:\/\/www.dchost.com\/dedicated-server\">dedicated server<\/a> locations with your user base to keep round\u2011trip times under control.<\/p>\n<h2><span id=\"Configuring_Odoo_Workers_on_a_VPS\">Configuring Odoo Workers on a VPS<\/span><\/h2>\n<p>Odoo uses a multi\u2011process model in production. The two key concepts are:<\/p>\n<ul>\n<li><strong>Workers<\/strong>: Processes that handle normal HTTP requests (CRUD screens, forms, reports)<\/li>\n<li><strong>Long\u2011polling workers<\/strong>: Processes dedicated to \u201clive\u201d features such as chat and notifications<\/li>\n<\/ul>\n<p>By default, a fresh Odoo install may run in single\u2011threaded \u201cdev style\u201d mode, which is fine for testing but not for production. Let\u2019s walk through realistic worker sizing.<\/p>\n<h3><span id=\"Baseline_Formula_for_Odoo_Workers\">Baseline Formula for Odoo Workers<\/span><\/h3>\n<p>Odoo\u2019s own rule of thumb is:<\/p>\n<ul>\n<li><strong>workers \u2248 (vCPU * 2) + 1<\/strong><\/li>\n<\/ul>\n<p>This assumes:<\/p>\n<ul>\n<li>You are running only Odoo on that VPS<\/li>\n<li>PostgreSQL is on another host (which is often not true for small setups)<\/li>\n<li>Sufficient RAM for the resulting worker count<\/li>\n<\/ul>\n<p>In real\u2011world single\u2011VPS setups we usually go more conservative, because PostgreSQL and other services also need CPU and memory.<\/p>\n<h3><span id=\"MemoryAware_Worker_Calculation\">Memory\u2011Aware Worker Calculation<\/span><\/h3>\n<p>Let\u2019s say you have a 4 vCPU \/ 8 GB RAM VPS running Odoo + PostgreSQL. We estimate:<\/p>\n<ul>\n<li>Reserve 2 GB for the OS, monitoring, Nginx and safety margin<\/li>\n<li>Reserve 2\u20133 GB for PostgreSQL<\/li>\n<li>Leave ~3 GB for Odoo workers<\/li>\n<\/ul>\n<p>If each Odoo worker typically uses 200\u2013250 MB under load, you can safely run:<\/p>\n<ul>\n<li>3 GB \/ 0.25 GB \u2248 12 workers (theoretical max)<\/li>\n<\/ul>\n<p>But we also care about CPU. With 4 vCPU, running 12 workers would be excessive. A more balanced configuration would be:<\/p>\n<ul>\n<li><strong>workers = 6<\/strong> (normal HTTP workers)<\/li>\n<li><strong>longpolling_workers = 1<\/strong> (for live notifications)<\/li>\n<\/ul>\n<p>This uses roughly 7 workers total, which an 8 GB VPS can handle comfortably under typical usage while leaving headroom.<\/p>\n<h3><span id=\"Example_odooconf_for_a_4_vCPU_8_GB_VPS\">Example odoo.conf for a 4 vCPU \/ 8 GB VPS<\/span><\/h3>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">[options]\n; basic\ndb_host = False\ndb_port = False\ndb_user = odoo\ndb_password = STRONG_PASSWORD\n\n; networking\nxmlrpc_port = 8069\nlongpolling_port = 8072\nproxy_mode = True\n\n; workers\nworkers = 6\nmax_cron_threads = 2\nlimit_memory_soft = 2147483648        ; 2 GB per worker\nlimit_memory_hard = 2684354560        ; 2.5 GB per worker\nlimit_request = 8192\nlimit_time_cpu = 60\nlimit_time_real = 120\n\n; logging\nlogfile = \/var\/log\/odoo\/odoo.log\nlogrotate = True\n<\/code><\/pre>\n<p>Notes:<\/p>\n<ul>\n<li><strong>proxy_mode = True<\/strong> tells Odoo it is behind a reverse proxy (Nginx), so it trusts X\u2011Forwarded headers.<\/li>\n<li><strong>limit_memory_soft\/hard<\/strong> should be below total RAM; they protect you from runaway modules consuming all memory.<\/li>\n<li><strong>max_cron_threads<\/strong> controls concurrent scheduled jobs; 1\u20132 is enough for most SMEs.<\/li>\n<\/ul>\n<h3><span id=\"Mapping_Odoo_Workers_to_Concurrent_Users\">Mapping Odoo Workers to Concurrent Users<\/span><\/h3>\n<p>A very approximate but handy mapping:<\/p>\n<ul>\n<li>1 worker can serve ~6\u201310 simultaneous active users comfortably<\/li>\n<\/ul>\n<p>So with 6 workers you can often support 40\u201360 active users doing a mix of operations (sales, inventory, accounting) as long as database and disk are healthy. If you see CPU pinned at 100% and requests queuing during busy periods, you may:<\/p>\n<ul>\n<li>Increase workers <strong>slightly<\/strong> (if RAM allows)<\/li>\n<li>Optimize heavy reports or scheduled jobs<\/li>\n<li>Move PostgreSQL to a separate VPS or dedicated server<\/li>\n<\/ul>\n<h2><span id=\"ERPNext_Frappe_Web_Workers_and_Scheduler\">ERPNext \/ Frappe: Web, Workers and Scheduler<\/span><\/h2>\n<p>ERPNext runs on the Frappe framework and uses a slightly different process model, usually managed via <code>bench<\/code> and Supervisor or systemd. In production you typically see these process types:<\/p>\n<ul>\n<li><strong>web<\/strong>: Gunicorn or similar WSGI workers handling HTTP requests<\/li>\n<li><strong>worker<\/strong>: Background job workers for queued tasks<\/li>\n<li><strong>worker-short \/ worker-long<\/strong>: Separate queues (short\u2011 and long\u2011running jobs)<\/li>\n<li><strong>schedule<\/strong>: Scheduler for cron\u2011like tasks<\/li>\n<\/ul>\n<h3><span id=\"Web_Workers_for_ERPNext\">Web Workers for ERPNext<\/span><\/h3>\n<p>A common Gunicorn rule of thumb is:<\/p>\n<ul>\n<li><strong>workers \u2248 (vCPU * 2) + 1<\/strong><\/li>\n<\/ul>\n<p>As with Odoo, on smaller single\u2011VPS setups we go more conservative to leave capacity for PostgreSQL and background workers. For example, on a 4 vCPU \/ 8 GB VPS:<\/p>\n<ul>\n<li><strong>web: 4 workers<\/strong> (Gunicorn)<\/li>\n<li><strong>timeout: 120 seconds<\/strong> (for heavy reports; adjust if needed)<\/li>\n<\/ul>\n<p>Configured via <code>Procfile<\/code> or bench configuration, then managed by Supervisor or systemd.<\/p>\n<h3><span id=\"Background_Workers_and_Queues\">Background Workers and Queues<\/span><\/h3>\n<p>ERPNext relies heavily on background jobs for sending emails, running reports, integrations and scheduled tasks. A simple but effective layout on a 4 vCPU \/ 8 GB VPS might be:<\/p>\n<ul>\n<li><strong>worker:<\/strong> 2 processes<\/li>\n<li><strong>worker-short:<\/strong> 1 process<\/li>\n<li><strong>worker-long:<\/strong> 1 process<\/li>\n<li><strong>schedule:<\/strong> 1 process<\/li>\n<\/ul>\n<p>This gives you concurrency for normal jobs, keeps long\u2011running tasks from blocking everything, and leaves enough CPU for web workers and PostgreSQL. If email sending or integrations build up a queue, you can scale <code>worker<\/code> and <code>worker-short<\/code> up \u2013 always watching CPU and RAM usage.<\/p>\n<h3><span id=\"Memory_Planning_for_ERPNext_Workers\">Memory Planning for ERPNext Workers<\/span><\/h3>\n<p>Frappe workers are Python processes similar in size to Odoo workers. As a rough estimate:<\/p>\n<ul>\n<li>Web worker: 150\u2013250 MB<\/li>\n<li>Background worker: 150\u2013250 MB<\/li>\n<li>Redis: 256\u2013512 MB<\/li>\n<\/ul>\n<p>So in the example above (4 web workers + 4 background workers + 1 scheduler), you might allocate:<\/p>\n<ul>\n<li>~8 workers \u00d7 250 MB \u2248 2 GB<\/li>\n<li>Redis: 512 MB<\/li>\n<li>PostgreSQL: 2\u20133 GB<\/li>\n<li>OS + Nginx + margin: 1.5\u20132 GB<\/li>\n<\/ul>\n<p>That fits well into an 8 GB VPS as long as you avoid excessive additional daemons. If you consistently run close to the RAM limit, enable swap carefully (see our article on <a href=\"https:\/\/www.dchost.com\/blog\/en\/vpste-ram-swap-ve-oom-killer-yonetimi\/\">RAM, swap and OOM killer management<\/a>) and plan a RAM upgrade or process tuning.<\/p>\n<h2><span id=\"Reverse_Proxy_Architecture_for_Odoo_and_ERPNext\">Reverse Proxy Architecture for Odoo and ERPNext<\/span><\/h2>\n<p>Running Odoo or ERPNext directly on port 8069 or 8000 is fine for internal tests, but production should always place a reverse proxy (commonly Nginx) in front. The reverse proxy handles:<\/p>\n<ul>\n<li>HTTPS termination (SSL\/TLS)<\/li>\n<li>HTTP\/2 or HTTP\/3 support<\/li>\n<li>Request buffering and limits (file uploads, timeouts)<\/li>\n<li>Static assets caching (CSS, JS, images)<\/li>\n<li>Path\u2011 or host\u2011based routing for multiple apps<\/li>\n<\/ul>\n<p>We have a general, hands\u2011on tutorial on reverse proxies in our article on <a href=\"https:\/\/www.dchost.com\/blog\/en\/nginx-reverse-proxy-ve-basit-load-balancer-kurulumu-kucuk-projeler-icin-uygulamali-rehber\/\">step\u2011by\u2011step Nginx reverse proxy setup<\/a>. Below we\u2019ll tailor the configuration specifically for Odoo and ERPNext.<\/p>\n<h3><span id=\"Key_Nginx_Settings_for_Odoo\">Key Nginx Settings for Odoo<\/span><\/h3>\n<p>Typical Odoo ports:<\/p>\n<ul>\n<li>Application (XML\u2011RPC\/HTTP): <strong>8069<\/strong><\/li>\n<li>Long\u2011polling: <strong>8072<\/strong><\/li>\n<\/ul>\n<p>A minimal but production\u2011friendly Nginx configuration might look like this:<\/p>\n<pre class=\"language-nginx line-numbers\"><code class=\"language-nginx\">upstream odoo {\n    server 127.0.0.1:8069 max_fails=3 fail_timeout=30s;\n}\n\nupstream odoo_longpolling {\n    server 127.0.0.1:8072 max_fails=3 fail_timeout=30s;\n}\n\nserver {\n    listen 80;\n    server_name erp.example.com;\n\n    # Redirect HTTP to HTTPS\n    return 301 https:\/\/$host$request_uri;\n}\n\nserver {\n    listen 443 ssl http2;\n    server_name erp.example.com;\n\n    # SSL configuration (certs, protocols, ciphers)\n    ssl_certificate     \/etc\/letsencrypt\/live\/erp.example.com\/fullchain.pem;\n    ssl_certificate_key \/etc\/letsencrypt\/live\/erp.example.com\/privkey.pem;\n\n    # Recommended headers\n    proxy_set_header X-Forwarded-Host $host;\n    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n    proxy_set_header X-Forwarded-Proto $scheme;\n    proxy_set_header X-Real-IP $remote_addr;\n\n    # Increase upload limits for attachments\n    client_max_body_size 64m;\n    proxy_read_timeout   720s;\n    proxy_connect_timeout 60s;\n    proxy_send_timeout   720s;\n\n    # Static files (optional, if you serve them via Odoo)\n    location \/web\/static\/ {\n        proxy_cache_valid 200 90m;\n        proxy_buffering on;\n        expires 864000;\n        proxy_pass http:\/\/odoo;\n    }\n\n    location \/longpolling {\n        proxy_pass http:\/\/odoo_longpolling;\n        proxy_set_header X-Forwarded-Host $host;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_read_timeout 720s;\n        proxy_buffering off;\n    }\n\n    location \/ {\n        proxy_pass http:\/\/odoo;\n        proxy_redirect off;\n        proxy_buffering on;\n        proxy_read_timeout 720s;\n    }\n}\n<\/code><\/pre>\n<p>Key points:<\/p>\n<ul>\n<li><strong>proxy_set_header<\/strong> lines are essential so Odoo can generate correct URLs and log client IPs.<\/li>\n<li><strong>client_max_body_size<\/strong> must be large enough for your biggest attachment uploads.<\/li>\n<li><strong>proxy_read_timeout<\/strong> is extended to avoid timeouts during large exports or reports.<\/li>\n<li><strong>\/longpolling<\/strong> is mapped to the long\u2011polling port to keep live notifications responsive.<\/li>\n<\/ul>\n<h3><span id=\"Nginx_Settings_for_ERPNext\">Nginx Settings for ERPNext<\/span><\/h3>\n<p>ERPNext has an official Nginx template generated by <code>bench setup nginx<\/code>, which you should use as a base and then tune. Most of the concepts are similar:<\/p>\n<ul>\n<li>Upstream to Gunicorn web workers<\/li>\n<li>Proper proxy headers<\/li>\n<li>Increased timeouts for long reports<\/li>\n<li>client_max_body_size for attachment uploads<\/li>\n<\/ul>\n<p>One extra consideration is static assets and caching. ERPNext\u2019s Nginx template usually sets strong caching on assets (hashed filenames), which is good. Just make sure you reload Nginx after bench updates if the template changes.<\/p>\n<h3><span id=\"Running_Multiple_Sites_on_One_Reverse_Proxy\">Running Multiple Sites on One Reverse Proxy<\/span><\/h3>\n<p>It\u2019s common to run several instances on the same VPS, for example:<\/p>\n<ul>\n<li><code>erp.company.com<\/code> \u2192 production Odoo<\/li>\n<li><code>test.company.com<\/code> \u2192 staging Odoo or ERPNext<\/li>\n<\/ul>\n<p>Each gets its own <code>server<\/code> block with its own <a href=\"https:\/\/www.dchost.com\/ssl\">SSL certificate<\/a> and upstream definition. If you also host a public website (WordPress, Laravel, etc.) on the same VPS, consider isolating workloads carefully and watching your resource usage; we have a dedicated article on <a href=\"https:\/\/www.dchost.com\/blog\/en\/vps-kaynak-kullanimi-izleme-rehberi-htop-iotop-netdata-ve-prometheus\/\">monitoring VPS resource usage with htop, iotop, Netdata and Prometheus<\/a> that shows how to catch contention early.<\/p>\n<h2><span id=\"Memory_Swap_and_Stability_Under_Load\">Memory, Swap and Stability Under Load<\/span><\/h2>\n<p>Even with correct CPU and worker counts, memory pressure can cause random slowness or crashes. Typical symptoms include:<\/p>\n<ul>\n<li>Odoo\/ERPNext workers being killed and restarted<\/li>\n<li>PostgreSQL errors about out\u2011of\u2011memory<\/li>\n<li>The whole VPS becoming unresponsive during large imports<\/li>\n<\/ul>\n<h3><span id=\"Practical_Memory_Rules_of_Thumb\">Practical Memory Rules of Thumb<\/span><\/h3>\n<ul>\n<li>Keep at least <strong>15\u201325% of RAM free<\/strong> during normal load.<\/li>\n<li>Don\u2019t run more workers than your RAM budget realistically allows (see earlier calculations).<\/li>\n<li>Enable a <strong>moderate swap<\/strong> (e.g. 1\u20132\u00d7 RAM for small VPS) to absorb spikes, but do not rely on swap for normal operation.<\/li>\n<li>Lower Odoo\/ERPNext worker memory limits (<code>limit_memory_soft\/hard<\/code> in Odoo; fewer workers in ERPNext) if you see frequent OOM kills.<\/li>\n<\/ul>\n<p>Our detailed article on <a href=\"https:\/\/www.dchost.com\/blog\/en\/vpste-ram-swap-ve-oom-killer-yonetimi\/\">RAM, swap and OOM killer management on VPS servers<\/a> walks through real commands (<code>free -h<\/code>, <code>dmesg<\/code>, <code>journalctl<\/code>) to see whether the kernel is killing your processes.<\/p>\n<h3><span id=\"PostgreSQL_Shared_Buffers_and_Work_Mem\">PostgreSQL Shared Buffers and Work Mem<\/span><\/h3>\n<p>For small and medium Odoo\/ERPNext databases on the same VPS, simple PostgreSQL tuning goes a long way:<\/p>\n<ul>\n<li><strong>shared_buffers<\/strong>: 20\u201325% of RAM (but not more than a few GB)<\/li>\n<li><strong>work_mem<\/strong>: 8\u201332 MB per connection for small setups<\/li>\n<\/ul>\n<p>Be cautious: both values multiply with concurrent connections. Over\u2011tuning PostgreSQL can starve your application workers.<\/p>\n<h2><span id=\"Concrete_Sizing_Scenarios\">Concrete Sizing Scenarios<\/span><\/h2>\n<p>Let\u2019s translate all the above into three realistic scenarios we often implement for clients at dchost.com.<\/p>\n<h3><span id=\"Scenario_1_Small_Team_Pilot_1015_Active_Users\">Scenario 1: Small Team Pilot (10\u201315 Active Users)<\/span><\/h3>\n<ul>\n<li><strong>Use case<\/strong>: Single company, basic CRM + sales + invoicing, light inventory.<\/li>\n<li><strong>Recommended VPS<\/strong>: 2 vCPU, 4 GB RAM, 80 GB NVMe disk.<\/li>\n<\/ul>\n<p><strong>Odoo example:<\/strong><\/p>\n<ul>\n<li>workers = 3<\/li>\n<li>longpolling_workers = 1<\/li>\n<li>max_cron_threads = 1<\/li>\n<\/ul>\n<p><strong>ERPNext example:<\/strong><\/p>\n<ul>\n<li>Gunicorn web workers: 2<\/li>\n<li>worker: 1<\/li>\n<li>worker-short: 1<\/li>\n<li>schedule: 1<\/li>\n<\/ul>\n<p>This fits comfortably in 4 GB RAM if you keep PostgreSQL and Redis settings modest. For pilots, this is usually enough, and you can scale vertically as usage grows.<\/p>\n<h3><span id=\"Scenario_2_Growing_Company_3060_Active_Users\">Scenario 2: Growing Company (30\u201360 Active Users)<\/span><\/h3>\n<ul>\n<li><strong>Use case<\/strong>: Several departments on Odoo\/ERPNext (Sales, Purchase, Inventory, Accounting), daily imports\/exports.<\/li>\n<li><strong>Recommended VPS<\/strong>: 4 vCPU, 8\u201312 GB RAM, 160+ GB NVMe disk.<\/li>\n<\/ul>\n<p><strong>Odoo example (4 vCPU \/ 8 GB):<\/strong><\/p>\n<ul>\n<li>workers = 6<\/li>\n<li>longpolling_workers = 1<\/li>\n<li>max_cron_threads = 2<\/li>\n<\/ul>\n<p><strong>ERPNext example (4 vCPU \/ 8 GB):<\/strong><\/p>\n<ul>\n<li>Gunicorn web workers: 4<\/li>\n<li>worker: 2<\/li>\n<li>worker-short: 1<\/li>\n<li>worker-long: 1<\/li>\n<li>schedule: 1<\/li>\n<\/ul>\n<p>At this stage you should also invest in proper monitoring. Our guide on <a href=\"https:\/\/www.dchost.com\/blog\/en\/vps-kaynak-kullanimi-izleme-rehberi-htop-iotop-netdata-ve-prometheus\/\">monitoring VPS resource usage with htop, iotop, Netdata and Prometheus<\/a> shows how to build dashboards and alerts before users start complaining.<\/p>\n<h3><span id=\"Scenario_3_MultiDepartment_MultiCompany_80200_Active_Users\">Scenario 3: Multi\u2011Department \/ Multi\u2011Company (80\u2013200+ Active Users)<\/span><\/h3>\n<ul>\n<li><strong>Use case<\/strong>: Many concurrent users, heavy accounting and reporting, integrations (e\u2011commerce, external WMS, etc.).<\/li>\n<li><strong>Recommended architecture<\/strong>: Separate database and application layers.<\/li>\n<\/ul>\n<p>A common layout:<\/p>\n<ul>\n<li><strong>Application VPS<\/strong>: 8 vCPU, 16\u201332 GB RAM, running Odoo\/ERPNext web + workers + Nginx.<\/li>\n<li><strong>Database VPS or dedicated server<\/strong>: 8+ vCPU, 32\u201364 GB RAM, tuned PostgreSQL and fast NVMe storage.<\/li>\n<\/ul>\n<p>At this scale, per\u2011project tuning becomes highly specific: index optimization, caching, connection pooling, sometimes even read replicas for reporting. dchost.com can provide both powerful VPS instances and bare\u2011metal dedicated servers or colocation if you want to bring your own hardware and run PostgreSQL on a fully isolated node.<\/p>\n<h2><span id=\"Operations_Monitoring_Alerts_and_Load_Testing\">Operations: Monitoring, Alerts and Load Testing<\/span><\/h2>\n<p>Capacity planning is not a one\u2011time task. Odoo and ERPNext usage patterns change as more departments adopt the system, new customizations are deployed, or reporting usage grows. You need continuous feedback from the server side.<\/p>\n<h3><span id=\"Key_Metrics_to_Watch\">Key Metrics to Watch<\/span><\/h3>\n<ul>\n<li><strong>CPU<\/strong>: sustained usage above 70\u201380% during business hours suggests you may need more vCPUs or worker tuning.<\/li>\n<li><strong>RAM<\/strong>: avoid constant use above 80\u201385%; leave breathing room for spikes.<\/li>\n<li><strong>Disk I\/O<\/strong>: high IOwait means your disk is saturated; NVMe or better IOPS limits help.<\/li>\n<li><strong>Database connections<\/strong>: track the number of active connections to PostgreSQL.<\/li>\n<\/ul>\n<p>Our monitoring guide with htop, iotop, Netdata and Prometheus (linked earlier) shows how to surface all of this in dashboards instead of guessing when users complain.<\/p>\n<h3><span id=\"Load_Testing_Before_Big_GoLives\">Load Testing Before Big Go\u2011Lives<\/span><\/h3>\n<p>If you are about to onboard a new department or migrate a lot of users at once, doing a small load test is worth it. Simulate realistic user flows (login, search, create order, validate invoice) and slowly ramp up concurrency. Watch CPU, RAM, PostgreSQL and worker queue lengths. Adjust worker counts and, if necessary, VPS size before the real go\u2011live instead of mid\u2011project.<\/p>\n<h2><span id=\"Security_and_Access_Basics_for_ERP_VPS_Setups\">Security and Access Basics for ERP VPS Setups<\/span><\/h2>\n<p>Performance is only half the story; these systems hold your core business data. At minimum:<\/p>\n<ul>\n<li>Restrict SSH and database access to trusted IPs or VPN users.<\/li>\n<li>Use strong TLS settings and keep certificates renewed automatically.<\/li>\n<li>Apply regular OS and application security updates.<\/li>\n<li>Take automatic, off\u2011site backups of databases and application files.<\/li>\n<\/ul>\n<p>We maintain a detailed checklist in our article on <a href=\"https:\/\/www.dchost.com\/blog\/en\/vps-guvenlik-sertlestirme-kontrol-listesi-sshd_config-fail2ban-ve-root-erisimini-kapatmak\/\">VPS security hardening with sshd_config, Fail2ban and disabling direct root SSH<\/a>, and for panel access we describe secure remote patterns (VPN, bastion hosts, zero\u2011trust) in our post on <a href=\"https:\/\/www.dchost.com\/blog\/en\/vpn-ve-bastion-host-ile-hosting-panellerine-guvenli-uzaktan-erisim-mimarisi\/\">secure remote access to hosting panels with VPN and bastion hosts<\/a>. The same principles apply to ERP servers.<\/p>\n<h2><span id=\"Summary_Turning_Your_Odoo_ERPNext_VPS_into_a_Reliable_Platform\">Summary: Turning Your Odoo \/ ERPNext VPS into a Reliable Platform<\/span><\/h2>\n<p>Running Odoo or ERPNext on a VPS is not just about installing the software; it\u2019s about turning that VPS into a predictable, well\u2011tuned platform. Start by picking realistic CPU and RAM for your current and near\u2011future user counts, then derive worker counts from those resources rather than from defaults alone. Keep an eye on how much memory each worker type consumes, and ensure PostgreSQL has enough headroom without starving the application.<\/p>\n<p>Put a reverse proxy like Nginx in front to handle HTTPS, timeouts and routing cleanly, and monitor CPU, RAM, disk and queue lengths so you can adjust before users feel pain. When you outgrow a single VPS, move to a split app\/database layout on larger VPS or dedicated servers \u2013 something we design frequently for dchost.com clients who scale from pilot projects to mission\u2011critical ERP deployments.<\/p>\n<p>If you\u2019re unsure where your current setup stands, our team can review your existing Odoo or ERPNext instance, look at real resource usage, and propose a concrete VPS, dedicated server or colocation plan on dchost.com with matching worker and reverse proxy settings. The goal is simple: you focus on running your business in your ERP, and we make sure the infrastructure quietly does its job in the background.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>When you move Odoo or ERPNext from a test install to a real production system, your VPS suddenly stops being \u201cjust a server\u201d and turns into the backbone of your finance, inventory, sales and HR data. At dchost.com we regularly see the same pattern: the first pilot runs fine, then usage grows, and the application [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":4984,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-4983","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-teknoloji"],"_links":{"self":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts\/4983","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/comments?post=4983"}],"version-history":[{"count":0,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts\/4983\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/media\/4984"}],"wp:attachment":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/media?parent=4983"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/categories?post=4983"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/tags?post=4983"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}