I have seen many articles mentioning that a /%postname%/ permalink is the best for SEO. But what about a /%post_id%/%postname% structure, such as myblog.com/123/the-slug-of-my-blog ?

  • It doesn't seem to affect search engine rankings (Stack Exchange and many others use this structure)
  • You make each permalink unique, even with the same slug (preventing the dreaded appending of "-2" in the slug)
  • You can even use myblog.com/123 as a short-url, or an easy to say url in a podcast, etc (maybe you need a bit of code customization to achieve this)

Is there any known performance issue about this permalink structure?

  • Are you sure you avoid the "-2" in the slug? I'm pretty sure that by default, slug creation is unique in WordPress (but the DB does not require it). Commented Sep 4, 2019 at 9:33
  • To me this reads like a case of somebody totally overthinking something but maybe I am wrong. IMO most of the SEO stuff is BS anyway and with some basic caching you should nor case about micro optimizing PHP site generation at all. Commented Sep 4, 2019 at 18:10
  • I've not got a link to hand but I do recall reading an article where the author said that while /%postname% might look cleaner, WordPress has first figure out if that's a page, a category, a tag, or a post. I imagine that could take a little more time. The conclusion was anything that clues WP into what it is dealing with cuts down on searching. I've not looked into it any further so I've no data to give you. Commented Sep 4, 2019 at 22:33
  • @NextGenThemes my original question was not about performance, but a moderator changed to that for some reason.
    – Victor
    Commented Sep 7, 2019 at 12:47

4 Answers 4


Note: we're talking here about the difference between permalinks /%ID%/%name%/ and %/name/%. It would be a whole different story if we were to compare /%ID%/%name%/ and %/ID/%.

Now, there are two use cases that affect performance:

One. You have a permalink and WP needs to resolve it in order to serve the page requested.

This means setting up the WP class. The main function is at the bottom of the code. After init this involves calling parse_request. This checks whether rewrite rules exist for this particular page and checks query variables for validity. In this case we'd like to know whether processing example.com/123/slug takes more time than example.com/slug. For that to matter you would have to assume that the PHP string function that needs to handle a few bytes more has a significant impact on performance.

Once the requested url has been chopped into workable chunks, the action moves to parse_query, which in this case will be passed a query object either containing name or both name and ID (confusingly in the query object the ID is called p). A lot of handling is done, but nothing extra for including the ID in the query.

Next follow two hooks in (pre_get_posts and posts_selection) that are plugin territory, so impact on performance is unknown.

Now comes the main issue: will it take more time to query the database with one variable or with two? Both ID and name are stored in the wp_posts table in the database. So, there is no difference in the size of the table that will be queried. Also, both are unique, because when a post is stored this is checked (OP's assumption that including ID in the url will get rid of the -2 in posts is wrong, unless you hack the saving procedure). As a result, it doesn't really matter whether you have to query all database rows for the unique ID or the unique name. The only difference in performance when providing both is that after the row with the ID has been found it will check if the name matches. That really is negligible.

Two. You need to generate a permalink on a page.

This is done by the get_permalink function. For standard post types the procedure only adds some lengthy calculations if you are using %category%. For ID and name it is just a matter of search and replace in this line of code:

$permalink = home_url( str_replace( $rewritecode, $rewritereplace, $permalink ) );

The efficiency of str_replace depends on the size of the parameters that are passed to it, but since all possible rewriting parameters are passed, not just the one or two that are actually used, this does not affect performance.

For custom post types get_permalink refers to get_post_permalink, which involves more calculations anyway, but essentially winds down to the same search and replace.


Having tested on a super-slow shared hosting environment, the post_id/postname option was faster.

I suppose searching for the ID is somehow better indexed - not sure how it works "under the hood".

Didn't notice any "seo" penalties from having a number added before the post name - suppose there are some, but not that severe, with the content still carrying greater "weight".

My tests and the conclusions described at great length: https://io.bikegremlin.com/6768/permalink-change/

  • 2
    Good work! The reason for this being faster in large, slow databases would be that comparing two integers (ID's) is faster than comparing two possibly long strings (names)
    – cjbj
    Commented Sep 10, 2019 at 17:53
  • I don't know how WP DB works, but general knowledge of databases tells me that unique number as a (unique) key is very fast to do search with. Commented Sep 10, 2019 at 18:11

There shouldn't be any diffrents. I recommend you to use the ID version and you coold even make it prettier like /%postname%-id=%post_id%.


There is no peformance issue with the above permalink and I will say both are good . However /%postname%/ is used widely as it will help you generate better search results and it is also SEO friendly URL.

Getting better rank in SEO is the purpose of any website. Hence the /%postname%/ is most used and preffered permalink structure for all wordpress websites .

/%post_id%/%postname% is also a good option to use but in most of cases people try to get only post name after site on URL to get better results in SEO

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.