This post walks your through WordPress permalinks step-by-step and you'll know exactly what kind of permalink structure to choose for your blog
Continuing the quest for the best permalink structure, this post dives into the world of WordPress (WP) and explains how WordPress handles permalinks. We'll go through how WordPress directs user to a post, the WP performance of different permalinks and finally, how to change WordPress permalinks. This is a result of in-depth research about WordPress permalinks, that will reveal that there are more than one options for the best permalink structure, considering both performance and SEO
Introduction to Permalinks in WordPress
As we learned from the previous post, permalink is an URL that points to a individual web page on a website. Perma stands for permanent. Ironically, permalinks of the site can change over time if one changes the permalink settings.
But this is good news, as those who already have blogs are not doomed to stick with their permalinks if they want to change the structure for the better.
In WordPress, the default permalink structure is /?p=n (where N is a unique, numeric post id). This default link (/?p=n) is always ON. WP uses .htaccess rules to redirect the link to index.php and then looks for the correct target based on the permalink structure.
From any given link, WordPress will try to find the right page or post and redirect the user there with the current permalink. WP has to do a number of requests to it's database in order to find the right post or page.
Depending on the permalink structure this process can be very resource intensive and bad for performance, or it can be very fast. Thus, good permalink is important for blog optimization, in addition to effects for search engine optimization.
How WordPress Directs User to a Post
To understand how WordPress handles incoming (perma)link, let's check the whole process.
Note: This stuff is the under the hood stuff, stuff you don't necessarily need to even know, because it just works. However, this needs to be here in order to label a post about permalinks as definite guide.
This is my understanding and explanation based on the WordPress documentation. However, I am not a WP developer or a tester, so feel free to fill in the holes and comment if you think this is inaccurate or misleading.
- User enters or clicks an URL
- the URL consists of two parts (from WordPress point of view)
- the domain, e.g. http://zemalf.com, and
- the permalink, e.g. /1151//
- the URL consists of two parts (from WordPress point of view)
- (User is taken to, or remains in, the correct domain)
- (Possible redirection rules, e.g. 301 redirect, are applied to the link on web server side)
- WordPress starts processing the incoming request
- WordPress picks up the permalink and tries to find where the permalink points to
- From WordPress point of view the permalink looks like this:
- /<first>(/<2>/<3>/.../<n-1>/<last>/), with <2>-<n-1> + <last> being optional
- First task is to figure if the link points to a page, post, attachment, archive-page or something else
- If <first> is /?p=n, WP takes the user to a post, if not,
- WP takes the <first> and checks if it is numeric or text field, or a string (words)
- If <first> is numeric (a post ID or a year for example), WP assumes it is a post
- If <first> is a text field, WP assumes it's a page, but also checks if <first> is a post name
- In order to distinguish pages from posts, WP stores lots of data to the database to shorten the time to find the right page or post
- If the string doesn't match any page or post, WP tries to figure out if the string is category, tag or author.
- If WP identified that the permalink points to a page (or archive), it directs user to that page
- If WP identified that it's a post, WP looks at the <last> in order to find unique identifier to a post, either post ID or post name
- the <last> is the same as the <first> if no optional elements are in the permalink
- If the <last> (or the <first>) wasn't an unique identifier, post ID or post name, WP goes through the other fields (<n-1>-<2>) an looks for that unique element
- If no unique post is found, and the post didn't match any page, WP gives 404 error and the user is taken to 404 ("not found") page.
- If WP found the unique element, based on the data WP saves to it's database,
- User is redirected to the /?p=%post_id% page
- WP takes the current permalink of the post (based on the settings), and
- WP takes the user to the correct post with the current permalink
Source: Using Permalinks - WordPress.org
Not All Permalinks Are Equal for Performance
As you saw above, WordPress has to process quite a bit with any other permalink structure than /?p=n. For other permalink structures WP has to do a lot to find the post, for the others, much less. The performance issues get worse, the larger the blog grows. Keep this in mind when choosing the permalink setting for your blog.
With only %postname%, WordPress has to check if the linked URL is a page or not and then move on to posts. Since 2.0, WordPress identifies post name as unique element, and doesn't go through loads of trouble finding out if the words actually point to a folder, category, tag or author.
With permalinks starting with other text fields, %category%, %tag% or %author%, WordPress has to do a lot of work to identify the post and save tons of identification data on it's database in order to prepare for all the possible queries.
WP has to check if the string is a page, post name, category, tag or author before it can move on to look for the unique ID on the permalink.
Because of this...
Starting Permalinks with %category%, %tag% or %author% is strongly NOT recommended for performance reasons.
Permalink structure starting with numeric field, %post_id% or %year% for example, is immediately identified as a post. Permalink that has %post_id% at the beginning can be directed to the right post right away and otherwise, the unique identifier can be looked from the rest of the permalink.
With either post ID or postname is found, WP can take the user to the correct post. Thus, for best performance, the permalink must have an unique identifier, either %postname% or %post_id%, and the unique identifier should preferably be at the beginning or the end or the permalink.
With this knowledge, the best permalink structures for WordPress performance are (performance alone does not make permalink good, thus the best overall options are bolded for your convenience):
- /?p=n
- /%post_id%/
- /%post_id%/%postname%/
- /%year%(/%month%/%day%)/%postname%/
- /%postname%/
- /%postname%/%post_id%/
and the worst permalink structures for performance are:
- /%category%/***
- /%tag%/***
- /%author%/***
Yes, /%category%/ might be good for SEO (most will do better without it), but I think this quote says it all:
/me wishes that %category% was never allowed in the permalinks - WP tester
It would be great is this design "flaw" didn't exist in WordPress, but it does (unless fixed at some later version), so we'll live with it. Fortunately /%category%/%postname%/ is not very good permalink anyway (it's often too long and prevents re-organizing categories without major 301-redirect party), so the performance issue just seals that deal.
Source: WP tester discussion about the scaling problems & Using Permalinks - WordPress.org
How To Change Permalink Structure in WordPress
If you have a new blog, it is best to set permalink structure before you write a single post (and before that, delete that "Hello World" post).
If you already have a WordPress blog with posts in it, it is relatively easy to change permalink if you're not happy with your current one, but you have to do a bit of extra work (including repairing internal links and setting redirection rules to get everything 100% right)
In WordPress, the permalink structure is defined in (Dashboard >>) Settings >> Permalinks.

To change permalinks in WordPress, go to the Settings - Permalinks and set the permalink structure as you like. My choice is /%post_id%/%postname%/
You can choose from the default options, or define your own, customized permalink.
The best permalink for WordPress
Based on the information presented above, the best permalink combining both performance and SEO, is either
- /%postname%/, or
- /%post_id%/%postname%/
If you're unsure, pick /%postname%/, you can't go wrong with that. Other great options are
- /%year%/%month%/%day%/%postname%/
- /%year%/%month%/%postname%/
- and similar structures ending with %postname%
Using /%postname%/ alone is great for SEO, and good for performance, which makes it ideal for any blog. Make it even better by editing the post-specific permalinks manually (SEO slugs), e.g. this posts postname-URL would by default be "definite-guide-to-wordpress-permalinks", but I chose to edit it as "wordpress-permalinks".
/%post_id%/%postname%/ adds the unique ID in the beginning, enabling using that ID as part of short URL, e.g. this post can be found as http://zemalf.com/1152. The short URL using the post_id can be used even if post_id is not in the permalink, but I think it makes the short URL very logical with the full permalink which is awesome.
Nowadays, many blogs are not "logs" or "diaries" anymore, so feel free to drop the date from the permalink, however for a blog with lots of daily posts or otherwise date-related posts, like news blog, using /%year%/%month%/%day%/ is great option too. But like said, I would stay away from this if you don't post daily or you're content is not tied to any specific date.
Changing the permalink on an existing blog
When changing permalink structure on an existing blog, your old permalink should has either %post_id% or %postname%, you can change the permalink and WordPress will find the post, even with the old permalink.
I think this happens because WP stores data to it's Db to speed up the process of finding individual posts and pages, and %postname% or %post_id% anywhere in the permalink is enough to find the post and take the user to the page or current permalink of the post.
As the old permalink is processed to the new permalink inside WordPress, I'm not 100% sure if this is considered 301 redirect from search engine point of view, which would mean that the pages keep their rankings and links (even that the links will word as WP finds the post with the old permalink).
However, 301 redirect will help WordPress by pointing the incoming link to the correct permalink before WordPress needs to process it. And it's also an insurance for keeping the search engine rankings, so before changing your permalinks, make sure you have all the old links in a file, so you can work the rules in .htaccess or Redirection -plugin after the change.
If you have an established blog, think carefully if you want to change the permalink structure. I did it, because I was using /%category%/%postname%/ and the URLs were long and clumsy. This in addition to the performance issues made me switch to a better one.
Summary
Permalink is an URL that points to a individual web page on a website. Permalink is important for both the blog readers and search engine optimization. Choosing the best permalink from the beginning is important, but it can be changed later if needed.
- Always include /%postname%/ to (end of) the permalink, no matter the rest of the structure. Words in the URL make your permalinks SEO friendly as well as informative for your readers.
- Do not use /%category%/ (or /%tag%/) at the beginning of the permalink, because of the WordPress-specific performance issues. In fact, do not use it all, because it makes the URL clunky and long.
- If the blog has daily date-specific content, like news, include the date, otherwise don't include year, month or day.
For WordPress blogs, the best permalink structures are:
- /%postname%/
- /%post_id%/%postname%/
- /%year%/%month%/%day%/%postname%/
If you are unsure what to pick, choose /%postname%/.
Thanks for reading the guide, I hope this was helpful to you.
If you missed the previous post, where I covered permalinks in detail, looking at the most popular permalink structures by studying the permalinks of the top 100 blogs and evaluated SEO benefits of them, you can find it here.
Antti Kokkonen
Mr.T of WordPress Permalinks