Site Hızı & Performans

    Keep-Alive Bağlantı Ayarları

    Kalıcı HTTP bağlantılarının mantığı, Nginx ve Apache keep-alive parametrelerinin doğru seçimi.

    10 dk okuma Güncellendi: 25 Ağustos 2026

    Bir hız testi raporunda "Use persistent connections" ya da "Keep-Alive etkin değil" uyarısını gördüyseniz, aslında sunucunuzun her istek için yeni bir TCP bağlantısı kurup kapattığını söylüyor demektir. Keep-Alive, tek bir TCP bağlantısını birden çok HTTP isteği için açık tutmayı sağlayan mekanizmadır; kapalı olduğunda bir sayfadaki her CSS dosyası, her görsel ve her script için baştan el sıkışma yapılır. HTTPS'te bu, her dosya için TCP üç yollu el sıkışması artı TLS el sıkışması demektir ve gecikmesi 60-80 ms olan bir bağlantıda saniyeler mertebesinde israfa dönüşür.

    Bu rehberde Keep-Alive'ın gerçekte ne yaptığını, Nginx ve Apache üzerinde hangi parametrelerle ayarlandığını, "daha uzun her zaman daha iyi" varsayımının neden yanlış olduğunu, ters vekil (reverse proxy) kurulumlarında sıkça atlanan upstream keepalive ayarını ve HTTP/2 ile birlikte bu ayarların anlamının nasıl değiştiğini anlatacağım. Sonunda bağlantıların gerçekten yeniden kullanılıp kullanılmadığını nasıl doğrulayacağınızı da göstereceğim.

    Keep-Alive Aslında Ne Yapıyor#

    HTTP/1.0 zamanında model basitti ve pahalıydı: istemci bağlanır, bir istek gönderir, yanıtı alır, bağlantı kapanır. Bir sayfa 40 kaynaktan oluşuyorsa 40 ayrı bağlantı kurulur. HTTP/1.1 ile birlikte kalıcı bağlantı varsayılan davranış oldu; bağlantı yanıttan sonra kapatılmaz, bir süre daha açık bekletilir ve aynı sunucuya gidecek sonraki istekler bu hazır borudan akar.

    Kazancın büyüklüğünü anlamak için bir el sıkışmanın maliyetine bakalım. Gidiş-dönüş süresi (RTT) 70 ms olan bir bağlantıda TCP el sıkışması yaklaşık 1 RTT, TLS 1.3 el sıkışması yine yaklaşık 1 RTT sürer. Yani her yeni HTTPS bağlantısı, tek bayt veri akmadan önce kabaca 140 ms harcar. Keep-Alive kapalıysa ve sayfanız 30 kaynak istiyorsa, tarayıcı bunları 6 paralel bağlantıya bölse bile beş tur boyunca bu maliyeti tekrar tekrar öder.

    DurumBağlantı sayısıÖdenen el sıkışmaTipik ek gecikme
    Keep-Alive kapalı, 30 kaynak3030 × (TCP + TLS)Çok yüksek
    Keep-Alive açık, HTTP/1.16 (tarayıcı sınırı)6 × (TCP + TLS)Düşük
    HTTP/2, tek bağlantı11 × (TCP + TLS)En düşük

    Tablodan görülebileceği gibi Keep-Alive, HTTP/2'ye giden yolun ilk basamağı. HTTP/2 zaten tek bir bağlantı üzerinde çalıştığı için kalıcı bağlantı onun için varsayılan ve zorunlu bir davranıştır; protokolün nasıl çalıştığını HTTP/2 nedir yazısında bulabilirsiniz.

    Nginx Tarafında Keep-Alive Parametreleri#

    Nginx'te Keep-Alive varsayılan olarak açıktır; ayarlamanız gereken şey ne kadar süre ve kaç istek boyunca açık kalacağıdır. İki temel yönerge var ve ikisi de http, server ya da location bloklarında tanımlanabilir:

    http {
        # Bağlantı boşta kaldıktan kaç saniye sonra kapatılsın
        keepalive_timeout 30s;
    
        # Tek bir bağlantı üzerinde en fazla kaç istek işlensin
        keepalive_requests 1000;
    
        # İstemciye "biz bu bağlantıyı 30 saniye açık tutuyoruz" bilgisini gönder
        # (ikinci parametre Keep-Alive başlığındaki timeout değeridir)
        # keepalive_timeout 30s 30s;
    }
    

    keepalive_timeout değerinin varsayılanı 75 saniyedir ve çoğu kurulum için gereğinden uzundur. Bu değeri seçerken şu dengeye bakın: bağlantıyı uzun tutmak, gerçekten dönecek bir ziyaretçi için el sıkışmayı bir kez daha kurtarır; ama boşta bekleyen her bağlantı bir dosya tanıtıcısı ve bir miktar bellek tutar. Nginx olay tabanlı çalıştığı için binlerce boşta bağlantıyı ucuza taşır, dolayısıyla 15-60 saniye aralığı güvenlidir. Sayfa içi kaynakların tamamı zaten ilk birkaç saniyede istenir; 75 saniye beklemenin pratik bir karşılığı yoktur.

    keepalive_requests ise tek bağlantıda işlenecek istek sayısını sınırlar. Sınırın var olma sebebi bellek hijyenidir: çok uzun ömürlü bağlantılarda bağlantı başına ayrılan tamponlar birikir. Modern Nginx sürümlerinde varsayılan 1000'dir ve normal siteler için değiştirmeye gerek yoktur.

    Değişiklikten sonra yapılandırmayı test edip yeniden yükleyin:

    nginx -t && systemctl reload nginx
    

    Apache Tarafında Keep-Alive Parametreleri#

    Apache'de üç yönerge iş görür ve ikisinin varsayılanı gerçekten kötüdür. Yapılandırma genelde /etc/apache2/apache2.conf ya da /etc/httpd/conf/httpd.conf içindedir:

    # Kalıcı bağlantılar açık olsun
    KeepAlive On
    
    # Tek bağlantıda en fazla kaç istek (0 = sınırsız)
    MaxKeepAliveRequests 200
    
    # Boşta bekleme süresi (saniye)
    KeepAliveTimeout 5
    

    Buradaki kritik nokta KeepAliveTimeout değeridir ve Apache'nin Nginx'ten neden farklı davrandığını anlamak gerekir. Apache prefork ya da worker MPM ile çalışırken her bağlantı bir süreç ya da iş parçacığı işgal eder. Bağlantıyı 60 saniye açık tutmak, o süreci 60 saniye boyunca başka bir ziyaretçiye hizmet edemez hale getirir. Eş zamanlı ziyaretçi sayınız MaxRequestWorkers değerine yaklaştığında yeni gelenler kuyruğa girer ve site "yavaşladı" değil, doğrudan "açılmıyor" durumuna geçer.

    Bu yüzden Apache'de pratik değer 2-5 saniyedir. Sayfanın kaynakları zaten bu süre içinde istenir; ziyaretçi okumaya başladıktan sonra bağlantıyı tutmanın faydası yoktur. mpm_event kullanıyorsanız boşta bağlantılar ayrı bir dinleyici iş parçacığına devredildiği için biraz daha cömert olabilirsiniz, ama yine de 10 saniyeyi geçmeye gerek yoktur. Apache ile LiteSpeed arasındaki eş zamanlılık modeli farkını merak ediyorsanız LiteSpeed vs Apache karşılaştırması bu konuyu ayrıntılandırıyor.

    Değişikliği uygulamadan önce söz dizimini doğrulayın:

    # Debian/Ubuntu
    apachectl configtest && systemctl reload apache2
    
    # RHEL/AlmaLinux
    httpd -t && systemctl reload httpd
    

    Ters Vekil Kurulumlarında Upstream Keep-Alive#

    En sık atlanan ayar budur ve etkisi genellikle en büyüğüdür. Nginx'i PHP-FPM, bir Node.js uygulaması ya da arka plandaki başka bir HTTP sunucusunun önüne koyduğunuzda, ziyaretçi ile Nginx arasındaki bağlantı kalıcıdır ama Nginx ile arka uç arasındaki bağlantı varsayılan olarak her istekte kurulup kapatılır. Yoğun bir sitede bu, saniyede yüzlerce gereksiz TCP el sıkışması ve TIME_WAIT durumunda biriken soketler demektir.

    Çözüm bir upstream bloğu tanımlayıp bağlantı havuzu açmaktır:

    upstream uygulama {
        server 127.0.0.1:3000;
    
        # Her worker sürecinin havuzunda tutulacak boşta bağlantı sayısı
        keepalive 32;
    
        # Havuzdaki bir bağlantı kaç istek ve kaç saniye sonra tazelensin
        keepalive_requests 1000;
        keepalive_timeout 60s;
    }
    
    server {
        location / {
            proxy_pass http://uygulama;
    
            # Bu iki satır olmadan keepalive ÇALIŞMAZ
            proxy_http_version 1.1;
            proxy_set_header Connection "";
    
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
    

    Son iki proxy_* satırı kesinlikle atlanmamalı. Nginx arka uca varsayılan olarak HTTP/1.0 ile konuşur ve HTTP/1.0'da kalıcı bağlantı yoktur; ayrıca gelen Connection başlığını olduğu gibi iletir, bu da çoğu zaman Connection: close anlamına gelir. proxy_http_version 1.1; ve boş Connection başlığı yazılmazsa keepalive 32; satırı hiçbir işe yaramaz — yapılandırma hatasız yüklenir, log'da bir uyarı çıkmaz ve siz havuzun çalıştığını sanırsınız. Bu, sessizce başarısız olan ayarların ders kitabı örneğidir.

    keepalive değerini seçerken arka ucunuzun eş zamanlı iş parçacığı sayısını göz önünde bulundurun; PHP-FPM havuzunuzda 20 çocuk süreç varsa 16-32 arası makul bir başlangıçtır. Nginx tabanlı önbellekleme ile birlikte kullandığınızda kazanç daha da belirginleşir; Nginx FastCGI cache yapılandırması yazısı bu ikiliyi birlikte kurmayı anlatıyor.

    HTTP/2 ve HTTP/3 ile Keep-Alive'ın Değişen Anlamı#

    HTTP/2'ye geçtiğinizde keepalive_requests ve keepalive_timeout yönergelerinin anlamı incelikle değişir. HTTP/2'de tarayıcı sunucuya zaten tek bir bağlantı açar ve tüm istekleri o bağlantıda multiplex eder. Yani "bağlantıyı yeniden kullanma" artık bir optimizasyon değil, protokolün temel çalışma biçimidir.

    Buradaki tuzak şudur: HTTP/2 bağlantısında keepalive_requests sınırına ulaşıldığında Nginx bağlantıyı kapatır ve tarayıcı yenisini kurmak zorunda kalır. Tek sayfada yüzlerce istek yapan bir uygulamada (örneğin çok sayıda küçük API çağrısı yapan bir panel), düşük bir keepalive_requests değeri gereksiz bağlantı yenilenmesine yol açar. Bu yüzden HTTP/2 kullanan sunucularda bu değeri 100 gibi eski varsayılanlarda bırakmayın; 1000 ve üzeri daha uygundur.

    HTTP/3'te ise durum bir adım daha değişir: QUIC bağlantıyı IP adresine değil bağlantı kimliğine bağlar, dolayısıyla ağ değişse bile oturum devam eder ve boşta kalma yönetimi QUIC'in kendi zamanlayıcılarına geçer. Bu geçişi yapmayı düşünüyorsanız HTTP/3 (QUIC) etkinleştirme rehberi yapılandırma tarafını adım adım anlatıyor.

    Doğrulama: Bağlantı Gerçekten Yeniden Kullanılıyor mu#

    Ayarları yazmak yetmez, ölçmek gerekir. En hızlı yöntem curl ile iki isteği tek komutta yapıp bağlantının yeniden kullanılıp kullanılmadığına bakmaktır:

    # -v çıktısında ikinci istekte "Re-using existing connection" görünmeli
    curl -sv https://firmaniz.com/ https://firmaniz.com/favicon.ico -o /dev/null 2>&1 \
      | grep -Ei "Connected to|Re-using|Connection #"
    
    # Yanıt başlığında bağlantının kapatılıp kapatılmadığını gör
    curl -sI https://firmaniz.com | grep -iE "connection|keep-alive"
    

    Yanıtta Connection: close görüyorsanız Keep-Alive kapalıdır ya da bir yerde kapatılıyordur. Hiçbir Connection başlığı yoksa ve protokol HTTP/1.1 ise varsayılan davranış zaten kalıcı bağlantıdır; endişelenmeyin. HTTP/2 yanıtlarında Connection başlığı protokol gereği hiç bulunmaz, bu normaldir.

    Sunucu tarafında soket durumlarına bakmak da öğreticidir:

    # Kurulu bağlantıların durum dağılımı
    ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn
    
    # TIME_WAIT sayısı çok yüksekse bağlantılar sürekli kurulup kapanıyordur
    ss -tan state time-wait | wc -l
    

    TIME_WAIT sayısının binlerle ifade edilmesi, özellikle 127.0.0.1 üzerindeki upstream bağlantılarında, yukarıdaki proxy_http_version 1.1; ayarının eksik olduğuna dair güçlü bir işarettir.

    Sık Yapılan Hatalar#

    Süreyi olabildiğince uzun tutmak. "Keep-Alive iyiyse daha uzunu daha iyidir" varsayımı Apache'de doğrudan kaynak tükenmesine yol açar. KeepAliveTimeout 65 yazılmış bir prefork Apache, birkaç yüz eş zamanlı ziyaretçide tüm süreçlerini boşta bekleyen bağlantılara kaptırır ve site erişilemez hale gelir. Nginx'te sonuç bu kadar yıkıcı değildir ama yine de bir fayda üretmez.

    Keep-Alive'ı kapatarak "yükü azaltmaya" çalışmak. Sunucu yoğunken bazı yöneticiler KeepAlive Off yaparak süreçleri serbest bırakmayı dener. Bu, semptomu bir yere taşır: süreçler serbest kalır ama her istek yeni bir el sıkışma ödediği için hem kullanıcı deneyimi kötüleşir hem de CPU'da TLS maliyeti artar. Doğru çözüm süreyi kısaltmaktır, kapatmak değil.

    Upstream keepalive'ı yazıp proxy_http_version satırını unutmak. Yukarıda anlattığım sessiz başarısızlık. Yapılandırmayı yazdıktan sonra mutlaka ss -tan state time-wait | wc -l ile doğrulayın.

    Yük dengeleyici ve CDN katmanını hesaba katmamak. Önünüzde Cloudflare gibi bir katman varsa, ziyaretçi ile CDN arasındaki bağlantıyı CDN yönetir; sizin keepalive_timeout ayarınız yalnızca CDN ile origin sunucunuz arasındaki bacağı etkiler. Bu bacakta çok kısa bir timeout, CDN tarafında bağlantı sıfırlanmalarına ve zaman zaman 520 türü hatalara yol açabilir; belirtileri Cloudflare 520, 521 ve 522 hataları yazısında karşılaştırabilirsiniz.

    Sağlık kontrolü trafiğini unutmak. Yük dengeleyicinizin ya da izleme sisteminizin saniyede bir attığı sağlık kontrolü istekleri de bağlantı açar. Bunlar Keep-Alive kullanmıyorsa arka planda sürekli el sıkışma üretir; izleme aracınızın kalıcı bağlantı kullandığından emin olun.

    Sıkça Sorulan Sorular#

    Keep-Alive siteyi gerçekten hızlandırır mı#

    Evet, özellikle HTTPS ve yüksek gecikmeli bağlantılarda kazanç somuttur. Her yeni bağlantı için TCP ve TLS el sıkışması ödenir; gidiş-dönüş süresi 70 ms olan bir bağlantıda bu, veri akmadan önce yaklaşık 140 ms demektir. Onlarca kaynağı olan bir sayfada bu maliyet tekrar tekrar ödenir. Keep-Alive açıkken aynı bağlantı yeniden kullanıldığı için bu süre yalnızca bir kez harcanır.

    keepalive_timeout değerini kaç yapmalıyım#

    Nginx için 15-60 saniye aralığı güvenli ve yaygın bir tercihtir; varsayılan 75 saniye çoğu site için gereğinden uzundur. Apache'de ise 2-5 saniye önerilir, çünkü her bağlantı bir süreç ya da iş parçacığı tutar ve uzun süre kaynak tüketir. Sayfanın tüm kaynakları zaten ilk birkaç saniyede istenir; ziyaretçi okumaya başladıktan sonra bağlantıyı açık tutmanın ölçülebilir bir faydası yoktur.

    Keep-Alive açık mı kapalı mı nasıl kontrol ederim#

    En pratik yöntem curl -sI https://firmaniz.com komutuyla yanıt başlıklarına bakmaktır. Connection: close görüyorsanız kalıcı bağlantı kullanılmıyor demektir. HTTP/1.1'de hiçbir Connection başlığı yoksa varsayılan zaten kalıcı bağlantıdır. Daha kesin bir test için curl -sv ile iki istek yapıp çıktıda "Re-using existing connection" satırını arayın.

    HTTP/2 kullanıyorsam Keep-Alive ayarlarıyla uğraşmam gerekir mi#

    HTTP/2 zaten tek bağlantı üzerinde çalıştığı için kalıcı bağlantı protokolün doğal davranışıdır; ayrıca açmanız gereken bir şey yoktur. Ancak keepalive_requests değeri hâlâ geçerlidir ve sınıra ulaşıldığında bağlantı kapatılır. Çok sayıda istek yapan uygulamalarda bu değeri düşük bırakmak gereksiz bağlantı yenilenmesine yol açar; 1000 ve üzeri makul bir seçimdir.

    TIME_WAIT sayısının çok yüksek olması ne anlama gelir#

    Bu, bağlantıların sürekli kurulup kapandığının işaretidir. Ziyaretçi tarafında Keep-Alive kapalı olabilir, ama daha sık rastlanan sebep ters vekil ile arka uç arasındaki upstream bağlantılarının havuzlanmamasıdır. Nginx kullanıyorsanız upstream bloğunda keepalive yönergesinin bulunduğunu ve location içinde proxy_http_version 1.1; ile boş Connection başlığının yazıldığını kontrol edin; bu iki satır eksikse havuz sessizce devre dışı kalır.

    Paylaşımlı hostingte bu ayarları değiştirebilir miyim#

    Doğrudan keepalive_timeout gibi sunucu genelindeki yönergelere erişemezsiniz, çünkü bunlar tüm hesapları etkiler ve sağlayıcı tarafından yönetilir. Bununla birlikte iyi yapılandırılmış paylaşımlı sunucularda Keep-Alive zaten açıktır; curl -sI ile doğrulayabilirsiniz. Kapalıysa destek talebi açmak ilk adımdır. Bu tür ayarları kendiniz yönetmek istiyorsanız root erişimli bir sunucuya geçmeniz gerekir.

    Kapanış#

    Keep-Alive, doğru ayarlandığında ücretsiz bir hız kazancı, yanlış ayarlandığında ise sunucuyu kilitleyen bir kaynak tuzağıdır. Aklınızda kalması gereken dört alışkanlık şunlar: Nginx'te süreyi 15-60 saniye, Apache'de 2-5 saniye aralığında tutun; kaynak sıkıntısında Keep-Alive'ı kapatmak yerine süreyi kısaltın; ters vekil kullanıyorsanız upstream havuzunu proxy_http_version 1.1; ve boş Connection başlığıyla birlikte mutlaka kurun; sonucu curl -sv ve ss -tan çıktılarıyla doğrulayın. Ayarların çoğu tek satırdır ama etkisi eş zamanlı ziyaretçi sayınız arttıkça katlanarak büyür.

    Bu tür sunucu düzeyindeki ince ayarları kendiniz yapmak istiyorsanız tam root erişimi veren VDS ve sanal sunucu paketlerimiz uygun bir zemin sunar. Yapılandırmayı uzmanına bırakmayı tercih ederseniz sunucu yönetimi hizmetimiz web sunucusu ayarlarını, önbellekleme ve protokol yapılandırmasını sizin yerinize üstlenir; hazır ve optimize edilmiş bir başlangıç arıyorsanız kurumsal hosting paketlerimize göz atabilirsiniz.

    Keep-AliveNginxApache

    Uygulamaya geçmeye hazır mısınız?

    NVMe SSD, ücretsiz SSL ve %99.9 uptime garantisiyle Clou.TR hosting ve sunucu çözümleriyle projenizi hayata geçirin.