← Home
🏗Crack System Design with DSA AnimatorSystem DesignNEW
🏗 System Design›Networking & Realtime

🪝Webhook

Event-driven callback from one system to another over HTTP.

📌 Key IdeaA webhook lets a provider push event data to your callback URL in near real-time. Compared to polling, it is more efficient and lower latency, but requires strong handling for signature verification, idempotency, retries, and out-of-order delivery.
🧩

Problem it solves

  • Polling external systems repeatedly wastes network/compute and still introduces delay.
  • Near-real-time event updates (payments, status changes) are hard with pull-only integration.
  • Webhooks push events as they happen, reducing latency and unnecessary polling load.
📖

Definition

Webhook is a mechanism where system A sends an HTTP request (usually POST) to system B when a configured event occurs. You register a callback endpoint once, then events are delivered automatically.

✨

Why It Matters

  • Removes wasteful polling loops and reduces API/network cost.
  • Improves responsiveness for payment/order/subscription workflows.
  • Fits naturally into event-driven and async system design.
💻

Code Variations

1️⃣ Spring Boot webhook receiver (skeleton)java
@RestController
@RequestMapping("/webhook")
class WebhookController {
  private final WebhookService service;

  @PostMapping("/payment")
  ResponseEntity<String> handle(
      @RequestBody String payload,
      @RequestHeader("X-Signature") String signature,
      @RequestHeader("X-Event-Id") String eventId
  ) {
    service.verifySignatureOrThrow(payload, signature);
    service.processIdempotently(eventId, payload); // ignore duplicate eventId
    return ResponseEntity.ok("processed");
  }
}
Never trust raw payload without signature verification.
2️⃣ Idempotent processing patternjava
@Transactional
public void processIdempotently(String eventId, String payload) {
  if (processedEventRepo.existsById(eventId)) return; // duplicate delivery

  DomainEvent event = parse(payload);
  applyBusinessChange(event);
  processedEventRepo.save(new ProcessedEvent(eventId));
}
Most providers retry; duplicate deliveries are normal.
3️⃣ Recommended endpoint behaviortext
1) Authenticate request (signature/HMAC).
2) Validate schema + event version.
3) Store event idempotently.
4) Ack fast (2xx) and process async if heavy.
5) Track retries, DLQ, and alerting.
Fast acknowledgment avoids provider timeout retries.
📊

Webhook vs Polling

AspectWebhookPolling
Trigger modelEvent-driven pushTime-based pull
LatencyLow (near real-time)Depends on poll interval
EfficiencyHigh (only on event)Lower (many empty checks)
ComplexityMedium (security/retry/idempotency)Low to medium
Failure handlingMust handle retries/out-of-orderClient controls retry cadence
🧪

Variations / Implementations

Standard provider webhook flow

Register callback URL -> provider detects event -> provider POSTs payload + signature -> consumer verifies and processes.

Queue-backed webhook ingestion

Acknowledge request quickly (2xx) after validation and enqueue event for async processing. This improves reliability under spikes.

Signed webhook with replay protection

Use HMAC signature + timestamp + nonce/event-id. Reject invalid signatures and old timestamps to prevent tampering/replay.

⚠️

Common Mistakes / Anti-Patterns

  • Processing without verifying signature or timestamp.
  • Treating webhook delivery as exactly-once.
  • Long synchronous business logic before returning 2xx.
  • No event-id deduplication or idempotency key tracking.
  • Assuming events always arrive in order.
🎤

Interview Q&A

🔮

Likely Follow-up Questions

  • How do you version webhook payload contracts?
  • How do you observe webhook health (success rate, retry depth, processing lag)?
  • When do you add a dead-letter queue for failed events?
  • How do you reconcile missed events after outage?
🧾

Quick Cheat Sheet

Core ideaPush on event, not pull on interval.
SecurityHMAC signature + timestamp check + HTTPS.
ReliabilityIdempotent handlers + retries + DLQ.
Design ruleAck fast, process async when possible.
🔗

Related Topics