De Keep Alive-webserver is vaak bepalend voor de wachttijd of snelheid: bij een verkeerde instelling remt hij stil af, bij een juiste afstemming versnelt hij elke aanvraag merkbaar. Ik laat concreet zien hoe ik Keep-Alive configureer welke tijdvensters werken en waarom te lang open TCP-Verbindingen Prestaties kosten.
Centrale punten
- mechanisme: Open TCP-verbindingen besparen handshakes en verminderen latentie.
- kernwaarden: KeepAliveTimeout, MaxKeepAliveRequests en activering doelgericht selecteren.
- Serverbelasting: Correct afgestelde tijdvensters verlagen het CPU- en RAM-verbruik.
- Praktijk: Houd consequent rekening met browsergedrag en reverse proxy-ketens.
- Controle: Meten, aanpassen, opnieuw meten – totdat de sweet spot is gevonden.
Wat Keep Alive doet
In plaats van elke aanvraag met een nieuwe handshake te starten, houdt Keep-Alive de TCP-verbinding open en verwerkt meerdere verzoeken via deze verbinding. In een scenario met 50 verzoeken per seconde van drie clients daalt het aantal pakketten drastisch: van naar schatting 9.000 naar ongeveer 540 pakketten per minuut, omdat er minder verbindingen worden gemaakt en er minder handshakes plaatsvinden. Dit vermindert de wachttijden en bespaart servercycli, wat directe gevolgen heeft voor Laadtijd en doorvoersnelheid heeft. In tests wordt de tijd gehalveerd van ongeveer 1.190 ms tot ongeveer 588 ms, dus met ruim 50 procent, mits de rest van de keten niet beperkt is. Daarom veranker ik Keep-Alive altijd vroeg in de configuratie en controleer ik de werkelijke latenties in het liveverkeer.
De juiste kengetallen
Ik begin met de drie instellingen die altijd van invloed zijn: activering, aantal verzoeken per verbinding en tijdsvenster tot het sluiten van de Aansluiting. De activering bepaalt of hergebruik überhaupt plaatsvindt; het maximale aantal verzoeken bepaalt hoe lang een verbinding zinvol open blijft; de time-out zorgt voor een evenwicht tussen zuinigheid en reactiesnelheid. Een te groot tijdvenster blokkeert slots en verspilt RAM, omdat inactieve sockets blijven liggen en er werknemers ontbreken. Een te kort venster doet afbreuk aan de voordelen, omdat de server te vroeg verbreekt en opnieuw moet opstarten. Ik houd me aan slanke standaardinstellingen en verhoog deze alleen als metingen echte wachttijden in de ruststand bevestigen.
HTTP/1.1 versus HTTP/2/3: classificatie
Keep-Alive werkt per TCP-verbinding. Bij HTTP/1.1 delen meerdere verzoeken achtereenvolgens één verbinding, bij HTTP/2 worden meerdere Streams via één enkele verbinding gemultiplexed, HTTP/3 gebruikt QUIC in plaats van TCP. Ik zie dat als volgt: een korte time-out blijft ook bij HTTP/2 zinvol, want idle streams zijn niet gratis – de verbinding blijft resources in beslag nemen, vooral bij TLS. Nginx heeft een eigen idle-venster voor HTTP/2; ik zorg ervoor dat de globale Keep-Alive-waarden en HTTP/2-specifieke grenswaarden bij elkaar passen en niet willekeurig hoog zijn. Belangrijk: Nginx communiceert momenteel alleen met de client HTTP/2; met de backend houdt het HTTP/1.1-verbindingen open. Upstream-Keepalive blijft daarom verplicht, zodat het voordeel van end-to-end behouden blijft. Voor HTTP/3 gelden vergelijkbare principes: ook al verbergt QUIC verliezen beter, een lang open, ongebruikt kanaal kost geheugen en bestandsdescriptoren. Mijn aanpak blijft daarom conservatief: korte idle-vensters, duidelijke limieten en liever een nette herverbinding dan eindeloos vasthouden.
TLS-overhead vanuit pragmatisch oogpunt bekeken
TLS vergroot de besparing door Keep-Alive nog verder, omdat handshakes duurder zijn dan pure TCP-opbouw. Met TLS 1.3 en Session-Resumption neemt de belasting weliswaar af, maar al met al levert elke vermeden nieuwe verbinding winst op. Ik controleer in de praktijk drie punten: ten eerste of de server Session Resumption correct gebruikt (tickets niet te vroeg laten verlopen). Ten tweede of sterke cijfers en moderne protocollen actief zijn, zonder oude clients onnodig te dwingen. Ten derde of het CPU-gebruik stabiel blijft bij hoge parallelliteit. Zelfs met hervatting voorkomen korte, stabiele keep-alive-tijdvensters extra CPU-pieken, omdat er minder onderhandelingen starten. Tegelijkertijd voorkom ik met te lange vensters geen handshakes, maar verplaats ik de belasting naar inactiviteit – dat is de duurdere variant.
Apache: aanbevolen instellingen
Bij Apache schakel ik KeepAlive in. Op, stel MaxKeepAliveRequests in op 300–500 en kies meestal voor een tijdvenster van 2–3 seconden. De waarde 0 voor het maximale aantal verzoeken klinkt aantrekkelijk, maar onbeperkt is zelden zinvol, omdat verbindingen anders te lang duren. lijmen. Voor veelgebruikte toepassingen met stabiele clients test ik 5-10 seconden; bij pieken met veel korte bezoeken ga ik naar 1-2 seconden. Belangrijk blijft: eerst de time-out aanpassen, dan het aantal verzoeken fijner instellen, zodat slots niet door inactiviteit worden geblokkeerd. Wie geen toegang heeft tot de hoofdconfiguratie, kan via mod_headers het verbindingsgedrag per directory regelen, mits de hoster deze optie heeft vrijgegeven.
Nginx: zinvolle afstemming
Onder Nginx is Keep-Alive standaard actief, daarom let ik vooral op time-out, browseruitzonderingen en het aantal per verbinding. Met keepalive_timeout stel ik het aantal open seconden in, dat ik afhankelijk van het verkeerspatroon stapsgewijs aanpas van 1 tot 5 seconden; bij veel API-oproepen kan ook 10 seconden zinvol zijn. Met keepalive_disable sluit ik problematische oude clients uit, zodat ze geen scheve Sessies genereren. Bij reverse proxies naar upstreams stel ik bovendien upstream keepalive in, zodat Nginx verbindingen met de backend hergebruikt en daar minder workers bindt. Zo houd ik het pad van begin tot eind consistent en voorkom ik ongewenste scheidingen midden in de request-flow.
Reverse proxy en header-doorsturing
In meerfasige opstellingen heb ik een doorlopende Strategie, die HTTP/1.1-headers correct doorgeeft en connection-waarden niet per ongeluk overschrijft. Nginx moet richting backend HTTP/1.1 spreken en Keep-Alive expliciet tolereren, terwijl Apache daarachter passende tijdvensters gebruikt. Configuraties die Connection: close afdwingen of upgrade-paden verstoren, zijn kritiek, omdat dan het vermeende voordeel teniet wordt gedaan. Onder Apache kan ik via mod_headers per locatie bepalen of verbindingen open blijven en welke aanvullende gegevens worden ingesteld. Alle knooppunten moeten hetzelfde doel nastreven, anders veroorzaakt een schakel de remwerking, die ik eigenlijk wilde vermijden.
CDN, load balancer en cloudconfiguraties
Als er een CDN of een load balancer voor staat, komen de meeste clientverbindingen daar terecht. De bron profiteert dan vooral van permanente, weinig verbindingen tussen edge en origin. Ik zorg ervoor dat de balancer ook met korte idle-vensters werkt en dat connection pooling naar de backend is geactiveerd. In container- en cloudomgevingen is ook de drain-flow van belang: vóór een rolling update stuur ik de knooppunten naar de Draineren-status, laat open verbindingen snel aflopen (time-out niet te hoog) en start dan pas de vervanging. Zo voorkom ik afgebroken verzoeken en achtergebleven zombieverbindingen. Sticky sessions (bijv. via cookies) kunnen verbindingspools opsplitsen; waar mogelijk zet ik in op statusarme Backends of externe sessieopslagplaatsen, zodat hergebruik gelijkmatig plaatsvindt.
Hostingsnelheid in de praktijk
Veel gedeelde omgevingen schakelen Keep-Alive uit om op korte termijn Slots om te besparen, maar de pagina's worden traag en verliezen hun interactieve karakter. Daarom controleer ik vroeg met laadtijdtests of de server hergebruik toestaat en hoe de verbindingsfasen er in het watervaldiagram uitzien. Als de tool lange handshake-blokken tussen veel kleine assets detecteert, ontbreekt meestal het hergebruik of wordt de time-out te vroeg verbroken. Voor verdere fijnafstemming helpt een gestructureerde handleiding zoals deze compacte Keep-Alive-tuning, zodat ik de stappen netjes kan afwerken. Zo vermijd ik giswerk en bereik ik met een paar handelingen een merkbaar resultaat. schwung aan de voorkant.
Time-outs, limieten en browsergedrag
Moderne browsers openen meerdere parallelle Verbindingen, vaak zes, en putten daarmee snel de Keep-Alive-capaciteit uit. Een MaxKeepAliveRequests van 300 is in de praktijk voldoende voor veel gelijktijdige bezoekers, mits de time-out niet onnodig hoog is. Als ik het venster op drie seconden instel, blijven er slots beschikbaar en geeft de server voorrang aan actieve clients in plaats van inactieve. Pas als verzoeken regelmatig afbreken of hergebruik niet werkt, verhoog ik de limiet in gematigde stappen. Voor pagina's met veel HTTP/2-stromen geldt een aparte overweging, details worden samengevat HTTP/2-multiplexing zeer compact, zodat ik kanaalgebruik en keep-alive netjes kan ordenen.
| Parameters | Apache-richtlijn | Nginx-richtlijn | richtwaarde | Tip |
|---|---|---|---|---|
| Activering | KeepAlive Aan | standaard actief | altijd activeren | Zonder hergebruik stijgt Overhead. |
| Time-out | KeepAliveTimeout | keepalive_timeout | 2–5 s | Korter bij veel korte oproepen, langer bij API's. |
| Aantal/Conn | MaxKeepAliveRequests | keepalive_requests | 300–500 | Beperkt het gebruik van hulpbronnen per Klant. |
| Browseruitzonderingen | - | keepalive_disable | selectief | Uitschakelen voor zeer oude Klanten. |
| Upstream | ProxyKeepAlive | upstream keepalive | actief | Zorgt voor hergebruik richting Backend. |
Beperkingen van het besturingssysteem en sockets
Op OS-niveau beperken bestandsdescriptoren en socketparameters de werkelijke capaciteit. Ik controleer ulimit -n, proces- en systeemlimieten en de configuratie van de webserver (bijv. worker_connections bij Nginx). Keep-Alive vermindert weliswaar het aantal nieuwe verbindingen, maar verlengt de tijd dat descriptoren bezet blijven. In drukke periodes kan TIME_WAIT-druk ontstaan wanneer verbindingen zeer snel worden verbroken – hier helpt vooral schoon hergebruik in plaats van agressieve kernel-hacks. Ik maak een duidelijk onderscheid tussen HTTP-Keep-Alive (toepassingsprotocol) en de TCP-Keepalive-probes van de kernel: deze laatste zijn pure levenstekenpakketten, niet te verwarren met het open HTTP-venster. Ik wijzig kernel-standaardinstellingen alleen met meetpunt en richt me in de eerste plaats op de webserver zelf: korte, maar effectieve idle-time-outs, beperkte verzoeken per verbinding en redelijke worker-reserves.
Veiligheid: Slowloris & Co. onschadelijk maken
Te royale keep-alive-waarden nodigen uit tot misbruik. Daarom beperk ik niet alleen de idle-tijden, maar ook de lees- en body-time-outs. Onder Nginx gebruik ik client_header_timeout en client_body_timeout; bij Apache stel ik via geschikte modules harde leeslimieten in, zodat geen enkele traag druppelende aanvraag workers blokkeert. Limieten voor headergrootte en request-bodies voorkomen bovendien geheugenbloat. In combinatie met gematigde keep-alive-vensters verlaag ik het risico dat een klein aantal clients veel sockets bezet. De volgorde blijft belangrijk: eerst correcte time-outs, dan gerichte limieten en ten slotte rate- of IP-gerelateerde regels. Alleen zo blijven echte gebruikers snel, terwijl aanvalsprofielen op niets uitlopen.
Monitoring en belastingstests
Na elke wijziging meet ik het effect met tools zoals ab, wrk of k6 en kijk ik naar het 95e percentiel van de Latencies. Ik verminder eerst de time-out in duidelijke stappen en kijk of het aantal time-outs of verbroken verbindingen toeneemt; vervolgens pas ik het aantal verzoeken per verbinding aan. Tegelijkertijd evalueer ik open sockets, worker-belasting en geheugenbehoefte om inactiviteit op de juiste plaats te onderbreken. Voor terugkerende wachttijden is het de moeite waard om te kijken naar wachtrijen in de backend, trefwoord Serverwachtrij en verzoekverdeling. Wie met meetpunten werkt, herkent knelpunten vroegtijdig en bespaart zichzelf veel tijd. Problemen oplossen.
Log- en metriekpraktijk
Ik wil zien of verbindingen echt opnieuw worden gebruikt. Onder Nginx breid ik het logformaat uit met verbindingscounters en tijden; de waarden laten me zien of clients veel verzoeken per verbinding verzenden of na één of twee hits sluiten. Ik ga op dezelfde manier te werk bij Apache om het aantal verzoeken per verbinding zichtbaar te maken. Zo identificeer ik patronen die meer profiteren van de time-out of de verzoeklimiet.
# Nginx: voorbeeld van uitgebreid logformaat log_format main_ext '$remote_addr $request ' 'conn=$connection reqs=$connection_requests ' 'rt=$request_time uct=$upstream_connect_time';
access_log /var/log/nginx/access.log main_ext;
# Apache: LogFormat met verbinding en duur LogFormat "%h %r conn:%{c}L reqs:%{REQUESTS_PER_CONN}n time:%D" keepalive CustomLog logs/access_log keepalive
Bij de monitoring ben ik naast de mediaan vooral geïnteresseerd in P95/P99-latenties, actieve verbindingen, de verdeling van de verzoeken/verbindingen en foutmarges (toenemende 408/499). Als deze met een kleiner keep-alive-venster omhoog springen, draai ik matig terug; als de belasting vlak blijft en de latentie beter wordt, heb ik de sweet spot gevonden.
Implementatie en rolling restarts
Reloads en upgrades zijn compatibel met Keep-Alive als ik ze goed plan. Bij Nginx zet ik in op soepele reloads en laat ik worker-verbindingen gecontroleerd afhandelen in plaats van ze hard af te sluiten. Korte idle-time-outs helpen om oude workers sneller vrij te maken. Onder Apache gebruik ik een sierlijk-Start opnieuw op en houd tegelijkertijd mod_status of statuspagina's in de gaten, zodat wachtende verzoeken niet verloren gaan. Voor grotere implementaties verlaag ik tijdelijk het Keep-Alive-venster om het systeem sneller te legen en breng ik het na een stabiliteitscontrole weer terug naar de streefwaarde. Belangrijk: documenteer wijzigingen en vergelijk ze met belastingprofielen, zodat er geen onopgemerkte vertragingen ontstaan. Regressies binnensluipen.
Veelvoorkomende fouten en tegenmaatregelen
Te lange tijdvensters houden inactieve Verbindingen open en verplaatsen het probleem naar worker-bottlenecks, wat nieuwe bezoekers merkbaar afremt. Onbeperkte verzoeken per verbinding zien er elegant uit, maar uiteindelijk groeit de binding per socket en raken piekbelastingen uit de hand. Extreem korte vensters van minder dan een seconde zorgen ervoor dat browsers voortdurend opnieuw worden opgebouwd, waardoor handshake-delen toenemen en de frontend schokkerig lijkt. In proxyketens ontbreekt vaak de consistentie: een schakel gebruikt HTTP/1.0 of stelt Connection: close in, wat hergebruik blokkeert. Ik werk daarom in volgorde: activering controleren, time-outs in kleine stappen aanpassen, verzoeken per verbinding aanpassen en alleen verhogen als metingen echt Voordeel show.
Checklist voor snelle implementatie
Eerst activeer ik Keep-Alive en noteer ik de huidige Waarden, zodat ik op elk moment terug kan schakelen. Daarna stel ik de time-out in op drie seconden, laad ik de configuratie opnieuw en controleer ik open verbindingen, belasting en watervallen in de frontend. Als er veel korte bezoeken zijn, verlaag ik dit naar twee seconden; als API-long-polls zich opstapelen, verhoog ik dit gematigd naar vijf tot tien seconden. Vervolgens stel ik MaxKeepAliveRequests in op 300-500 en kijk ik of er slots vrij blijven of dat sterke permanente clients te lang verbonden blijven. Na elke stap meet ik opnieuw, documenteer ik de effecten en houd ik de beste Combinatie vast.
Korte balans
Een correct geconfigureerde Keep-Alive bespaart handshakes, vermindert de latentie en geeft de server meer Lucht per verzoek. Met korte, maar niet te korte tijdvensters en een gemiddeld aantal verzoeken per verbinding werkt de host merkbaar soepeler. Ik zet in op kleine wijzigingen met duidelijke meetpunten, in plaats van blindelings te draaien op maximale waarden. Wie hosting, reverse proxy en backend consistent op hergebruik afstemt, profiteert van snelle interactie zonder onnodige binding van resources. Uiteindelijk telt de meting: alleen echte kengetallen laten zien of de afstemming het verhoopte resultaat oplevert. Effect brengt.


