{"id":18649,"date":"2026-04-02T15:04:36","date_gmt":"2026-04-02T13:04:36","guid":{"rendered":"https:\/\/webhosting.de\/file-descriptor-limit-server-hosting-tuning-servergrenzen\/"},"modified":"2026-04-02T15:04:36","modified_gmt":"2026-04-02T13:04:36","slug":"limit-deskryptora-pliku-hosting-serwera-dostrajanie-limitow-serwera","status":"publish","type":"post","link":"https:\/\/webhosting.de\/pl\/file-descriptor-limit-server-hosting-tuning-servergrenzen\/","title":{"rendered":"Serwer limit\u00f3w deskryptor\u00f3w plik\u00f3w: Optymalizacja limit\u00f3w w hostingu"},"content":{"rendered":"<p>Ich zeige, wie das <strong>File Descriptor Limit<\/strong> auf dem Server Verbindungen, Dateien und Sockets begrenzt und so die Leistungsf\u00e4higkeit bestimmt. Mit klaren Schritten erh\u00f6he ich Limits, messe den Bedarf und verhindere EMFILE-Fehler, bevor Dienste unter Last ausfallen.<\/p>\n\n<h2>Zentrale Punkte<\/h2>\n\n<p>Damit du schnell handeln kannst, fasse ich die wichtigsten <strong>Hebel<\/strong> zum Optimieren der FD-Limits kompakt zusammen:<\/p>\n<ul>\n  <li><strong>Ursache<\/strong>: Jeder Socket, jede Datei, jede DB-Connection verbraucht FDs.<\/li>\n  <li><strong>Symptome<\/strong>: HTTP 500, EMFILE-Meldungen, blockierte I\/O, Dienstabst\u00fcrze.<\/li>\n  <li><strong>Messung<\/strong>: ulimit, \/proc\/limits, file-max und lsof geben Klarheit.<\/li>\n  <li><strong>Optimierung<\/strong>: Limits in limits.conf, systemd und sysctl gezielt anheben.<\/li>\n  <li><strong>Sicherheit<\/strong>: Hohe Limits mit Rate-Limiting und Monitoring flankieren.<\/li>\n<\/ul>\n\n<h2>Was sind File Descriptors und warum Limits z\u00e4hlen<\/h2>\n\n<p>Ein File Descriptor ist ein einfacher ganzzahliger <strong>Bezeichner<\/strong>, den der Kernel nutzt, um ge\u00f6ffnete Dateien, Sockets, Pipes oder Ger\u00e4te per Prozess zu referenzieren. Jeder Prozess h\u00e4lt ein Soft- und ein Hard-Limit, systemweit existiert zus\u00e4tzlich ein globales Maximum, das alle Prozesse zusammen begrenzt und so <strong>Knappheit<\/strong> verhindern soll. Standardm\u00e4\u00dfig stehen pro Prozess oft nur 1024 FDs bereit, was bei High-Traffic-Websites, API-Gateways oder Chat-Backends schnell eng wird und so <strong>Lastspitzen<\/strong> versch\u00e4rft. Erreicht ein Prozess sein Limit, schlagen neue Verbindungen fehl, Worker k\u00f6nnen keine Dateien mehr \u00f6ffnen, und Logs f\u00fcllen sich mit EMFILE, was die <strong>Antwortzeiten<\/strong> verl\u00e4ngert. Besonders kritisch wird es bei Setups, die pro Request mehrere Handles belegen: PHP-FPM, Cache-Backends, Logfiles und Reverse-Proxies akkumulieren FDs, bis die <strong>Grenzen<\/strong> blockieren.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/04\/serveroptimierung-raum-4571.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Symptome erkennen und messen<\/h2>\n\n<p>Erste Anzeichen eines zu engen Limits siehst du oft als <strong>HTTP-500<\/strong> ohne klare Ursache, z\u00e4he Responses oder sporadische Neustarts einzelner Dienste. Typische Logeintr\u00e4ge wie &#8222;Too many open files&#8220; deuten auf EMFILE hin und signalisieren unmittelbaren <strong>Handlungsbedarf<\/strong>. Ich pr\u00fcfe zuerst prozessbezogene Grenzen und den aktuellen Verbrauch, um zwischen lokalem Engpass und systemweitem Problem zu unterscheiden und so die <strong>Ursache<\/strong> zu pr\u00e4zisieren. F\u00fcr einen strukturierten Einstieg eignet sich dieser kompakte <a href=\"https:\/\/webhosting.de\/server-ulimits-hosting-grenzen-serverressourcen-ultimativ\/\">Server-Ulimits Guide<\/a>, wenn du die Stellschrauben kurz \u00fcberblicken willst und <strong>Schritte<\/strong> planst. Danach messe ich mit lsof, wie viele Deskriptoren ein Prozess wirklich h\u00e4lt, denn Messwerte schlagen Annahmen, sobald Lastprofile <strong>wechseln<\/strong>.<\/p>\n\n<pre><code># Soft- und Hard-Limit der aktuellen Shell\nulimit -n\nulimit -Hn\n\n# Limits eines Prozesses pr\u00fcfen\ncat \/proc\/&lt;pid&gt;\/limits | grep \"open files\"\n\n# Gesamtzustand des Systems\ncat \/proc\/sys\/fs\/file-nr   # ge\u00f6ffnet | frei | maximum\ncat \/proc\/sys\/fs\/file-max  # globales Maximum\n\n# Verbrauch pro Prozess grob sch\u00e4tzen\nlsof -p &lt;pid&gt; | wc -l\n<\/code><\/pre>\n\n<h2>Limits pr\u00fcfen und Kennzahlen interpretieren<\/h2>\n\n<p>Ich unterscheide strikt zwischen prozessbezogenen und globalen Grenzen, damit ich Engp\u00e4sse gezielt <strong>beseitige<\/strong> statt nur zu verschieben. Das Hard-Limit setzt die Oberkante f\u00fcr Erh\u00f6hungen in Sessions, w\u00e4hrend fs.file-max und fs.nr_open den globalen Rahmen festlegen und somit die <strong>Kapazit\u00e4t<\/strong> des Hosts beschreiben. Bew\u00e4hrt hat sich die Faustregel, pro Prozess mindestens 65535 FDs zuzulassen, sofern RAM und Workload dies tragen und du die <strong>Last<\/strong> kennst. Parallel achte ich darauf, dass die Summe aktiver Worker, Child-Prozesse und Netzwerkverbindungen in realistischen Hochlastszenarien innerhalb der globalen <strong>Rahmenwerte<\/strong> bleibt. Eine klare Sicht auf diese Zahlen verhindert blindes Erh\u00f6hen ohne Plan und h\u00e4lt die Systemintegrit\u00e4t unter <strong>Druck<\/strong>.<\/p>\n\n<table>\n  <thead>\n    <tr>\n      <th>Befehl\/Pfad<\/th>\n      <th>Funktion<\/th>\n      <th>Worauf achten<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td><code>ulimit -n \/ -Hn<\/code><\/td>\n      <td>Soft-\/Hard-Limit der aktuellen Session<\/td>\n      <td>Hard-Limit setzt Obergrenze f\u00fcr <strong>Anhebung<\/strong><\/td>\n    <\/tr>\n    <tr>\n      <td><code>\/proc\/&lt;pid&gt;\/limits<\/code><\/td>\n      <td>Per-Prozess-Grenzen und offene Dateien<\/td>\n      <td>Kritisch bei Daemons wie <strong>nginx<\/strong>\/php-fpm<\/td>\n    <\/tr>\n    <tr>\n      <td><code>\/proc\/sys\/fs\/file-max<\/code><\/td>\n      <td>Globales Maximum aller FDs<\/td>\n      <td>Muss zur Prozesssumme und <strong>RAM<\/strong> passen<\/td>\n    <\/tr>\n    <tr>\n      <td><code>\/proc\/sys\/fs\/file-nr<\/code><\/td>\n      <td>Ge\u00f6ffnet, frei, Maximum in Zahlen<\/td>\n      <td>Trend bei Lasttests und <strong>Peaks<\/strong> pr\u00fcfen<\/td>\n    <\/tr>\n    <tr>\n      <td><code>lsof<\/code><\/td>\n      <td>Zeigt offene Handles<\/td>\n      <td>Je Worker\/Thread <strong>verbrauchte<\/strong> FDs messen<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/04\/Dateideskriptor_Optimierung_5493.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>FD-Limits tempor\u00e4r und dauerhaft anpassen<\/h2>\n\n<p>F\u00fcr schnelle Tests setze ich per ulimit ein h\u00f6heres <strong>Soft-Limit<\/strong>, bevor ich dauerhafte Regeln hinterlege und Dienste neu starte. Danach schreibe ich die passenden Eintr\u00e4ge in \/etc\/security\/limits.conf, erg\u00e4nze systemd-Overrides und verifiziere die \u00c4nderung mit einem gezielten <strong>Lasttest<\/strong>. Wichtig: Der Dienst-User muss stimmen, sonst bleibt die Erh\u00f6hung wirkungslos und das <strong>Problem<\/strong> taucht unter Last wieder auf. Zus\u00e4tzlich passe ich das globale Limit an, damit viele Worker-Prozesse das Systemlimit nicht gemeinsam <strong>auflaufen<\/strong> lassen. Erst wenn Prozess- und Systemseite zusammenpassen, h\u00e4lt die Konfiguration echten Hochlastsszenarien stand und vermeidet <strong>EMFILE<\/strong>.<\/p>\n\n<pre><code># Tempor\u00e4r (bis zur Abmeldung\/Neustart)\nulimit -n 65535\n\n# Systemweit (bis zum Neustart oder dauerhaft per sysctl.conf)\nsudo sysctl -w fs.file-max=2097152\n\n# Dauerhaft (Beispiel f\u00fcr Webserver-User)\necho -e \"www-data soft nofile 65535\\nwww-data hard nofile 65535\\n* soft nofile 65535\\n* hard nofile 65535\" | sudo tee -a \/etc\/security\/limits.conf\n\n# systemd-Services (z. B. nginx)\nsudo mkdir -p \/etc\/systemd\/system\/nginx.service.d\ncat &lt;&lt;'EOF' | sudo tee \/etc\/systemd\/system\/nginx.service.d\/limits.conf\n[Service]\nLimitNOFILE=65536\nEOF\nsudo systemctl daemon-reload &amp;&amp; sudo systemctl restart nginx\n<\/code><\/pre>\n\n<h2>Kernel-Parameter richtig setzen<\/h2>\n\n<p>Ich validiere fs.file-max und fs.nr_open gemeinsam, damit der Kernel genug <strong>Puffer<\/strong> f\u00fcr Spitzenlast bereitstellt. Erh\u00f6ht man nur das per-Prozess-Limit, st\u00f6\u00dft man sonst am globalen Limit an und verlagert den <strong>Engpass<\/strong> auf Systemebene. Sinnvoll ist ein Abstand zwischen typischer Peak-Last und den globalen Werten, sodass Reserven f\u00fcr Wartungsfenster oder Burst-Traffic bestehen und <strong>Risikospitzen<\/strong> abged\u00e4mpft werden. Details zur systemweiten Abstimmung findest du im Artikel zu <a href=\"https:\/\/webhosting.de\/kernel-tuning-linux-sysctl-parameter-serverboost-opti\/\">Kernel-Tuning<\/a>, den ich bei tiefgreifenden OS-Anpassungen gern als <strong>Checkliste<\/strong> nutze. Nach \u00c4nderungen lade ich die Parameter neu, pr\u00fcfe erneut file-nr und verifiziere, dass alle Dienste mit den neuen Limits neu gestartet wurden und die <strong>Werte<\/strong> \u00fcbernehmen.<\/p>\n\n<pre><code># Dauerhafte Kernel-Parameter\nsudo bash -c 'cat &gt;&gt; \/etc\/sysctl.d\/99-ulimits.conf &lt;&lt;EOF\nfs.file-max = 2097152\nfs.nr_open  = 2097152\nEOF'\nsudo sysctl --system\n\n# Kontrolle\ncat \/proc\/sys\/fs\/file-max\ncat \/proc\/sys\/fs\/nr_open || sysctl fs.nr_open\n<\/code><\/pre>\n\n<h2>Kapazit\u00e4tsplanung und Architektur<\/h2>\n\n<p>Eine realistische Kapazit\u00e4tsplanung startet mit gemessenen <strong>Profilen<\/strong> pro Request: Wie viele FDs brauchen Webserver, App-Layer, Datenbank und Cache gemeinsam. Aus diesen Zahlen leite ich pro Host die Summe gleichzeitig ge\u00f6ffneter Handles ab und plane Puffer f\u00fcr <strong>Peaks<\/strong> ein. Rechne konservativ: Logrotation, zus\u00e4tzliche Sockets, tempor\u00e4re Dateien und Backup-Jobs erh\u00f6hen den Bedarf und fressen <strong>Reserven<\/strong>. Ich achte darauf, dass horizontale Skalierung mit Load-Balancern die FD-Last pro Knoten senkt, was Ausfalltoleranz und \u00c4nderungsfenster <strong>vereinfacht<\/strong>. Erst mit klaren Grenzwerten pro Tier kannst du Limits gezielt setzen und Kapazit\u00e4t sinnvoll zwischen Diensten <strong>aufteilen<\/strong>.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/04\/optimizing-file-descriptor-limits-4827.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Webserver- und Datenbank-Feinabstimmung<\/h2>\n\n<p>Bei Webservern halte ich mich an die Regel <strong>Threads*4<\/strong> kleiner als das FD-Limit, damit Reserven f\u00fcr Upstream-Verbindungen, tempor\u00e4re Dateien und Logs bestehen. F\u00fcr nginx und Apache beziehe ich Keep-Alive, offene Access- und Error-Logs sowie Upstream-Sockets in die Kalkulation ein und sichere mir so <strong>Puffer<\/strong>. Datenbanken wie MariaDB oder PostgreSQL \u00f6ffnen viele Sockets gegen Applikationen, Replikation und Monitoring; deren Limits m\u00fcssen zum Connection-Pool und zu Spitzen im Traffic <strong>passen<\/strong>. Caches (Redis, Memcached) senken DB-Last, reduzieren aber nicht zwangsl\u00e4ufig die FD-Zahl, sofern viele Clients parallel anfragen und Verbindungen <strong>halten<\/strong>. Ich plane deshalb koordinierte Limits entlang der Kette: Frontend, Upstream, DB, Cache und Message-Queues, damit nirgendwo die erste harte <strong>Schranke<\/strong> greift.<\/p>\n\n<pre><code># Beispiel: nginx systemd-Limit und Worker\nLimitNOFILE=65536   # systemd\nworker_processes auto;\nworker_connections 4096;  # 4096 * Worker &lt;= 65536\n\n# Beispiel: PostgreSQL\nmax_connections = 1000     # FD-Bedarf ~ 1-2 pro Connection + Dateien\/Logs\n<\/code><\/pre>\n\n<h2>WordPress und PHP-Stacks effizient halten<\/h2>\n\n<p>WordPress-Instanzen mit vielen Plugins \u00f6ffnen mehr Dateien, mehr Netzwerkverbindungen und mehr <strong>Logs<\/strong>. Ich senke die Zahl unn\u00f6tiger Includes per OPCache, entlaste Datenbanken mit Redis Object Cache und lagere statische Assets \u00fcber ein CDN aus, um Dateizugriffe und <strong>Verbindungen<\/strong> zu reduzieren. Gleichzeitig erh\u00f6he ich gezielt die Limits f\u00fcr php-fpm und den Webserver, damit Peaks bei Cronjobs, Crawlern oder Shop-Checkouts keine harten <strong>Abbr\u00fcche<\/strong> erzeugen. Ein sauberer Umgang mit Error-Logs und Rotationen verhindert, dass Logwriter ins Leere laufen und neue Dateien nicht \u00f6ffnen <strong>d\u00fcrfen<\/strong>. So kombiniere ich Verbrauchsreduktion und Limitanhebung, damit der Stack unter Last leistbar bleibt und <strong>Durchsatz<\/strong> h\u00e4lt.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/04\/file_descriptor_limit_3421.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Container und Cloud-Umgebungen<\/h2>\n\n<p>In Docker und Kubernetes erben Prozesse oft die FD-Limits des <strong>Nodes<\/strong>, weshalb ich zuerst die Host-Parameter und anschlie\u00dfend die Service-Definitionen pr\u00fcfe. F\u00fcr systemd-nspawn oder containerd gelten analoge Prinzipien, doch die Umsetzung erfolgt in Unit-Files, PodSpecs oder Daemon-Konfigurationen mit <strong>Overrides<\/strong>. Ich dokumentiere die Limits als Code (IaC) und halte sie \u00fcber Playbooks konsistent, damit neue Nodes identische <strong>Grenzen<\/strong> mitbringen. Bei Kubernetes pr\u00fcfe ich zus\u00e4tzlich SecurityContexts und setze erforderliche Capabilities, damit systemseitige <strong>Limits<\/strong> greifen. Wichtig bleibt am Ende die Messung im Cluster, denn Scheduling, Autoscaling und Rolling Updates ver\u00e4ndern die Verteilung offener Handles und testen deine <strong>Puffer<\/strong>.<\/p>\n\n<pre><code># Beispiel: systemd in Container-Hosts\ncat &lt;&lt;'EOF' | sudo tee \/etc\/systemd\/system\/myapp.service.d\/limits.conf\n[Service]\nLimitNOFILE=65536\nEOF\n\n# Kubernetes: podSpec (Container-Image muss ulimit respektieren)\n# Hinweis: rlimit-Settings sind je nach Runtime\/OS unterschiedlich zu setzen\n<\/code><\/pre>\n\n<h2>Sicherheit, Rate-Limiting und Monitoring<\/h2>\n\n<p>Hohe Limits geben Luft, doch sie vergr\u00f6\u00dfern die Angriffsfl\u00e4che bei <strong>Floods<\/strong>, daher begrenze ich Anfragen an der Edge mit Rate-Limiting und setze Connection Limits im Webserver. Eine Web Application Firewall und sinnvolle Timeouts verhindern, dass Idle-Verbindungen die FDs dauerhaft <strong>binden<\/strong>. F\u00fcr wiederkehrende Tests nutze ich reproduzierbare Lastprofile und beobachte mit Prometheus, Netdata oder Nagios konsistent die Metriken rund um offene Dateien und <strong>Sockets<\/strong>. Je nach Workload korrigiere ich Grenzwerte schrittweise, statt sie sprunghaft zu erh\u00f6hen, damit Auswirkungen messbar bleiben und <strong>R\u00fcckbau<\/strong> leicht f\u00e4llt. Wer tiefer in Grenzwerte auf Verbindungsseite einsteigen will, findet Orientierung \u00fcber diesen kompakten Beitrag zu <a href=\"https:\/\/webhosting.de\/connection-limits-webhosting-serverlast-optimierungshub\/\">Connection Limits<\/a>, der mir bei Netzwerkgrenzen als <strong>Leitfaden<\/strong> dient.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/04\/server_optimierung_fdlimits_9834.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Fehlersuche bei EMFILE: strukturierter Ablauf<\/h2>\n\n<p>Ich starte mit einem Blick ins <strong>Journal<\/strong> und in die Dienst-Logs, um Zeitpunkt und H\u00e4ufigkeit der Fehler sauber einzugrenzen. Danach pr\u00fcfe ich mit lsof den Top-Verbrauch pro Prozess und identifiziere Muster wie Leaks, wachsendes Logging oder ungew\u00f6hnliche <strong>Socket<\/strong>-Typen. Als N\u00e4chstes vergleiche ich gesetzte Limits mit realen Peaks und erh\u00f6he zuerst tempor\u00e4r, damit ich Ursache und Wirkung in einem kontrollierten Test validiere und daraus <strong>Dauereinstellungen<\/strong> ableite. Findet sich ein Leak, patche oder rolle ich die Komponente zur\u00fcck, denn h\u00f6here Limits kaschieren nur Symptome und verschieben das <strong>Problem<\/strong>. Zuletzt dokumentiere ich die Korrektur, setze Alarme und plane einen erneuten Lasttest, damit die L\u00f6sung Bestand zeigt und <strong>Vertrauen<\/strong> schafft.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/04\/optimierung-serverraum-5796.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Ressourcenkosten hoher FD-Limits realistisch bewerten<\/h2>\n\n<p>Jede offene Datei oder jeder Socket kostet Kernel-Speicher. Plane deshalb den <strong>RAM-Fu\u00dfabdruck<\/strong> mit ein: Pro FD fallen je nach Kernel-Version und Architektur grob einige hundert Bytes bis wenige Kilobyte an (inklusive VFS-\/Socket-Strukturen). Bei hunderttausenden FDs summiert sich das. Ich dimensioniere globales file-max so, dass im Worst Case noch ausreichender Pagecache und Arbeitsspeicher f\u00fcr Anwendungen frei bleibt. Ein einfacher Gegencheck erfolgt \u00fcber vmstat, free und den Trend offener FDs \u00fcber file-nr w\u00e4hrend eines <strong>Spitzenlasttests<\/strong>. Ziel ist eine Konfiguration, die bei Peak-Last weder in Swap kippt noch \u00fcberm\u00e4\u00dfige Reclaim- oder OOM-Aktivit\u00e4t triggert.<\/p>\n\n<h2>Distribution- und Startpfad-Fallen (PAM, systemd, Cron)<\/h2>\n\n<p>Ob Limits greifen, h\u00e4ngt vom <strong>Startpfad<\/strong> ab. PAM-basierte Logins (ssh, su, login) lesen \/etc\/security\/limits.conf, systemd-Services hingegen nutzen prim\u00e4r ihre Unit-Parameter (LimitNOFILE) und <em>nicht<\/em> zwingend PAM. Cron\/at k\u00f6nnen eigene Kontexte haben. Ich validiere daher pro Dienst:<\/p>\n<ul>\n  <li>Wie startet der Prozess? (systemctl status, ps -ef)<\/li>\n  <li>Welche Limits sieht er wirklich? (cat \/proc\/&lt;pid&gt;\/limits)<\/li>\n  <li>Greift PAM? (PAM-Module in \/etc\/pam.d\/* pr\u00fcfen)<\/li>\n  <li>Existieren systemweite Defaults? (systemd: DefaultLimitNOFILE in system.conf)<\/li>\n<\/ul>\n<p>So verhindere ich, dass Anwendungen je nach Startweg unterschiedliche FD-Limits erhalten und unter Last <strong>inkonsistent<\/strong> reagieren.<\/p>\n\n<h2>Praxisdimensionierung mit Rechenbeispielen<\/h2>\n\n<p>Ich rechne von den <strong>Workern<\/strong> und Verbindungsprofilen aus r\u00fcckw\u00e4rts zur n\u00f6tigen FD-Kapazit\u00e4t:<\/p>\n<ul>\n  <li>nginx mit 8 Workern \u00e0 4000 Verbindungen: ~32000 Verbindungen. Pro aktiver Verbindung reserviert nginx in der Regel 1 FD; plus Upstream (Keep-Alive) und Logs addieren ~10\u201320% Puffer. Ergebnis: ~38000 FDs allein f\u00fcr nginx.<\/li>\n  <li>php-fpm mit 150 Children, je Child typische 20\u201340 FDs (Includes, Sockets, Logs): konservativ 6000 FDs.<\/li>\n  <li>Redis\/DB-Clients: 200 parallele Verbindungen, je 1\u20132 FDs: ~400 FDs.<\/li>\n<\/ul>\n<p>Summiert pro Host: ~44k FDs. Ich setze <strong>LimitNOFILE<\/strong> f\u00fcr nginx auf 65536, php-fpm analog, und plane <em>global<\/em> fs.file-max so, dass alle Dienste plus Reserve (x1,5\u2013x2) hineinpassen. F\u00fcr mehrere stark ausgelastete Instanzen pro Host skaliere global auf 1\u20132 Millionen FDs, wenn RAM und I\/O-Pfade das <strong>hergeben<\/strong>.<\/p>\n\n<h2>Tiefere Diagnose: Leaks und Hotspots finden<\/h2>\n\n<p>Wenn FDs kontinuierlich steigen, suche ich mit zielgerichteten Werkzeugen nach der Ursache:<\/p>\n<pre><code># Offene Handles gruppiert nach Typ\nlsof -p &lt;pid&gt; | awk '{print $5}' | sort | uniq -c | sort -nr\n\n# Nur Sockets eines Prozesses\nlsof -Pan -p &lt;pid&gt; -i\n\n# Welche Dateien wachsen (Logs, Temp)\nlsof +L1            # gel\u00f6schte, aber noch ge\u00f6ffnete Dateien\nls -l \/proc\/&lt;pid&gt;\/fd\n\n# Syscall-Sicht: wer \u00f6ffnet dauernd?\nstrace -f -p &lt;pid&gt; -e trace=open,openat,close,socket,accept,accept4 -s 0\n<\/code><\/pre>\n<p>Besonders t\u00fcckisch sind <strong>gel\u00f6schte Logs<\/strong>, die weiter offen sind: Sie belegen Platz und FDs, tauchen aber im Filesystem nicht mehr auf. Neustart oder ein explizites Reopen (z. B. bei nginx via USR1) l\u00f6st das sauber. Auch falsch konfigurierte Watcher\/Exporter k\u00f6nnen stetig neue Sockets \u00f6ffnen \u2013 hier helfen Rate-Limits und <strong>Pooling<\/strong>.<\/p>\n\n<h2>Inotify, epoll und EMFILE sauber abgrenzen<\/h2>\n\n<p>Nicht jede Ressourcengrenze hei\u00dft FD-Limit. In Entwicklungs- und CI-Umgebungen schlagen Builds oft mit ENOSPC in Bezug auf Inotify fehl (Watcher-Grenzen). Ich pr\u00fcfe und setze erg\u00e4nzend:<\/p>\n<pre><code># Inotify-Grenzen (nutzerweit und Instanzen)\nsysctl fs.inotify.max_user_watches\nsysctl fs.inotify.max_user_instances\n\n# Beispielhafte Erh\u00f6hung\nsudo sysctl -w fs.inotify.max_user_watches=524288\nsudo sysctl -w fs.inotify.max_user_instances=1024\n<\/code><\/pre>\n<p>W\u00e4hrend epoll intern mit FDs arbeitet, ist die eigentliche Engstelle bei massiven <strong>Long-Lived<\/strong>-Verbindungen oft das FD-Limit selbst. Deshalb korreliere ich epoll-\/Event-Loop-Daten (z. B. aktive Handles) mit file-nr und prozessbezogenem Verbrauch.<\/p>\n\n<h2>Sprach- und Runtime-Besonderheiten (Java, Node.js, Go, Python)<\/h2>\n\n<p>Runtimes gehen unterschiedlich mit FDs um:<\/p>\n<ul>\n  <li><strong>Java\/Netty<\/strong>: Viele NIO-Channels pro Prozess, Logging-Frameworks halten File-Appender offen. Ich setze gro\u00dfz\u00fcgige Limits und rotiere Logs mit Reopen-Strategie statt Close\/Replace.<\/li>\n  <li><strong>Node.js<\/strong>: EMFILE tritt schnell bei File-System-Heavy Workloads auf (z. B. Watcher, Build-Pipelines). Ich reguliere parallele fs-Operationen, erh\u00f6he Limits und setze Backoff\/Retry-Strategien.<\/li>\n  <li><strong>Go<\/strong>: Hohe Parallelit\u00e4t durch Goroutines kann viele Sockets \u00f6ffnen. Ich begrenze Dial- und Response-Header-Timeouts und pr\u00fcfe, ob Verbindungen sauber geschlossen werden (IdleConnTimeout).<\/li>\n  <li><strong>Python\/uWSGI\/Gunicorn<\/strong>: Worker\/Thread-Modelle verbrauchen FDs f\u00fcr Logs, Sockets und tempor\u00e4re Dateien; ich harmonisiere Worker-Zahl, Thread-Pools und <strong>nofile<\/strong>-Limits.<\/li>\n<\/ul>\n<p>Gemeinsam ist allen: Ohne koordinierte Logrotation und verl\u00e4ssliches <strong>Connection-Management<\/strong> steigen FDs schleichend an.<\/p>\n\n<h2>Container konkret: Docker- und Kubernetes-Settings<\/h2>\n\n<p>Damit Container die gew\u00fcnschten Limits auch wirklich sehen, setze ich sie konsistent entlang der Kette:<\/p>\n<ul>\n  <li><strong>Docker-Run<\/strong>: mit &#8211;ulimit nofile=65535:65535 starten oder per Daemon-Vorgabe (z. B. Default-Ulimits) setzen.<\/li>\n  <li><strong>Images<\/strong>: Startskripte sollten kein restriktives ulimit zur\u00fccksetzen.<\/li>\n  <li><strong>Kubernetes<\/strong>: Je nach Runtime (containerd, cri-o) greifen rlimit-Einstellungen unterschiedlich. Ich teste im Pod via cat \/proc\/self\/limits und passe Node-\/Runtime-Defaults an, wenn Pod-Spezifika nicht ausreichen.<\/li>\n<\/ul>\n<p>Besonders in Multi-Tenant-Umgebungen sichere ich die <strong>Gesamtsumme<\/strong> gegen fs.file-max ab und isoliere Noisy-Neighbor-Effekte durch getrennte Nodesets oder PodBudgets, damit einzelne Deployments nicht die Host-reservierten FDs aufzehren.<\/p>\n\n<h2>Monitoring-Metriken und Alarme pr\u00e4zisieren<\/h2>\n\n<p>Ich beobachte neben file-nr und file-max auch per-Prozess-FDs und Trendlinien:<\/p>\n<ul>\n  <li><strong>Systemweit<\/strong>: Allocated vs. Maximum, Rate of Change, Verh\u00e4ltnis Peak\/Maximum.<\/li>\n  <li><strong>Pro Prozess<\/strong>: FDs je Worker\/Thread, Top-N Prozesse, Anomalien in der Nacht (Batch\/Jobs).<\/li>\n  <li><strong>Qualitativ<\/strong>: HTTP-Fehlerraten, Queue-L\u00e4ngen, Accept-\/Handshake-Fehler synchron zum FD-Trend.<\/li>\n<\/ul>\n<p>Alerts setze ich <em>mehrstufig<\/em>: Warnung bei 70\u201380%, Kritisch ab 90% des konfigurierten Limits, plus <strong>Leckage-Erkennung<\/strong> \u00fcber steigende 7\u2011Tage-Trends. So reagiere ich rechtzeitig, bevor harte Schranken greifen.<\/p>\n\n<h2>Runbook f\u00fcr den Notfall<\/h2>\n\n<p>Wenn EMFILE akut zuschl\u00e4gt, handle ich in klaren Schritten:<\/p>\n<ol>\n  <li>Top-Verbraucher identifizieren (lsof, \/proc\/&lt;pid&gt;\/fd, Journaleintr\u00e4ge).<\/li>\n  <li>Tempor\u00e4r Soft-Limit erh\u00f6hen (ulimit in Session oder LimitNOFILE-Override) und Dienst neu starten.<\/li>\n  <li>Falls Logs der Grund sind: Rotation stoppen, Reopen triggern, Log-Level reduzieren.<\/li>\n  <li>Burst-Traffic an der Edge <strong>drosseln<\/strong> (Rate-Limits\/Connection-Limits erh\u00f6hen oder versch\u00e4rfen \u2013 je nach Lage).<\/li>\n  <li>Root Cause fixen (Leak, zu aggressive Parallelit\u00e4t, fehlende Timeouts) und dauerhafte Limits <strong>nachziehen<\/strong>.<\/li>\n<\/ol>\n<p>Wichtig ist die Nachbereitung: Dokumentation, wiederholte Lasttests, und Alarme so sch\u00e4rfen, dass dieselbe Kette fr\u00fchzeitig erkannt wird.<\/p>\n\n<h2>Kurz zusammengefasst<\/h2>\n\n<p>Mit erh\u00f6hten FD-Limits, sauber gesetzten Kernel-Parametern und einer getesteten Architektur verschaffe ich Diensten <strong>Spielraum<\/strong> unter Hochlast. Ich messe zuerst, setze dann angemessene Grenzwerte, verifiziere mit Lasttests und sichere das Ergebnis mit Rate-Limiting, Monitoring und klaren <strong>Regeln<\/strong>.<\/p>","protected":false},"excerpt":{"rendered":"<p>Optymalizacja serwera z limitem deskryptor\u00f3w plik\u00f3w: Unikaj wyczerpania fd poprzez tuning hostingu dla stabilnych serwer\u00f3w internetowych i najwy\u017cszej wydajno\u015bci.<\/p>","protected":false},"author":1,"featured_media":18642,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_crdt_document":"","inline_featured_image":false,"footnotes":""},"categories":[676],"tags":[],"class_list":["post-18649","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-server_vm"],"acf":[],"_wp_attached_file":null,"_wp_attachment_metadata":null,"litespeed-optimize-size":null,"litespeed-optimize-set":null,"_elementor_source_image_hash":null,"_wp_attachment_image_alt":null,"stockpack_author_name":null,"stockpack_author_url":null,"stockpack_provider":null,"stockpack_image_url":null,"stockpack_license":null,"stockpack_license_url":null,"stockpack_modification":null,"color":null,"original_id":null,"original_url":null,"original_link":null,"unsplash_location":null,"unsplash_sponsor":null,"unsplash_exif":null,"unsplash_attachment_metadata":null,"_elementor_is_screenshot":null,"surfer_file_name":null,"surfer_file_original_url":null,"envato_tk_source_kit":null,"envato_tk_source_index":null,"envato_tk_manifest":null,"envato_tk_folder_name":null,"envato_tk_builder":null,"envato_elements_download_event":null,"_menu_item_type":null,"_menu_item_menu_item_parent":null,"_menu_item_object_id":null,"_menu_item_object":null,"_menu_item_target":null,"_menu_item_classes":null,"_menu_item_xfn":null,"_menu_item_url":null,"_trp_menu_languages":null,"rank_math_primary_category":null,"rank_math_title":null,"inline_featured_image":null,"_yoast_wpseo_primary_category":null,"rank_math_schema_blogposting":null,"rank_math_schema_videoobject":null,"_oembed_049c719bc4a9f89deaead66a7da9fddc":null,"_oembed_time_049c719bc4a9f89deaead66a7da9fddc":null,"_yoast_wpseo_focuskw":null,"_yoast_wpseo_linkdex":null,"_oembed_27e3473bf8bec795fbeb3a9d38489348":null,"_oembed_c3b0f6959478faf92a1f343d8f96b19e":null,"_trp_translated_slug_en_us":null,"_wp_desired_post_slug":null,"_yoast_wpseo_title":null,"tldname":null,"tldpreis":null,"tldrubrik":null,"tldpolicylink":null,"tldsize":null,"tldregistrierungsdauer":null,"tldtransfer":null,"tldwhoisprivacy":null,"tldregistrarchange":null,"tldregistrantchange":null,"tldwhoisupdate":null,"tldnameserverupdate":null,"tlddeletesofort":null,"tlddeleteexpire":null,"tldumlaute":null,"tldrestore":null,"tldsubcategory":null,"tldbildname":null,"tldbildurl":null,"tldclean":null,"tldcategory":null,"tldpolicy":null,"tldbesonderheiten":null,"tld_bedeutung":null,"_oembed_d167040d816d8f94c072940c8009f5f8":null,"_oembed_b0a0fa59ef14f8870da2c63f2027d064":null,"_oembed_4792fa4dfb2a8f09ab950a73b7f313ba":null,"_oembed_33ceb1fe54a8ab775d9410abf699878d":null,"_oembed_fd7014d14d919b45ec004937c0db9335":null,"_oembed_21a029d076783ec3e8042698c351bd7e":null,"_oembed_be5ea8a0c7b18e658f08cc571a909452":null,"_oembed_a9ca7a298b19f9b48ec5914e010294d2":null,"_oembed_f8db6b27d08a2bb1f920e7647808899a":null,"_oembed_168ebde5096e77d8a89326519af9e022":null,"_oembed_cdb76f1b345b42743edfe25481b6f98f":null,"_oembed_87b0613611ae54e86e8864265404b0a1":null,"_oembed_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_oembed_time_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_tldname":null,"_tldclean":null,"_tldpreis":null,"_tldcategory":null,"_tldsubcategory":null,"_tldpolicy":null,"_tldpolicylink":null,"_tldsize":null,"_tldregistrierungsdauer":null,"_tldtransfer":null,"_tldwhoisprivacy":null,"_tldregistrarchange":null,"_tldregistrantchange":null,"_tldwhoisupdate":null,"_tldnameserverupdate":null,"_tlddeletesofort":null,"_tlddeleteexpire":null,"_tldumlaute":null,"_tldrestore":null,"_tldbildname":null,"_tldbildurl":null,"_tld_bedeutung":null,"_tldbesonderheiten":null,"_oembed_ad96e4112edb9f8ffa35731d4098bc6b":null,"_oembed_8357e2b8a2575c74ed5978f262a10126":null,"_oembed_3d5fea5103dd0d22ec5d6a33eff7f863":null,"_eael_widget_elements":null,"_oembed_0d8a206f09633e3d62b95a15a4dd0487":null,"_oembed_time_0d8a206f09633e3d62b95a15a4dd0487":null,"_aioseo_description":null,"_eb_attr":null,"_eb_data_table":null,"_oembed_819a879e7da16dd629cfd15a97334c8a":null,"_oembed_time_819a879e7da16dd629cfd15a97334c8a":null,"_acf_changed":null,"_wpcode_auto_insert":null,"_edit_last":null,"_edit_lock":null,"_oembed_e7b913c6c84084ed9702cb4feb012ddd":null,"_oembed_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_time_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_03514b67990db061d7c4672de26dc514":null,"_oembed_time_03514b67990db061d7c4672de26dc514":null,"rank_math_news_sitemap_robots":null,"rank_math_robots":null,"_eael_post_view_count":"440","_trp_automatically_translated_slug_ru_ru":null,"_trp_automatically_translated_slug_et":null,"_trp_automatically_translated_slug_lv":null,"_trp_automatically_translated_slug_fr_fr":null,"_trp_automatically_translated_slug_en_us":null,"_wp_old_slug":null,"_trp_automatically_translated_slug_da_dk":null,"_trp_automatically_translated_slug_pl_pl":null,"_trp_automatically_translated_slug_es_es":null,"_trp_automatically_translated_slug_hu_hu":null,"_trp_automatically_translated_slug_fi":null,"_trp_automatically_translated_slug_ja":null,"_trp_automatically_translated_slug_lt_lt":null,"_elementor_edit_mode":null,"_elementor_template_type":null,"_elementor_version":null,"_elementor_pro_version":null,"_wp_page_template":null,"_elementor_page_settings":null,"_elementor_data":null,"_elementor_css":null,"_elementor_conditions":null,"_happyaddons_elements_cache":null,"_oembed_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_time_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_time_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_59808117857ddf57e478a31d79f76e4d":null,"_oembed_time_59808117857ddf57e478a31d79f76e4d":null,"_oembed_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_time_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_81002f7ee3604f645db4ebcfd1912acf":null,"_oembed_time_81002f7ee3604f645db4ebcfd1912acf":null,"_elementor_screenshot":null,"_oembed_7ea3429961cf98fa85da9747683af827":null,"_oembed_time_7ea3429961cf98fa85da9747683af827":null,"_elementor_controls_usage":null,"_elementor_page_assets":[],"_elementor_screenshot_failed":null,"theplus_transient_widgets":null,"_eael_custom_js":null,"_wp_old_date":null,"_trp_automatically_translated_slug_it_it":null,"_trp_automatically_translated_slug_pt_pt":null,"_trp_automatically_translated_slug_zh_cn":null,"_trp_automatically_translated_slug_nl_nl":null,"_trp_automatically_translated_slug_pt_br":null,"_trp_automatically_translated_slug_sv_se":null,"rank_math_analytic_object_id":null,"rank_math_internal_links_processed":"1","_trp_automatically_translated_slug_ro_ro":null,"_trp_automatically_translated_slug_sk_sk":null,"_trp_automatically_translated_slug_bg_bg":null,"_trp_automatically_translated_slug_sl_si":null,"litespeed_vpi_list":null,"litespeed_vpi_list_mobile":null,"rank_math_seo_score":null,"rank_math_contentai_score":null,"ilj_limitincominglinks":null,"ilj_maxincominglinks":null,"ilj_limitoutgoinglinks":null,"ilj_maxoutgoinglinks":null,"ilj_limitlinksperparagraph":null,"ilj_linksperparagraph":null,"ilj_blacklistdefinition":null,"ilj_linkdefinition":null,"_eb_reusable_block_ids":null,"rank_math_focus_keyword":"File Descriptor Limit","rank_math_og_content_image":null,"_yoast_wpseo_metadesc":null,"_yoast_wpseo_content_score":null,"_yoast_wpseo_focuskeywords":null,"_yoast_wpseo_keywordsynonyms":null,"_yoast_wpseo_estimated-reading-time-minutes":null,"rank_math_description":null,"surfer_last_post_update":null,"surfer_last_post_update_direction":null,"surfer_keywords":null,"surfer_location":null,"surfer_draft_id":null,"surfer_permalink_hash":null,"surfer_scrape_ready":null,"_thumbnail_id":"18642","footnotes":null,"_links":{"self":[{"href":"https:\/\/webhosting.de\/pl\/wp-json\/wp\/v2\/posts\/18649","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/webhosting.de\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/webhosting.de\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/webhosting.de\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/webhosting.de\/pl\/wp-json\/wp\/v2\/comments?post=18649"}],"version-history":[{"count":0,"href":"https:\/\/webhosting.de\/pl\/wp-json\/wp\/v2\/posts\/18649\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/webhosting.de\/pl\/wp-json\/wp\/v2\/media\/18642"}],"wp:attachment":[{"href":"https:\/\/webhosting.de\/pl\/wp-json\/wp\/v2\/media?parent=18649"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/webhosting.de\/pl\/wp-json\/wp\/v2\/categories?post=18649"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/webhosting.de\/pl\/wp-json\/wp\/v2\/tags?post=18649"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}