Skip to main content

Events vs Hooks — when to use which

They are not interchangeable, and one does not replace the other. (A common first question: "do we need hooks if we have on/off?" — yes.) Pick by a single rule:

  • "I want to react after something happened and I can't/shouldn't change it" → Event (pq.on(...)).
  • "I want to run before/around an operation and possibly change or block it" → Hook (pq.useHook(...)).
Events (on/off/once)Hooks (useHook)
PurposeObservationParticipation
Awaited?No — fan-out is non-blockingYes — awaited, in registration order
Can change the outcome?No — read-only payloadYes — mutate options/data, or veto by throwing
Inside the caller's transaction?NoBEFORE_ADD does when tx is used
On the hot path?Must never block itDeliberately part of the operation
Typical usemetrics, logging, dashboard live view, alertsenrich the outgoing data, enforce a tenant idempotencyKey, authorize/veto an add, enrich/skip before processing

Only hooks can do three things an event fundamentally cannot:

  1. Mutate the outgoing job (BEFORE_ADD).
  2. Abort/skip an operation by throwing (BEFORE_ADD / BEFORE_PROCESS).
  3. Be awaited, so the operation waits for them (and runs in the same transaction as the insert).

Rule of thumb restated: events are past-tense and passive; hooks are present-tense and active.