October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk5 min

Webhook Idempotency with Node.js: Key Facts for Redis and PostgreSQL

Use stable provider event IDs, atomic claims, and PostgreSQL uniqueness to keep webhook retries and concurrent deliveries from repeating database work.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To prevent duplicate webhook work in Node.js, use the provider’s stable event ID as an idempotency key, claim it atomically, and enforce durable uniqueness in PostgreSQL. Put the event claim and database changes in one transaction. Redis can speed up duplicate checks, but it should not be the only record if losing or expiring a key could cause the event to run again.

Why webhook idempotency matters

Webhook senders may deliver an event more than once. For example, your handler can finish its work but the response can be lost or delayed, leaving the sender uncertain whether to retry. Your service therefore needs to distinguish a new event from a repeat delivery, including when two copies arrive at nearly the same time.

As an Amazon Associate I earn from qualifying purchases.

Idempotency means that processing the same event again does not repeat its business effect. It does not mean ignoring every repeated HTTP request blindly: the handler must first establish that the event has already been claimed or completed according to your processing design.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose a stable, properly scoped key

After authenticating the request as the provider requires, extract its stable event or delivery identifier. A timestamp for the current delivery or a locally generated request ID is unsuitable: either can change on retry and make the same logical event appear new.

Scope the key to the event namespace. A composite key such as provider plus event ID may be sufficient; include a tenant or endpoint as well when IDs are only unique within those boundaries. This prevents unrelated event sources from colliding.

Pick the claim architecture

Design Strength Trade-off
Redis-only atomic claim A Redis SET with NX can claim a key atomically and an expiry can reclaim it later. Redis describes the NX flag as avoiding a check-then-insert race, even under concurrent requests: Redis: How to do data deduplication with Redis. Expiry, eviction, restart, or data loss can remove the only record and allow a repeat to be processed.
PostgreSQL unique constraint A unique or primary-key constraint, combined with INSERT ... ON CONFLICT DO NOTHING, is a durable, concurrency-safe gate. Every claim involves the database. Whether a Redis fast path is worth adding depends on traffic, latency needs, and the cost of operating another dependency.
Redis fast gate plus PostgreSQL backstop Redis can filter repeats quickly while PostgreSQL retains durable uniqueness. The additional layer does not replace the database constraint or the transaction that couples the claim to business changes.

Do not deduplicate with a separate SELECT followed by an INSERT. Two concurrent handlers can both read “not present” before either inserts. Let an atomic claim operation or the database uniqueness constraint decide which request wins.

Deduplicate webhooks in PostgreSQL from Node.js

For database-backed work, the durable event record and the business changes should commit together. The example below assumes a PostgreSQL client that exposes transaction control, a table with a unique key, and an authenticated event whose provider and ID have already been validated. Adapt the client calls and SQL types to your installed driver and schema.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const client = await pool.connect();

try {
  await client.query('BEGIN');

  const claim = await client.query(
    `INSERT INTO processed_webhook_events (provider, event_id)
     VALUES ($1, $2)
     ON CONFLICT (provider, event_id) DO NOTHING
     RETURNING event_id`,
    [provider, event.id]
  );

  if (claim.rowCount === 0) {
    await client.query('COMMIT');
    return { duplicate: true };
  }

  // Apply database-backed business changes using this transaction.
  await applyBusinessChanges(client, event);

  await client.query('COMMIT');
  return { duplicate: false };
} catch (error) {
  await client.query('ROLLBACK');
  throw error;
} finally {
  client.release();
}

The table needs a uniqueness rule matching the key scope—for example, a unique constraint on (provider, event_id), or on additional tenant or endpoint columns if required. Only the request whose insert returns a row should apply the database effects. If the insert conflicts, the transaction has established that the key already exists and no business changes should run for that delivery.

Because the claim and database changes are in the same transaction, a failure before commit rolls both back. A later provider retry can then attempt the event again. Once committed, a conflicting delivery is a confirmed duplicate and should receive a successful acknowledgement so the sender does not keep retrying completed work.

Use Redis as an optional fast layer

A Redis claim can reduce repeat work or database load, but its state is temporary compared with a durable PostgreSQL uniqueness constraint. Configure the TTL to cover the provider’s retry horizon plus realistic processing delay; the appropriate duration is provider-specific, not a universal number. Keep PostgreSQL’s unique constraint as the backstop if correctness depends on not applying the database effect twice.

Redis state can disappear through expiry, eviction, restart, or data loss. If Redis is used before the database transaction, treat a positive Redis result as a signal to verify the durable event state where necessary, and do not let Redis absence authorize unguarded business work. The PostgreSQL insert remains the authoritative claim for transactional database processing.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Redis’s official deduplication tutorial demonstrates the atomic command pattern, but its example uses Bun and Express; it is useful for understanding the Redis operation, not proof of a single production architecture for every Node.js service.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Protect effects outside the database

A PostgreSQL transaction cannot atomically commit an external API call, email, or message-broker publish. If the database commits but the remote call fails—or the remote system acts but its response is lost—the two systems can disagree about what happened.

  • Pass a downstream idempotency key when the external service supports one.
  • Use state-aware operations, such as upserts or guarded state transitions, where they fit the effect.
  • For message publication or other remote work, record enough state to recover and retry deliberately rather than assuming the database transaction covered the remote action.
  • Define how to investigate and resolve ambiguous outcomes, especially for payments or other consequential work.

For correctness-critical deduplication, use exact key checks such as Redis SET NX or PostgreSQL uniqueness. A bitset or Bloom-style filter can produce false positives, so it should not be the sole reason to discard an important event.

Set retention around retries and replay

Redis expiration should span the sender’s documented retry window and the processing delays your system reasonably expects. Keep durable PostgreSQL event IDs for the application’s manual replay and recovery window. Provider retry schedules, response deadlines, and replay policies vary, so check the specific provider’s current documentation before choosing retention or acknowledgement behavior.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Longer retention improves protection against old replays but increases the number of stored identifiers; shorter retention reduces storage but narrows the period in which a repeat is recognized. Choose the horizon based on actual provider behavior and your operational replay policy rather than treating a sample TTL as generally correct.

Operational checks before shipping

  • Verify that authentication happens before trusting the event ID.
  • Confirm the database uniqueness constraint matches the full event namespace.
  • Test simultaneous deliveries of the same event; exactly one should win the database claim.
  • Force a business-change failure and confirm the transaction rolls back, allowing a retry to claim the event.
  • Confirm a committed duplicate receives the provider-appropriate successful response.
  • Exercise Redis expiry or loss and verify PostgreSQL still prevents duplicate database effects.
  • Test external-effect failures and ambiguous responses with the downstream idempotency or recovery behavior you have chosen.

Provider-specific retry rules and response deadlines are not interchangeable. Verify them against the provider’s own documentation and the versions of the Node.js SDK and database client deployed in your service; implementation guides and tutorials illustrate patterns but do not establish provider requirements.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.