Check for update vs new post on save_post action

Is it possible within the save_post action to determine whether it’s a new post being created or an existing post being update?


Since WordPress version 3.7. – IIRC – the save_post hook – more information about the hook and its usage at Code Reference: save_post and Codex: save_post – has a third parameter $update which can be used to determine just that.

@param     int               $post_ID     Post ID.
@param     WP_Post     $post          Post object.
@param     bool            $update     Whether this is an existing post being updated or not.


$update is not always true – you can see and test it yourself with below code. It is not well documented though, possibly far from optimally named, and hence creates misleading expectations. Below code can be used for some debugging, play around with when to intercept code execution, because otherwise you won’t see the information/messages. I think, the culprit in deceptive behavior is the handling of revisions and auto saves – which could be disabled, but I don’t recommend it, and haven’t tested it. Not sure if this warrants a Trac Ticket, so I didn’t open one, if you think so, please follow the link and do it yourself. Aside from that, as stated in the comments, if you have a specific problem, post a new question.

add_action( 'save_post', 'debug_save_post_update', 10, 3 );
function debug_save_post_update( $ID, $post, $update ) {

  echo '<pre>';
  print_r( $post ); echo '<br>';
  echo '$update == ';
  echo $update ? 'true' : 'false';

  if( ! $update && $post->post_status == "auto-draft" ) {
    // applies to new post
    echo ' && $post->post_status == "auto-draft"';
  } else if ( ! $update ) {
    // applies basically to the (auto saved) revision 
  } else {
    // applies to updating a published post
    // when there is a revision, which is normally the case, 
    // standard behavior of WordPress, then it is considered 
    // an update, which is where the confusion sets in
    // there are other methods, like checking time or post status
    // depending on your use case it might be more appropriate 
    // to use one of those alternatives 

  echo '</pre>';

Leave a Comment