I just realised that in wp-includes/post.php (source), at the end of wp_insert_post(), both the save_post and wp_insert_post actions are called one after the other, with the exact same parameters:

3520  /**
3521   * Fires once a post has been saved.
3522   *
3523   * @since 1.5.0
3524   *
3525   * @param int     $post_ID Post ID.
3526   * @param WP_Post $post    Post object.
3527   * @param bool    $update  Whether this is an existing post being updated or not.
3528   */
3529  do_action( 'save_post', $post_ID, $post, $update );
3531  /**
3532   * Fires once a post has been saved.
3533   *
3534   * @since 2.0.0
3535   *
3536   * @param int     $post_ID Post ID.
3537   * @param WP_Post $post    Post object.
3538   * @param bool    $update  Whether this is an existing post being updated or not.
3539   */
3540  do_action( 'wp_insert_post', $post_ID, $post, $update );

Nothing happens between them, so there appears to be no difference between using one or the other.

The same redundancy is repeated a little further down in wp_publish_post() (source), and the oldest tracked version of the file also has the same two actions (thanks toscho for pointing these out).

Am I missing something? Why are they both there, and if I am choosing an action to use, is there a reason to choose one over the other?

  • Weird. Seems to be impossible to find anything on trac or in the repo. The oldest tracked version of that file had these actions already.
    – fuxia
    Jun 26, 2016 at 21:31
  • Must be a matter of meaning, did you check the amount of occurrences ? I mean is there only one place for both in core files ?
    – JMau
    Jun 26, 2016 at 22:45
  • Perhaps wp_insert_post was added later as a way to make hook names within functions guessable?
    – GaryJ
    Jun 26, 2016 at 23:18
  • @JMau Both action are only called in one other place: wp_publish_post(). And there, the same redundancy exists.
    – fuxia
    Jun 26, 2016 at 23:31
  • @toscho I've added both your comments to the post.
    – Tim Malone
    Jun 26, 2016 at 23:36

1 Answer 1


wp_insert_post was introduced in changeset 2887, and was to fix bug #1681. I couldn't find the save_post hook's original provenance, but it was most recently added to core in changeset 3291, related to ticket #2063. Evidently it had existed in 1.5.2 (although version control does not support this theory) and needed to be added back for back-compat.

So apparently, save_post was added in 1.5.0, then somehow removed in the 2.0 development lifecycle, then wp_insert_post was later added in the 2.0 development lifecycle, and finally, save_post was added back even later in the 2.0 lifecycle so as not to break back-compat.

And rather than being the deprecated hook you'd expect such a hook to be if that's true, it became the de facto default hook that developers use.

  • 1
    Great finds, thanks John! I guess we can summarise: a hook was accidentally removed; not realising that, a new hook was added where one was missing; the previous hook was then re-added for back-compat. Because the hooks are only in use in one other place and are used together there too, with no difference between them, and there's little chance either will be removed now, it simply doesn't matter which one we choose.
    – Tim Malone
    Jun 27, 2016 at 19:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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