Skip to content

Filter webhooks by event type in database query instead of memory #531

Description

@DeFiVC

Bug Description

The dispatchWebhook function in src/services/webhook-dispatcher.ts (lines 129-172) fetches ALL active webhooks from the database, then filters by event type in application code. This is inefficient and could be a performance issue at scale.

Location

src/services/webhook-dispatcher.ts lines 132-140

// Fetches ALL active webhooks
const activeWebhooks = await db
    .select()
    .from(webhooks)
    .where(eq(webhooks.active, true));

// Filters in memory
const listenersForEvent = activeWebhooks.filter((w) =>
    (w.events as string[]).includes(payload.event)
);

The Problem

  1. Every webhook dispatch queries ALL active webhooks, regardless of event type
  2. The filtering happens in JavaScript, not in the database
  3. If there are 100 webhooks but only 2 listen for "enrollment.created", we still fetch all 100
  4. The events column is a JSONB array, so we can use PostgreSQL's @> (contains) operator

Recommended Fix

Use PostgreSQL's JSONB containment operator to filter at the database level:

const listenersForEvent = await db
    .select()
    .from(webhooks)
    .where(
        and(
            eq(webhooks.active, true),
            sql`${webhooks.events} @> ${JSON.stringify([payload.event])}::jsonb`
        )
    );

This pushes the filtering to PostgreSQL, which can use a GIN index on the events column for efficient lookups.

Acceptance Criteria

  • Filter webhooks by event type in the database query
  • Consider adding a GIN index on the events column for performance
  • Verify that only webhooks listening for the specific event are queried

Severity

low - Performance optimization, not a functional bug. Impact increases with webhook count.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions