posthog-js-lite icon indicating copy to clipboard operation
posthog-js-lite copied to clipboard

Events lost when submitting multiple events and using `flushAt: 1, flushInterval: 0`

Open freeatnet opened this issue 3 months ago • 6 comments

Bug description

posthog-node running in a Next.js app router app configured with flushAt: 1, flushInterval: 0 as recommended seems to lose events that are issued in batches.

We have a Next.js 14.2.3 App Router app that includes a batch job (invoked via an API request) that pulls a list of PostHog events and possibly distributes rewards points to users based on those events. The general form of the batch job is attached in additional context below.

When run with slightly non-trivial amounts of data (e.g., 50-100 input events), posthog-node seems only to submit some of them, as indicated by the data visible on posthog.com and message list passed to posthog.on('flush', (...args) => { console.log('PostHog flush', ...args); }).

The issue can be worked around by creating a custom instance of posthog-node with no flushAt: 1, flushInterval: 0 parameters.

How to reproduce

This is probably the bare minimum information for a reproduction — please let me know if you need a sample repo.

  1. Create a Next.js 14.2 app router app, configure a posthog instance with recommended parameters, and set up a batch job that captures a number of events while processing input in a loop.
  2. Set up instrumentation to catch capture, flush, and error events emitted by the posthog instance.
  3. Run the batch job.
  4. Verify that no errors occurred and there are no additional console output (e.g., no "queue is full" messages).

Expected: All events that have triggered a capture event also appear in the flush event, and all events are visible in PostHog. Observed: Some captured events are not submitted to PostHog and don't appear in flush event logs.

Related sub-libraries

  • [ ] All of them
  • [ ] posthog-web
  • [x] posthog-node 4.0.1
  • [ ] posthog-react-native

Additional context

Sample batch job flow

export async function distributeWelcomeBonuses() {
  const { results } = await queryPostHog(
    HOGQL_QUERY,
    { now: new Date().toISOString() },
    RESULTS_SCHEMA,
    {
      host: env.NEXT_PUBLIC_POSTHOG_HOST,
      projectId: env.POSTHOG_PROJECT_ID,
      apiKey: env.POSTHOG_READ_API_KEY,
    },
  );

  for (const row of results) {
    const { userId, triggerEventKey } = row;

    const shouldReward = Math.random() < 0.8; // some logic

    if (shouldReward) {
      // insert a reward transaction into the database
      await createEarnPointsTransaction(dbClient, {
        userId: userId,
        amount: REWARD_AMOUNT,
        reason: POINTS_AWARDED_REASON,
        internalNote: `${triggerEventKey.event} - ${env.NEXT_PUBLIC_POSTHOG_HOST}/project/${env.POSTHOG_PROJECT_ID}/events/${triggerEventKey.uuid}/${triggerEventKey.timestamp}`,
        eventKey: triggerEventKey,
      });


      posthog.capture({
        distinctId: userId.toString(),
        event: POINTS_AWARDED_EVENT,
        properties: {
          reward_reason: POINTS_AWARDED_REASON,
          reward_amount: REWARD_AMOUNT,
          reward_trigger_event: triggerEventKey,
        },
      });
    }
  }

  await posthog.flush();
}

Thank you for your bug report – we love squashing them!

freeatnet avatar May 19 '24 09:05 freeatnet