Ana Sayfa Hakkımda Dersler Blog Mikrofonda İletişim Projeler
Dersler DEPLOY · C#

Shared Hosting'de Cold Start Sorunu ve Warmup Cron

8 dk okuma · Emre Ulutabak
1
Cold start nedir?

Bir sabah sitene giriyorsun, sayfa 8-10 saniye boyunca beyaz ekranda kalıyor. Panik yapıyorsun — "sunucu mu çöktü?" Ama sayfa yükleniyor, her şey normal çalışıyor. Sonraki tıklamalar ise anında açılıyor.

Bu cold start. Uygulaman bir süre istek almadığında, IIS onu belleğe alıp kapatır. Bir sonraki istek geldiğinde, .NET runtime'ı sıfırdan ayağa kaldırmak, DbContext'i kurmak, servisleri DI container'a doldurmak gerekir — işte o birkaç saniyelik gecikme burdan gelir.

Kullanıcı için sorun değilse de, bir lisans doğrulama API'si için ciddi sorun. Müşterinin plugin'i her açılışta API'ye soruyor — API uyuyorsa, plugin donmuş gibi görünür.

💡
Cold start bir hata değil, IIS'in tasarım gereği yaptığı bir kaynak tasarrufu. Shared hosting'de yüzlerce site aynı sunucuyu paylaşır — boşta duran uygulamalar RAM işgal etmesin diye kapatılır.
2
Uygulama neden "uyur"?

Bunun sorumlusu IIS'in App Pool Idle Time-out ayarı. Bu süre sabit değil — hosting sağlayıcısına ve panel yapılandırmasına göre değişir; bazı panellerde 5 dakika kadar kısa, bazılarında 20 dakika veya daha uzun olabilir. Bir uygulama bu süre boyunca hiç istek almazsa, IIS worker process'i (w3wp.exe) kapatır. Belleği geri alır, başka siteler kullansın diye.

Dedicated bir sunucuda bu ayarı IIS Manager'dan değiştirebilirsin, hatta "Always On" moduna alabilirsin. Ama shared hosting'de bu seçenek yok — Application Pool ayarlarına erişimin kısıtlı, çünkü o pool'u sen değil, hosting firması yönetiyor.

Önce kendi panelindeki değeri öğrenmek faydalı olur (hosting firmana sorabilir ya da panel dokümantasyonuna bakabilirsin). Ama pratikte soru şu hale geliyor: IIS'i değiştiremiyorsan, uygulamanı hiç uyumasın diye nasıl "meşgul" tutarsın?

3
Warmup cron çözümü

Çözüm basit bir fikre dayanıyor: idle timeout süresi dolmadan, dışarıdan uygulamana kendin bir istek gönder. Uygulama hiç boşta kalmadığı için IIS onu kapatma fırsatı bulamaz.

Bunun için önce uygulamana hafif, kimlik doğrulaması istemeyen bir "ping" endpoint'i eklemen gerekiyor:

csharp
[ApiController]
[Route("api/[controller]")]
public class PingController : ControllerBase
{
    // AllowAnonymous — cron job giriş yapmıyor, sadece uyandırıyor
    [HttpGet]
    [AllowAnonymous]
    public IActionResult Get()
    {
        // Ağır bir iş yapma — tek amacı process'i canlı tutmak
        return Ok(new { status = "awake", time = DateTime.UtcNow });
    }
}
💡
Ping endpoint'ini DB'ye bağlama. Amacı sadece IIS worker process'ini canlı tutmak — DB sorgusu eklersen hem gereksiz yük binersin hem de DB kapalıyken cron'un kendisi hata vermeye başlar.
4
Plesk'te cron kurulumu

Endpoint hazır olunca sırada, onu düzenli aralıklarla çağıracak bir zamanlayıcı var. Plesk'te bu Scheduled Tasks (Zamanlanmış Görevler) altında.

Idle timeout süresi dolmadan tetiklemek için, örneğin her 3 dakikada bir çalışan bir görev genelde yeterli pay bırakır — ama panelinin gerçek timeout süresini bilmiyorsan, önce onu öğrenmekte fayda var:

powershell
# Plesk Scheduled Task — cron ifadesi
# Her 3 dakikada bir, saatin her dakikasında (0, 3, 6, 9 ... 57)
0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57 * * * *

# Çalıştırılacak komut (curl ile)
curl -s -o /dev/null -w "%{http_code}" https://api.emreulutabak.com/api/ping
💡
"Her dakika" (* * * * *) yazmaya gerek yok. Örneğin 3 dakikalık bir aralık çoğu panelde yeterli pay bırakır — ama kendi panelindeki idle timeout süresini biliyorsan, cron aralığını ona göre (belirgin şekilde kısa tutarak) ayarla.
5
Doğrulama ve izleme

Kurulumdan sonra çözümün gerçekten çalıştığını doğrulamak lazım. Birkaç yöntem:

  • Plesk Task Log'u — her çalıştırmanın çıktısını gösterir, HTTP 200 dönüp dönmediğini buradan izle.
  • Manuel test — uygulamaya, bildiğin idle timeout süresinden biraz daha uzun bir süre hiç istek atma, sonra bir sayfa aç. Cron çalışıyorsa gecikme olmamalı.
  • stdout log — gerekirse geçici olarak açıp, gerçekten her 3 dakikada bir isteğin geldiğini logdan doğrula.
6
Altın kurallar
  • ✅ Ping endpoint'i [AllowAnonymous] olmalı — cron'un login yapması gerekmez
  • ✅ Ping endpoint'i DB'ye bağlanmamalı — sadece process'i canlı tutar
  • ✅ Cron aralığı, idle timeout'tan belirgin şekilde kısa olmalı (ör. panelin idle timeout'u 5 dk ise, 2-3 dk'da bir tetiklemek gibi)
  • ✅ Birden fazla subdomain/uygulama varsa, her biri için ayrı ping + cron kur
  • ✅ Task log'unu düzenli kontrol et — sessizce başarısız olabilir
7
Mini quiz
MİNİ QUIZ
IIS App Pool Idle Time-out süresi hosting sağlayıcısına göre değişir (bazı panellerde 5 dakika kadar kısa olabilir). Bu ayarı değiştiremiyorsan, uygulamanın uyumasını engellemek için en pratik çözüm nedir?
20 dakikadan kısa aralıklarla anonim bir ping endpoint'ini cron ile çağırmak
Uygulamayı sürekli DB sorgusu yapan bir arka plan döngüsüne sokmak
web.config'de hostingModel'i inprocess yapmak
Hosting firmasının Application Pool ayarlarını manuel değiştirmesini beklemek