Server Actions are not running intermittently

🌐

This post has been translated by DeepL . Please let us know if there are any mistranslations!

the problem

when I ran the following Mixpanel tracking code on the server side, events were only logged intermittently.

mixpanel.track(event, { distinct_id: userId, properties }, err => {
  if (err) {
    reject(err);
  } else {
    resolve("success");
  }
});

in the local environment, all events were logged correctly, but in the Vercel deployment, only some events were logged.

cause

before we look at the cause, let's understand Vercel Function. Vercel provides a feature called Vercel Functionfor environments deployed on Vercel.

The short description of Vercel Function is that all server-side code execution deployed on Vercel runs under Vercel's infrastructure environment, which means that it is FaaS.

FaaS stands for Function as a Service and is one of the ways to implement serverless computing. the idea is that the functions are the ones we use in our development, and we put them on a cloud service and call them only when we need them. in other words, FaaS allows us to write and execute functions without having to develop servers. Thanks to this feature of Vercel, we can use API Routes, SSR, etc. without having to set up a server.

✏️ Good to Know Vercel's serverless architecture is powered by Lambda on AWS.

the code that caused the problem was also set as a Server Action and executed on the server, and since Vercel is based on serverless, the code was registered as a serverless function.

however, serverless functions have the potential to terminate the process during execution, and in this case, the function could have terminated before the asynchronous task was completed, meaning that the callback functionwas not executed and the event was not sent correctly.

the workaround

we wrapped the code in a Promiseas shown below, and all events came in as expected.

return new Promise((resolve, reject) => {
    mixpanel.track(event, { distinct_id: userId, properties }, (err) => {
      if (err) {
        reject(err)
      } else {
        resolve('success')
      }
    })
  })

Why did we run the tracking code server-side?

so why didn't we run the tracking code like mixpanel.track on the client side?

  • data integrity: when sending events directly from the client, users may miss events due to browser settings (e.g. ad blockers) or network issues. running server-side reduces these external factors and allows for more reliable data collection.
  • integration with business logic: when tracking events are closely related to server-side logic (e.g., payment processing, user authentication, etc.), it is more natural and efficient to handle them directly on the server. for example, if you want to record an event after a payment is completed, it makes sense to check if the payment was successful on the server and then track it.
  • optimize performance: Handling tracking requests on the client can result in additional network calls, which can increase page load times. handling it server-side can reduce the burden on the client and improve the user experience.

for these reasons, you'll get more accurate and reliable metrics by running server-side rather than client-side whenever possible.

πŸ”Ž See also