Bir kayıt formu sekiz saniye sürüyordu. İstek içinde sırayla şunlar oluyordu: kullanıcı kaydediliyor, hoş geldin e-postası gönderiliyor, bir PDF üretiliyor, bir CRM’e kayıt işleniyor. Kullanıcı bu sekiz saniye boyunca dönen bir spinner’a bakıyordu — oysa onu ilgilendiren tek şey, kaydının oluşup oluşmadığıydı.

Bir işi HTTP isteği içinde anında mı yapmalı, kuyruğa mı atmalı? Çizgi göründüğünden net.

Karar çizgisi: kullanıcı sonucu bekliyor mu?

Tek bir soru kararın çoğunu verir: kullanıcı bu işin sonucunu görmek zorunda mı?

  • Cevap “evet” ise iş senkron kalır — istek içinde, yanıt dönmeden biter.
  • Cevap “hayır” ise iş kuyruğa gider — istek “kabul edildi” der ve döner.

Yukarıdaki formda kullanıcı sadece “kaydım oluştu mu” cevabını bekliyor. E-posta, PDF, CRM — hiçbirinin sonucunu o ekranda görmesi gerekmiyor. Üçü de yanlış tarafta duruyordu.

Senkron kalması gerekenler

Kullanıcının sonucunu doğrudan gördüğü işler istek içinde kalır:

  • Girdi doğrulama — hata anında dönmeli.
  • Asıl kaynağın yaratılması — kullanıcı oluşturma, sipariş oluşturma.
  • Ödeme yetkilendirmesinin sonucu — kart geçti mi geçmedi mi, kullanıcı bunu o an bilmeli.
  • Kullanıcının bir sonraki adımda göreceği veri.

Bunları kuyruğa atmak, kullanıcıya “sonra bak” demektir — ve çoğu zaman kötü bir deneyimdir.

Kuyruğa gitmesi gerekenler

Kullanıcının sonucunu o an görmesi gerekmeyen her iş asenkrondur:

  • E-posta ve bildirim.
  • PDF ve rapor üretimi.
  • Webhook gönderimi.
  • Üçüncü parti senkronizasyonu — CRM, analitik, arama indeksi.
  • Görsel işleme, dışa aktarma.

Bunlar için doğru yanıt 202 Accepted’tir: “isteğini aldım, işliyorum.” Kullanıcı beklemez, sistem işi kendi temposunda yapar.

Çizgiyi yanıt süresi keskinleştirir

Her endpoint için bir p95 bütçeniz olmalı — diyelim 300 ms. Bir adım bu bütçeyi tek başına yiyorsa ve kullanıcı o adımın sonucunu görmek zorunda değilse, o adım kuyruğa gider.

Senkron zincir, en yavaş halkası kadar hızlıdır. PDF üretimi 4 saniye sürüyorsa, kullanıcı oluşturma da 4 saniye sürer — PDF’in yanıtla hiçbir ilgisi olmasa bile.

Hata toleransı: asıl ayrım

Asıl mesele hız değil, hatadır. Senkron ve asenkron, başarısızlığı bambaşka karşılar:

  • Senkron hata = kullanıcı bir hata ekranı görür. İş kaybolur.
  • Asenkron hata = job retry edilir, gerekirse DLQ’ya düşer, kuyruk sonra işler.

Buradan tek bir kural çıkar: kararsız bir üçüncü parti asla senkron yolda durmamalı. O CRM çağrısı istek içindeyse, CRM her çöktüğünde sizin kayıt formunuz da çöker. Kuyruğa alınmış bir çağrı ise, CRM döndüğünde retry kendiliğinden tamamlanır. Üçüncü partinin uptime’ı sizin uptime’ınız olmaktan çıkar.

202 ve durum sorgusu kalıbı

İş kuyruğa gidince kullanıcıya bir takip yolu bırakın:

POST /exports          → 202 Accepted  { "id": "exp_1a2b", "status": "processing" }
GET  /exports/exp_1a2b → 200 OK        { "status": "done", "url": "..." }

Kullanıcı sonucu beklemiyordur ama bazen merak eder. Bir durum endpoint’i ya da hazır olunca gönderilen bir bildirim, bu boşluğu kapatır.

Sınır nerede kalkar?

Bazı işler ikisinin arasındadır: kullanıcı sonucu görmek ister ama iş de yavaştır. Burada üçüncü bir yol var — işi senkron başlat, ilk anlamlı sonucu hemen dön, gerisini kuyruğa devret. Sipariş kaydını anında oluştur (senkron), faturayı arkada üret (asenkron).

Çizgiyi her iş için ayrı çizin; “her şey kuyruğa” da “her şey senkron” kadar yanlıştır.


Senkron mu asenkron mu sorusu bir performans sorusu değil, bir “kim bekliyor” sorusudur. Kullanıcının beklemediği hiçbir iş, onun isteğini bekletmemeli.

İsteği yalnızca, cevabını gerçekten istediği işle meşgul edin.