I have two actions that run when a post is updated. The issue is, the second function runs before the first has completed.

add_action('save_post', 'postUpdate', 10);

add_action('post_updated', ‘deleteCacheOnCloudfront ’, 1000, 3);

What is the best method to allow the first function to finish before the second action starts? Is there another hook that starts much later? In the meantime, I have set a one time cron to activate 5 seconds later, which I don't think is an elegant solution.



Note that the third input argument for the save_post callback, tells us whether it's an update or not. That could be helpful here, I think.

Taking your example as is, one suggestion could be:

add_action( 'save_post', function(  $post_ID, $post, $update ) {

   postUpdate( $post_ID );

   if ( $update ) {
       deleteCacheOnCloudfront( $post_ID, $post, $update );

}, 10, 3 );

to run the deleteCacheOnCloudfront() function after the postUpdate() function on post updates only.

The save_post is a very general hook and there exists more specific ones, like save_post_{post_type} or other based on post status transitions, if you want to avoid running your code when .it doesn't need to.

The postUpdate() function name is very general, so you should consider using a namespace or a function prefix, to avoid possible name collisions.

Hopefully the deleteCacheOnCloudfront() runs quickly (short timeout) and will not let the user wait too long during each post save.

Hope it helps!


If deleteCacheOnCloudfront() depends on $post_before and $post_after we can consider:

 * Run postUpdate() on save_post with priority 10.
add_action( 'save_post', function(  $post_ID, $post, $update ) {
   postUpdate( $post_ID );
}, 10, 3 );

 * Run deleteCacheOnCloudfront() on save_post with priority 11 when post is updated.
add_action( 'post_updated', function(  $post_ID, $post_before, $post_after ) {
    add_action( 'save_post', 
        function(  $post_ID, $post, $update ) use ( $post_before, $post_after ) {
            deleteCacheOnCloudfront( $post_ID, $post_before, $post_after );
        }, 11, 3 );
}, 10, 3 );

where we pass data from the parent scope with the use keyword and use different priority to make sure deleteCacheOnCloudfront() (priority 11) runs after postUpdate() (priority 10), within the save_post action.

We could also write this as a class instead, to move data across different hooks.

  • Thank you so much for your suggestion! I tried it with my setup, however, I realized I didn't get the results I needed. I actually use the arguments ($post_ID, $post_after, $post_before) that are available with the post_updated hook. I think I'll have to stick with the one time cron method.
    – Harv
    Feb 11 '19 at 21:45
  • @Harv I updated the answer with another approach. Hope it helps
    – birgire
    Feb 19 '19 at 9:26
  • Thanks @birgire, I'll give this a try. While testing, I also realized that post_updated action occurs before save_post.
    – Harv
    Feb 25 '19 at 2:00
  • yes, that was the reason for the "hook twisting" in my updated answer, making sure both run in correct order when save_post fires, but with data from the post_updated event available :-)
    – birgire
    Feb 25 '19 at 15:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.