İki sistem arasında data senkronizasyonu kurarken ilk soru: webhook mı polling mi? Cevap genelde ikisi de, duruma göre.
Son yıllarda bir e-ticaret entegrasyonu (Shopify + ERP), bir fintech bildirim sistemi (banka webhook + fallback poll), bir analytics platform (event ingestion) üzerinde bu sorunun cevabını ikinci defa verdim. Aynı soru, her seferinde biraz farklı cevap.
Bu yazıda framework’ü paylaşıyorum.
Polling: sade, aptal, çalışıyor
Polling: client bir endpoint’i düzenli aralıklarla çağırıp değişiklik var mı diye kontrol ediyor.
while true:
response = GET /api/orders?since=last_sync_timestamp
for order in response.orders:
process(order)
last_sync_timestamp = response.server_time
sleep(60)Avantajlar:
– Client pull ediyor, firewall / NAT problem yok
– Authentication client side, standart Bearer token yeter
– Failure recovery basit: bir çağrı başarısız oldu, bir sonraki çağrıda yakalanır
– Debugging kolay: curl ile test, log’da her çağrı görünüyor
Dezavantajlar:
– Latency: poll interval kadar. 60 saniye poll ile 30 saniye gecikme ortalama
– Kaynak israfı: çoğu poll “hiç değişiklik yok” cevabı, bandwidth ve CPU boşa
– Server side load: N client her 60 saniyede bir poll = istikrarlı baseline load
Webhook: reactive, verimli, zor
Webhook: server değişiklik olduğunda client’ın verdiği URL’e POST atıyor. Client’ın publicly reachable endpoint’i olmalı.
Avantajlar:
– Latency: milisaniye. Event olduğu anda bildirim
– Verimlilik: boşuna poll yok, sadece gerçek değişiklik
– Scalability: millions of client mümkün, her biri sadece kendi event’ini alıyor
Dezavantajlar:
– Client publicly reachable olmalı (dev environment’ta tunnel gerekir, ngrok/Cloudflare Tunnel)
– Authentication karmaşık: signature verification, secret rotation
– Delivery garantisi zor: webhook server tarafından kaybolabilir, client 5xx dönebilir, retry semantics belirsiz
– Ordering garanti yok: event’ler sıralı gelmiyor olabilir
– Debugging zor: POST geldi mi gelmedi mi bilinmiyor, retrospective incelenemiyor
Hangi durumda hangisi?
Karar matrisim:
| Durum | Tercih |
|——-|——–|
| Low-frequency data, sub-second latency gerekli | Webhook |
| High-frequency data, saniye seviyesi ok | Polling |
| Client firewalled / local dev | Polling |
| Event sırası kritik | Polling (pagination ile) |
| Backend’den sinyal, oluş sayısı belirsiz | Webhook |
| Both ends you control | Webhook ideal |
| Third-party consumer | Polling fallback şart |
En sık gördüğüm hata: webhook-only
Webhook’u sevmek kolay. Latency düşük, verimli, modern. “Polling artık 2010’ların teknolojisi” diyen mühendislerle karşılaştım.
Ama webhook-only sistem hassas. Bir webhook düşerse (server outage, network issue, endpoint 500 dönüyor), event kaybolur. Consumer’ın bu event’in hiç olmadığını anlaması için hiçbir yol yok.
Gerçek bir incident: Shopify bir 15 dakika süresince webhook delivery’de gecikme yaşadı, retry yaptı ama endpoint’imizde rate limit’e takıldı, bazı order’lar %99 başarı ile düştü, %1’i kayıp. ERP’de 47 sipariş eksik oluştu. Destek kriz.
Hibrit yaklaşım: webhook + reconciliation
En sağlıklı pattern:
- Webhook: real-time event’ler için primary
- Polling-based reconciliation: her 1-6 saatte bir “son 24 saatin event’lerini” poll et, eksik olanları yakala
Reconciliation job:
def reconcile_last_24h():
since = now - timedelta(hours=24)
remote_events = api.fetch_events(since=since)
local_events = db.fetch_events(since=since)
missing = [e for e in remote_events if e.id not in local_events]
for event in missing:
log.warn(f"Missed webhook: {event.id}")
process_event(event)Reconciliation sık değil (saatlik yeterli), tek job. Ama webhook’un gözden kaçırdığı her şeyi yakalıyor.
Webhook delivery guarantees
Webhook tasarlıyorsanız şunları garantilemelisiniz:
At-least-once delivery. Retry policy olmalı. Consumer 5xx döndüyse, timeout olduysa, retry. Exponential backoff.
Signature verification. Her webhook HMAC-signed olmalı. Consumer secret ile doğrulayıp forgery’i engelliyor.
Idempotency key. Her event’in unique ID’si. Consumer aynı ID’yi ikinci kez görürse skip.
Delivery log. Consumer tarafında “bu ID’li webhook şu zamanda geldi” log’u. Destek debug için şart.
Delivery dashboard. Producer side, kullanıcıya “son 1 saatte kaç webhook gitti, kaçı başarısız, hangisi retry’da” göstermek. Customer support ticket azaltıyor.
Consumer side: endpoint design
Webhook endpoint’i tasarlarken:
Fast ack. 200 OK’i hemen dönün, iş processing’i async queue’ya atın. Webhook producer timeout (çoğu 10-30 saniye) uzun iş için yetmez, queue’ya attıktan sonra sürdürebilirsiniz.
Idempotency built-in. Consumer event ID + timestamp’e göre duplicate’leri filtreler.
Rate limit’e dayanıklı. Burst traffic gelebilir (downtime sonrası catch-up). Queue ile buffer, backpressure.
Logging. Her webhook’u raw body ile logla. Bug debug için aksi taktirde kaybolur.
Polling: tasarım iyi olursa verimli
Polling her zaman verimsiz değil. İyi pattern:
Since cursor ile incremental pull. Tüm dataset’i her seferinde çekmeyin. Son çekilen timestamp’ten itibaren yeni kayıtları çekin.
Conditional requests. ETag / If-Modified-Since header’ları. Değişmemişse 304 Not Modified dönüyor, bandwidth tasarrufu.
Adaptive polling interval. Aktivite fazla iken sık poll, az iken seyrek poll. Kullanıcı aktif oturumda her 10 saniye, offline ise her 10 dakika.
Long polling. Client request’i open bırakır, server değişiklik olduğunda cevap veriyor. Real-time deneyim, polling’in sadeliği ile.
Long polling webhook’un alternatifi gibi, ama client-initiated – NAT / firewall problem yok.
GraphQL subscriptions, SSE, WebSocket
Diğer iletişim mekanizmaları:
Server-Sent Events (SSE). Server tek yönlü push, long-lived HTTP connection. Browser native, polyfill yok.
WebSocket. Bidirectional, low-latency. Chat, game, collaborative editor gibi use case’ler için.
GraphQL subscriptions. Subscription spec’i ile websocket üzerinde event stream.
Bunlar webhook/polling’den daha uygun olabilir eğer:
– Client sürekli open connection tutabiliyor
– Bidirectional iletişim gerekli
– Browser’dan direkt server’a konuşuyor
Server-to-server backend entegrasyonlarda genelde webhook daha uygun.
Son tavsiye
“Webhook mı polling mi?” sorusunu “hangisi?” olarak değil, “nasıl kombine?” olarak sorun.
- Real-time için webhook
- Reliability için polling reconciliation
- Debugging için her ikisinin de log’u
- Monitoring için delivery dashboard
Tek sistem yerine iki sistemi paralel çalıştırmak başta karmaşık görünüyor, ama outage sırasında size çok şey kazandırıyor.