Skip to content

Backgrounds

How-to Guides

Technical References

Fix performance issues by filtering wp_unique_post_slug

If you’ve noticed a function in a captured slow New Relic trace continually making SELECTs, you may need to help wp_unique_post_slug with a custom filter.

What you may be seeing is wp_unique_post_slug attempting to generate a unique post slug for a post type where the slug doesn’t really need to look like the title. (The slug is the string that’s often part of the URL).

The core WordPress function wp_unique_post_slug is meant to generate a unique slug for a newly published post and avoid conflicts when, for example, a headline gets reused. Ultimately what it does is tack a number on the end, for example, monthly-report-2 or photo-17.

However, it can become problematic when used with post types that are given default or similar slugs, such as attachments, because it iterates through the DB to find the next ID like uploaded-photo-2867.

This manifests in a New Relic trace as a series of SELECT queries on the post table. SELECT post_name FROM wp_posts WHERE post_name = ‘payment-error-1’ … with the number incrementing – and when there are 2867 matching entries in the table, this can seriously slow things down. This function is called during the post creation process but might also be called in the REST API under certain circumstances. It’s one explanation for slowness reported by editors at publishing time.

To avoid this behavior, when the content or format of the slug doesn’t matter, we suggest the snippet below, which will simply assign a unique ID and avoid any DB lookups. This takes advantage of a filter added in WP 5.3.

// generate a random, but not pretty, slug for a post type
add_filter( 'pre_wp_unique_post_slug', 'vip_set_log_slug', 10, 6 );

function vip_set_log_slug( $override, $slug, $post_ID, $post_status, $post_type, $post_parent ) {
    if ( 'wp_log' === $post_type ) {
        if ( $post_ID ) {
            return $post_ID;
        }
        return uniqid( $post_type . '-' );
    } 
    return $override;
}

The filter only modifies the slug behavior when the post type is wp_log. That is the custom post type used by a popular add on called WP_Logging which we’ve seen used for logging errors, especially for E-commerce.

The sample above can be easily modified for other custom post types, or, if your site editors frequently upload photos with generic titles such as “uploaded photo”, you may also want to use it for the attachment post type.

Last updated: August 29, 2021