{"id":1196,"date":"2026-09-21T22:39:59","date_gmt":"2026-09-21T22:39:59","guid":{"rendered":"https:\/\/virtualserversvps.com\/blog\/?p=1196"},"modified":"2026-09-21T22:39:59","modified_gmt":"2026-09-21T22:39:59","slug":"file-descriptor-ulimits-vps-high-connection-counts","status":"publish","type":"post","link":"https:\/\/virtualserversvps.com\/blog\/file-descriptor-ulimits-vps-high-connection-counts\/","title":{"rendered":"Raising File Descriptor and Process Limits on a VPS for High Connection Counts"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Most services on a VPS have a hard ceiling that has nothing to do with CPU, RAM, or bandwidth: the number of open file descriptors and processes they are permitted. A socket is a file descriptor, so every connection your web server holds is a descriptor. When the limit is reached, the failure is abrupt and the error messages are misleading \u2014 <code>accept4() failed (24: Too many open files)<\/code> in Nginx, or an application that simply stops responding. Here is how the limits stack and how to raise them once, correctly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Four layers, all of which must agree<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is the reason limit changes so often appear not to work. There is no single place to set this. A process receives the <em>lowest<\/em> of five values, and any one of them left at its default silently caps everything.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Layer<\/th><th>Where<\/th><th>Default<\/th><th>Notes<\/th><\/tr><\/thead><tbody><tr><td>Kernel global<\/td><td><code>fs.file-max<\/code><\/td><td>~1M<\/td><td>Rarely the limit on modern kernels<\/td><\/tr><tr><td>systemd manager<\/td><td><code>DefaultLimitNOFILE<\/code><\/td><td>1024<\/td><td>Caps every service systemd starts<\/td><\/tr><tr><td>systemd unit<\/td><td><code>LimitNOFILE=<\/code><\/td><td>inherits above<\/td><td>Per-service override<\/td><\/tr><tr><td>PAM \/ login<\/td><td><code>pam_limits.so<\/code> via <code>\/etc\/security\/limits.conf<\/code><\/td><td>1024<\/td><td>Only affects interactive shells, not services<\/td><\/tr><tr><td>Process<\/td><td><code>ulimit -n<\/code><\/td><td>inherited<\/td><td>What the app actually sees<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The classic mistake is editing <code>\/etc\/security\/limits.conf<\/code>, testing by logging in over SSH where it works, and wondering why Nginx still runs out. SSH sessions go through PAM; systemd services do not. <a href=\"https:\/\/virtualserversvps.com\/\">Our VPS comparison page<\/a> is useful for picking a plan with enough memory to hold all those connections, but the limits themselves are yours to set.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Reading what a running process is actually allowed<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Never guess. Ask the kernel what the process has, and ask systemd what it was told to grant.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># What the process actually has (works for any PID)\nPID=$(pgrep -o nginx)\ncat \/proc\/$PID\/limits | grep -Ei 'open files|processes'\n\n# What systemd thinks it granted\nsystemctl show nginx -p LimitNOFILE --value\n\n# The interactive-shell view (different number, usually)\nulimit -n; ulimit -u\n\n# Kernel-wide ceiling and current usage\nsysctl fs.file-max\ncat \/proc\/sys\/fs\/file-nr      # allocated  unused  max<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If <code>\/proc\/$PID\/limits<\/code> shows 1024 and <code>systemctl show<\/code> also shows 1024, you know exactly which layer to fix. If systemd shows 65535 but the process shows 1024, the unit file or a drop-in is overriding it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A configuration that covers every layer<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code># 1. Kernel global\ncat &gt;\/etc\/sysctl.d\/99-file-max.conf &lt;\/etc\/security\/limits.d\/99-web.conf &lt;&lt;&#039;EOF&#039;\n*       soft    nofile  65535\n*       hard    nofile  65535\n*       soft    nproc   32768\n*       hard    nproc   32768\nroot    soft    nofile  65535\nroot    hard    nofile  65535\nEOF\n\nsysctl --system\nsystemctl daemon-reexec      # required for manager-level limits<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>systemctl daemon-reexec<\/code> is not optional \u2014 a plain <code>daemon-reload<\/code> does not re-apply the manager&#8217;s own limits to services started afterward on older systemd versions. And on distributions that include a <code>limits.d\/20-nproc.conf<\/code> file, a later-sorted file wins, so name yours <code>99-<\/code> to be sure. A common trap on CentOS-family images is <code>root<\/code> being excluded from the <code>*<\/code> wildcard, hence the explicit root lines.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Per-service overrides<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For a service, use a drop-in rather than editing the package&#8217;s unit file, which will be overwritten on upgrade.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir -p \/etc\/systemd\/system\/nginx.service.d\ncat &gt;\/etc\/systemd\/system\/nginx.service.d\/limits.conf &lt;&lt;&#039;EOF&#039;\n[Service]\nLimitNOFILE=65535\nLimitNPROC=32768\nTasksMax=infinity\nEOF\n\nsystemctl daemon-reload &amp;&amp; systemctl restart nginx\ncat \/proc\/$(pgrep -o nginx)\/limits | grep &#039;open files&#039;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>TasksMax<\/code> is easy to miss because it is a cgroup concept rather than a classic ulimit. With the systemd default of 15% of <code>kernel.pid_max<\/code>, a worker-spawning service hits <code>Failed to fork: Resource temporarily unavailable<\/code> long before <code>nproc<\/code> matters.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There is one more interaction worth knowing: <code>fs.nr_open<\/code> caps what any single process may request, and it is the ceiling that <code>LimitNOFILE<\/code> cannot exceed. If you set <code>DefaultLimitNOFILE=1048576<\/code> while <code>fs.nr_open<\/code> remains at its lower default, systemd will accept the configuration and the service will still start with the smaller number. Check <code>sysctl fs.nr_open<\/code> before choosing a target, and raise both together rather than chasing the discrepancy later.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Choosing a number<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Web server: 2 file descriptors per proxied connection (client plus upstream), so 10,000 concurrent requests needs <code>LimitNOFILE=32768<\/code>.<\/li>\n<li>Database: each open table, each connection, and each temporary file consumes descriptors. MySQL&#8217;s <code>open_files_limit<\/code> and <code>table_open_cache<\/code> interact with the system limit.<\/li>\n<li>Do not set <code>fs.file-max<\/code> wildly high and leave process limits low \u2014 the kernel-wide number is a safety net, not a per-process budget.<\/li>\n<li>Memory matters: each socket also consumes kernel memory. Raising limits on a 512 MB instance does not create capacity that is not there.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Verifying under load<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code># Live descriptor usage for the web server\nls \/proc\/$(pgrep -o nginx)\/fd | wc -l\n\n# Which limit was hit, if any\ngrep -E 'Too many open files|Resource temporarily unavailable|accept4' \\\n     \/var\/log\/nginx\/error.log \/var\/log\/syslog\n\n# System-wide allocation trend during a load test\nwatch -n1 'cat \/proc\/sys\/fs\/file-nr'<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Run the load test again after the change. Descriptor count should rise to roughly your expected concurrency, error-log entries drop to zero, and <code>file-nr<\/code>&#8216;s first column should stabilise rather than climb indefinitely. A count that climbs without plateauing under steady load is a descriptor leak in the application, which raising limits will only postpone.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When the counters are clean and connections still fail, the constraint has moved to memory or network throughput. <a href=\"https:\/\/virtualserversvps.com\/\">See the full specs and pricing<\/a> to match the plan to the concurrency you have now measured, rather than repeatedly raising limits on an instance that cannot physically sustain them.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Most services on a VPS have a hard ceiling that has nothing to do with CPU, RAM, or bandwidth: the number of open file descriptors and processes they are permitted&#8230;.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":0,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1196","post","type-post","status-publish","format-standard","hentry","category-vps-guides-tutorials"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Raising File Descriptor and Process Limits on a VPS for High Connection Counts - Virtual Servers VPS Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/virtualserversvps.com\/blog\/file-descriptor-ulimits-vps-high-connection-counts\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Raising File Descriptor and Process Limits on a VPS for High Connection Counts\" \/>\n<meta property=\"og:description\" content=\"Raising File Descriptor and Process Limits on a VPS for High Connection Counts\" \/>\n<meta property=\"og:url\" content=\"https:\/\/virtualserversvps.com\/blog\/file-descriptor-ulimits-vps-high-connection-counts\/\" \/>\n<meta property=\"og:site_name\" content=\"Virtual Servers VPS Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-09-21T22:39:59+00:00\" \/>\n<meta name=\"author\" content=\"Virtual-Servers-Vps-Editor\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Virtual-Servers-Vps-Editor\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/file-descriptor-ulimits-vps-high-connection-counts\/\",\"url\":\"https:\/\/virtualserversvps.com\/blog\/file-descriptor-ulimits-vps-high-connection-counts\/\",\"name\":\"Raising File Descriptor and Process Limits on a VPS for High Connection Counts - Virtual Servers VPS Blog\",\"isPartOf\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#website\"},\"datePublished\":\"2026-09-21T22:39:59+00:00\",\"author\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0\"},\"breadcrumb\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/file-descriptor-ulimits-vps-high-connection-counts\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/virtualserversvps.com\/blog\/file-descriptor-ulimits-vps-high-connection-counts\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/file-descriptor-ulimits-vps-high-connection-counts\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/virtualserversvps.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Raising File Descriptor and Process Limits on a VPS for High Connection Counts\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#website\",\"url\":\"https:\/\/virtualserversvps.com\/blog\/\",\"name\":\"Virtual Servers VPS Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/virtualserversvps.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0\",\"name\":\"Virtual-Servers-Vps-Editor\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g\",\"caption\":\"Virtual-Servers-Vps-Editor\"},\"sameAs\":[\"https:\/\/virtualserversvps.com\/blog\"],\"url\":\"https:\/\/virtualserversvps.com\/blog\/author\/virtualserversvps\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Raising File Descriptor and Process Limits on a VPS for High Connection Counts - Virtual Servers VPS Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/virtualserversvps.com\/blog\/file-descriptor-ulimits-vps-high-connection-counts\/","og_locale":"en_US","og_type":"article","og_title":"Raising File Descriptor and Process Limits on a VPS for High Connection Counts","og_description":"Raising File Descriptor and Process Limits on a VPS for High Connection Counts","og_url":"https:\/\/virtualserversvps.com\/blog\/file-descriptor-ulimits-vps-high-connection-counts\/","og_site_name":"Virtual Servers VPS Blog","article_published_time":"2026-09-21T22:39:59+00:00","author":"Virtual-Servers-Vps-Editor","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Virtual-Servers-Vps-Editor","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/virtualserversvps.com\/blog\/file-descriptor-ulimits-vps-high-connection-counts\/","url":"https:\/\/virtualserversvps.com\/blog\/file-descriptor-ulimits-vps-high-connection-counts\/","name":"Raising File Descriptor and Process Limits on a VPS for High Connection Counts - Virtual Servers VPS Blog","isPartOf":{"@id":"https:\/\/virtualserversvps.com\/blog\/#website"},"datePublished":"2026-09-21T22:39:59+00:00","author":{"@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0"},"breadcrumb":{"@id":"https:\/\/virtualserversvps.com\/blog\/file-descriptor-ulimits-vps-high-connection-counts\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/virtualserversvps.com\/blog\/file-descriptor-ulimits-vps-high-connection-counts\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/virtualserversvps.com\/blog\/file-descriptor-ulimits-vps-high-connection-counts\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/virtualserversvps.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Raising File Descriptor and Process Limits on a VPS for High Connection Counts"}]},{"@type":"WebSite","@id":"https:\/\/virtualserversvps.com\/blog\/#website","url":"https:\/\/virtualserversvps.com\/blog\/","name":"Virtual Servers VPS Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/virtualserversvps.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0","name":"Virtual-Servers-Vps-Editor","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g","caption":"Virtual-Servers-Vps-Editor"},"sameAs":["https:\/\/virtualserversvps.com\/blog"],"url":"https:\/\/virtualserversvps.com\/blog\/author\/virtualserversvps\/"}]}},"_links":{"self":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1196","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/comments?post=1196"}],"version-history":[{"count":1,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1196\/revisions"}],"predecessor-version":[{"id":1198,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1196\/revisions\/1198"}],"wp:attachment":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/media?parent=1196"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/categories?post=1196"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/tags?post=1196"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}