Updated October 2026 by Marius: rewritten for current WordPress and tested on WordPress 7.1. Originally published by Hardeep Asrani in 2014.
When you change the slug of a published post, WordPress remembers the old one in a _wp_old_slug custom field. Later, when someone visits the old URL and it would return a 404, the wp_old_slug_redirect() function finds the post that used to have that slug and sends a 301 redirect to its current URL.
Most of the time you want this, because it keeps old links and search rankings working. Turn it off only when old URLs really should stop resolving, for example after renaming something that should disappear, or when old slugs keep sending visitors to the wrong post. If you create a new post that reuses an old slug, you don’t need this at all: the redirect only fires on 404s, so the new post already wins.
Turn off old slug redirects
The redirect URL passes through the old_slug_redirect_url filter, and WordPress skips the redirect when the filter returns false:
add_filter( 'old_slug_redirect_url', '__return_false' );Code language: PHP (php)
Old URLs now return a normal 404 instead of redirecting.
Stop WordPress from saving old slugs
The filter above stops the redirects, but WordPress keeps saving old slugs every time you change one. To stop that as well, remove the function that saves them from posts and attachments:
remove_action( 'post_updated', 'wp_check_for_changed_slugs', 12 );
remove_action( 'attachment_updated', 'wp_check_for_changed_slugs', 12 );Code language: PHP (php)
The priority (12) has to match the one WordPress core uses, or remove_action() does nothing.
Delete the old slugs already stored
Old slugs saved so far stay in the database. Back up your database first, then delete them in one go. With WP-CLI:
wp eval "delete_post_meta_by_key( '_wp_old_slug' );"Code language: Bash (bash)
Without WP-CLI, add delete_post_meta_by_key( '_wp_old_slug' ); as a snippet, load any page once, then remove the snippet. Don’t leave it running on every request. delete_post_meta_by_key() is a core function, so this doesn’t depend on your table prefix the way the raw SQL in older tutorials does.
Where to add this code
Add the snippet with a code snippets plugin instead of your theme’s functions.php, so it survives theme updates and you can switch it off without FTP. This guide shows how with the free Code Snippets plugin. On my own sites I use WPCodeBox, which keeps snippets in a cloud library so the same snippet can go on several sites. (Marius)
Disclosure: the WPCodeBox link is an affiliate link. If you buy through it, I earn a commission at no extra cost to you.
