Arsitektur3 Agustus 20268 mnt baca

Webhook vs Polling: Pilih Menurut Mode Kegagalan, Bukan Tren

Polling boros permintaan, tetapi gagalnya terkendali. Webhook efisien, tetapi gagal diam-diam. Plus pola hybrid yang dibangun kebanyakan integrasi serius.

POLLING · CELAHNYA TERTUTUP SENDIRIloop Andamati 3 jampoll berikutnyasince=cursorsinkron lagipemulihan tidak butuh kode yang belum Anda tulisWEBHOOK · CELAHNYA TIDAK TERLIHATprovider500s 3 jmencoba ulang, berhentitidak adatanpa error & kursortidak ada sinyaldi mana punketiadaan data terlihat persis seperti ketiadaan aktivitas
Perbandingan yang penting bukan jumlah permintaan per jam. Yang penting adalah apa yang ditinggalkan masing-masing model saat gagal.

Anggapan yang umum adalah polling itu pendekatan naif, dan webhook adalah tahap berikutnya setelah Anda naik kelas. Ceritanya rapi, dan cerita itu cukup sering membawa tim ke arsitektur yang salah.

Pertanyaan yang berguna bukan mana yang lebih efisien. Webhook lebih efisien, dan selisihnya jauh. Pertanyaan yang berguna adalah apa yang dilakukan masing-masing saat rusak, karena sifat itulah yang akan Anda hadapi pukul 3 dini hari, dan keduanya hampir berlawanan persis.

TL;DR

  • Polling gagal dengan jelas dan bisa dipulihkan: Anda menyadarinya, dan poll berikutnya mengejar ketertinggalan
  • Webhook gagal diam-diam dan permanen: tidak ada error, event-nya hilang begitu saja
  • Webhook memaksa Anda membangun infrastruktur yang didapat gratis dengan polling: percobaan ulang (retry), deduplikasi, urutan, dan verifikasi tanda tangan (signature)
  • Sebagian besar integrasi production akhirnya hybrid: webhook untuk latensi, poll rekonsiliasi untuk ketepatan
  • Jika Anda hanya bisa membangun satu, dan ketepatan lebih penting daripada latensi, pakai polling

Perbandingan yang biasa disajikan

PollingWebhook
LatensiInterval Anda, rata-rata setengahnyaHampir real-time
Permintaan yang terbuangSebagian besarTidak ada
Siapa yang menanggung biayaAndaPengirim
Butuh endpoint publikTidakYa
UrutanAnda yang mengendalikanTidak dijamin
PenyiapanSatu panggilan HTTP dan sebuah loopEndpoint, TLS, verifikasi tanda tangan, deduplikasi, percobaan ulang

Baca tabel itu, dan webhook menang di baris yang biasanya diprioritaskan orang. Itulah sebabnya begitu banyak tim beralih, merilisnya, lalu diam-diam kehilangan event selama dua bulan.

Perbandingan yang sebenarnya menentukan

Tanyakan ini sebagai gantinya: saat sistem ini rusak, bagaimana saya mengetahuinya?

Polling memburuk dengan cara yang langsung kelihatan. Server Anda mati, jadi loop-nya tidak berjalan. Saat server hidup kembali, poll berikutnya bertanya “apa yang berubah sejak cursor terakhir saya” dan mendapatkan semuanya. Pemulihan berjalan otomatis dan tidak butuh kode yang belum Anda tulis. Jika API-nya mati, poll Anda mengembalikan 500 dan Anda langsung melihatnya di tingkat error Anda sendiri. Model pull berarti Anda selalu tahu posisi terakhir Anda yang diketahui benar, dan satu sifat itu saja sangat berharga.

Webhook gagal dengan cara yang tidak terlihat dari sisi Anda. Endpoint Anda mengembalikan 500 selama enam jam akibat deploy yang buruk. Provider mencoba ulang, menyerah, lalu beralih ke hal lain. Log Anda tidak menunjukkan apa pun yang aneh, karena Anda tidak bisa mencatat permintaan yang tidak pernah Anda terima. Tidak ada cursor, tidak ada pendeteksi celah, tidak ada angka “saya tertinggal 400 event” di mana pun dalam sistem Anda. Tidak adanya data terlihat persis sama dengan tidak adanya aktivitas, dan pada hari Minggu yang sepi Anda tidak bisa membedakan keduanya.

POLLING · CELAHNYA TERTUTUP SENDIRIloop Andamati 3 jampoll berikutnyasince=cursorsinkron lagipemulihan tidak butuh kode yang belum Anda tulisWEBHOOK · CELAHNYA TIDAK TERLIHATprovider500s 3 jmencoba ulang, berhentitidak adatanpa error & kursortidak ada sinyaldi mana punketiadaan data terlihat persis seperti ketiadaan aktivitas

Asimetri itulah yang seharusnya menentukan. Kasus terburuk polling adalah data basi yang nanti akan terkejar. Kasus terburuk webhook adalah data hilang yang tidak akan pernah Anda ketahui.

Biaya turunannya mengikuti dari situ. Dengan webhook, logika percobaan ulang kini menjadi urusan Anda, karena jendela waktu provider terbatas dan provider yang paling longgar pun menyerah setelah tiga hari. Idempotensi menjadi urusan Anda, karena pengiriman setidaknya sekali (at-least-once) membuat duplikat pasti terjadi. Penjaga urutan menjadi urusan Anda, karena percobaan ulang memungkinkan event #2 menyalip event #1. Verifikasi tanda tangan menjadi urusan Anda, karena endpoint Anda publik dan siapa pun bisa mengirim POST ke sana. Dan endpoint HTTPS publik yang selalu hidup menjadi urusan Anda, sebuah syarat ketersediaan yang berbeda dari “aplikasi kami biasanya hidup.”

Satu per satu, tidak ada yang sulit. Bersama-sama, semua itu adalah alasan “pakai webhook saja” berubah menjadi proyek dua minggu yang belum selesai saat Anda mengira sudah selesai.

Kapan polling memang jawaban yang tepat

Jangan sampai argumen efisiensi membuat Anda melewatkan kasus berikut.

Yang paling jelas adalah latensi yang tidak Anda butuhkan. Sinkronisasi akuntansi setiap malam, rekonsiliasi inventaris, job pengayaan data CRM: jika tidak ada yang menyadari keterlambatan 5 menit, Anda membayar kerumitan nyata untuk sifat yang tidak bernilai bagi siapa pun.

Lalu ada kasus ketika tidak ada tempat untuk menerima. Aplikasi desktop, tool internal di balik VPN, job yang berjalan di laptop seseorang. Menyalurkan webhook ke localhost lewat tunnel adalah teknik pengembangan, bukan arsitektur production, dan kami sudah menulis di mana batasnya dalam Mengapa ngrok Saja Tidak Cukup.

Kasus yang paling sering disalahpahami tim adalah ketika ketepatan lebih penting daripada latensi dan tenggatnya tinggal seminggu. Poll berbasis cursor yang bisa Anda pahami lebih baik daripada pipeline webhook yang baru setengah jadi.

Volume rendah condong ke arah yang sama. Poll setiap 5 menit berarti 288 permintaan sehari, jumlah yang tidak akan disadari rate limit mana pun, dan kesederhanaan operasionalnya Anda dapat gratis. Begitu juga provider yang webhook-nya sendiri tidak stabil: jika pengirimannya tidak andal dan log event-nya minim, melakukan polling ke API mereka lebih dapat dipercaya daripada mengandalkan pengirim mereka.

Kapan webhook sepadan dengan kerumitannya

Webhook sepadan ketika ada manusia yang menunggu. Konfirmasi pembayaran, status deploy, pesan chat. Latensi sub-detik penting di sini, dan polling yang cukup cepat untuk menirunya berarti membombardir API.

Webhook juga unggul ketika event jarang terjadi dan tidak bisa diprediksi. Melakukan polling untuk sesuatu yang terjadi dua kali sehari berarti kira-kira 99,9% permintaan Anda tidak mengembalikan apa pun, dan untuk kasus seperti itulah webhook dirancang. Di ekstrem yang lain, volume bisa membuat polling sama sekali tidak mungkin: sepuluh ribu toko yang masing-masing butuh data sesegar 30 detik berarti 28,8 juta permintaan sehari, dan Anda akan terkena rate limit jauh sebelum sampai ke angka itu.

Kasus terakhir adalah job yang berjalan lama. Transcode video, inferensi model, ekspor batch. Provider tahu kapan job selesai sementara Anda hanya bisa menebak, itulah sebabnya API AI dan media sangat mendorong webhook. Lihat Webhook untuk Agen AI.

Hybrid, yang toh akan Anda bangun juga

Hampir setiap integrasi yang matang berakhir di sini, dan tiba di sini dengan sengaja lebih murah daripada tiba setelah insiden. Webhook menangani latensi; poll rekonsiliasi berkala menangani ketepatan.

// Fast path: webhook, near-real-time
export async function POST(req: Request) {
  const event = await verify(req);
  await upsertEvent(event);           // idempotent by provider event id
  return new Response(null, { status: 200 });
}

// Safety net: every 15 minutes, ask what we should have
async function reconcile() {
  const now = new Date();             // before listing, so nothing updated mid-sweep is skipped
  const since = await getLastReconciledAt();
  for await (const obj of provider.list({ updated_since: since })) {
    await upsertEvent(obj);           // same idempotent path, no-op if webhook won
  }
  await setLastReconciledAt(now);
}

Job rekonsiliasi hanya membebani Anda satu fungsi terjadwal dan memakai ulang kode yang sudah Anda tulis. Sebagai gantinya, job itu mengubah sifat terburuk webhook, kehilangan permanen yang diam-diam, menjadi “paling lama basi 15 menit.” Itu risiko yang sama sekali berbeda. Kasus terburuknya bahkan bukan pembayaran yang terlewat, yang lambat laun akan disadari seseorang, melainkan access.revoked yang terlewat, yang tidak disadari siapa pun.

Syarat agar ini berhasil adalah kedua jalur melewati fungsi tulis idempoten yang sama. Jika webhook sudah menanganinya, rekonsiliasi tidak melakukan apa-apa. Jika belum, rekonsiliasi memperbaikinya. Ini hanya berlaku jika Anda melakukan deduplikasi berdasarkan ID event dari provider, bukan berdasarkan waktu kedatangan versi Anda sendiri. Polanya ada di Anda Menerima Webhook yang Sama Dua Kali.

Lalu ukur tumpang tindihnya. Hitung seberapa sering rekonsiliasi menemukan sesuatu yang tidak ditangkap webhook. Angka itu adalah tingkat kehilangan yang sebenarnya dari pipeline webhook Anda, dan satu-satunya ukuran jujur yang akan pernah Anda dapatkan. Jika angkanya nol selama sebulan, webhook Anda sehat. Jika angkanya melonjak, Anda sedang mengalami gangguan yang tanpa angka ini tidak akan pernah terdeteksi.

Jalan tengah yang sering dilupakan

Polling tidak harus naif.

Polling berbasis cursor, yaitu ?since=<cursor> alih-alih “ambil semuanya lalu bandingkan”, jauh lebih murah dan tidak pernah melewatkan satu item pun, karena cursor hanya maju setelah pemrosesan berhasil.

Permintaan bersyarat, If-None-Match dengan ETag atau If-Modified-Since, mengembalikan 304 tanpa body. Banyak provider tidak menghitungnya ke dalam rate limit Anda. Anda bisa melakukan polling secara agresif dengan biaya sangat kecil.

Long polling memberi Anda latensi seperti webhook dengan pemulihan ala model pull. Fitur ini lebih jarang, tetapi jika tersedia, sering kali inilah yang terbaik dari keduanya.

Jika Anda menolak polling karena biaya mengambil semuanya pada interval tetap, mungkin Anda membandingkannya dengan versi polling yang terburuk.

Peran AnyHook

Webhook gagal diam-diam karena tidak ada yang mencatat apa yang seharusnya tiba. AnyHook adalah catatan itu.

Provider mengirim POST ke in.anyhook.net/you/app. Setiap event disimpan secara persisten sebelum pengiriman dicoba, sehingga:

  • Celahnya menjadi terlihat. Kegagalan pengiriman dihitung, ditampilkan, dan memicu peringatan pada 1, 5, dan 20 kegagalan berturut-turut, sehingga “diam-diam” tidak lagi tepat
  • Pemulihan berarti putar ulang (replay), bukan job rekonsiliasi. Pilih rentang waktu saat server Anda mati, lalu putar ulang event-nya dari log. Memutar ulang event yang gagal tidak mengurangi kuota bulanan Anda, meskipun ada batas harian dan memakai jatah komputasi (compute allowance) Anda
  • Kami yang membayar pajak infrastrukturnya, sekali untuk semua: percobaan ulang dengan backoff eksponensial, log yang persisten, dan satu header AnyHook-Signature alih-alih skema verifikasi untuk setiap provider

Ini tidak menghapus alasan untuk tetap memakai poll rekonsiliasi. Jika provider tidak pernah mengirim event itu, tidak ada relay yang bisa memunculkannya. Namun mode kegagalannya menyusut dari “diam-diam dan permanen” menjadi “tercatat, memicu peringatan, dan dapat diputar ulang”, dan itulah sebagian besar yang tadinya Anda dapat dari pola hybrid.

Untuk melihatnya sebelum mendaftar apa pun, satu perintah mengembalikan URL masuk (inbound URL) yang aktif, tanpa akun:

curl -X POST https://anyhook.net/api/v1/quickstart

Responsnya berisi inbound_url untuk Anda berikan ke provider, api_key untuk membaca log event lewat API, dan claim_url. Endpoint ini sementara: endpoint dan event-nya dihapus setelah 7 hari kecuali Anda membuka URL klaim itu lalu masuk, dan URL-nya tetap sama.

Kesimpulan

Pilih berdasarkan mode kegagalan. Polling terlambat tetapi memulihkan dirinya sendiri; webhook cepat tetapi kehilangan data tanpa suara. Jika latensi tidak berpengaruh pada manusia atau rate limit, polling bukan pilihan pemula, melainkan pilihan dengan kasus terburuk yang lebih baik. Dan jika Anda menjalankan webhook di production, tambahkan poll rekonsiliasi sebelum Anda membutuhkannya, karena metrik yang dihasilkannya adalah satu-satunya cara untuk mengetahui berapa banyak event yang sebenarnya hilang.

Semua artikel3 Agustus 2026 · 8 mnt

Berhenti kehilangan webhook.

Ganti satu URL. Dapatkan percobaan ulang, log event, dan putar ulang sekali klik. Atau lihat dulu: daftar dan jalankan latihan gangguan 30 detik, lalu saksikan event tetap selamat saat server Anda mati. Tidak perlu server.