A Hook That Fires Twice – and How Not to Trigger an Infinite Loop When Saving a Post
Why This Is Dangerous This isn’t some edge case — it’s one of the most common reasons a “simple” post save suddenly hangs the admin. The problem is…

Action Hook since 1.5.0
Fires after a post is saved or updated
save_post runs after WordPress writes the post row. Use it for caches, sync, and derived data — and always guard against autosave, revisions, and infinite loops.
After wp_insert_post() commits. Fires for autosaves and revisions unless you skip them.
do_action( 'save_post', int $post_id, WP_Post $post, bool $update );$post_id int — Saved post ID.$post WP_Post — Post object after save.$update bool — True when updating an existing post.add_action( 'save_post', function( $post_id, $post ) {
if ( $post->post_type !== 'book' ) {
return;
}
delete_transient( 'book_list_' . $post_id );
}, 10, 2 );Flush a per-post transient when a book is saved.
add_action( 'save_post', function( $post_id, $post, $update ) {
if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) ) {
return;
}
if ( $update ) {
do_action( 'my_plugin_post_updated', $post_id );
}
}, 10, 3 );Skip autosaves/revisions and fire a custom event only on real updates.

Why This Is Dangerous This isn’t some edge case — it’s one of the most common reasons a “simple” post save suddenly hangs the admin. The problem is…
Once for the autosave/revision and once for the real post. Guard with wp_is_post_autosave() and wp_is_post_revision().
Not if it's synchronous — save_post runs inside the save request itself, so slow logic on a large database can lock tables and delay the editor's save response. Offload it to a queue or scheduled event (e.g. Action Scheduler or wp_schedule_single_event) instead.
Source: wp-includes/post.php
One session: this hook, then each related_hooks entry. Walk it and tell us what to change.
save_post → init
Practice the save_post WordPress action hook in our interactive sandbox — a VS Code-style editor with a step-by-step save_post tutorial, add_action exercises, and instant feedback. No local WordPress install required.