Hook “wp_trash_post” executing multiple time in case of bulk trash products

Custom (database) Queue

One way would be to create a custom database table, and write to it the product id, each time a product is trashed via the trashed_post hook.

Then you can bulk process the collected trashed product ids via e.g. wp-cron and the user will not be affected by that potentially heavy processing.

With a real cron (not wp-cron) you could better control the timing/frequency of the processing.

This approach should also work if the products are trashed e.g. via wp-cli.

Similarly one could remove a product id from the custom table (or flag it) when the untrashed_post hook is fired for products.

PHP Class and WP Hooks

One might also create a PHP class and use it to hook into trashed_post/untrashed_post and collect (e.g. via PHP queue object within the class) all product ids and then at a later hook, process all at once. The user might notice this for heavy processing or slow external API requests, unless it uses some async workarounds or in addition uses the custom database approach mentioned above.