I was stuck on a problem this week that necessitated changing a site's permalink structure. Initially, we were using the "Day and Name" format - [cci]/2014/11/16/some-cool-post[/cci], for example. We wanted to remove some, or at least part, of the date from the permalink. Unfortunately I'm not as up-to-speed with the performance of various permastructs in WordPress right now.

So I turned to Twitter:

https://twitter.com/EricMann/status/537329833739825153

Even more unfortunate, no one seemed able to help me. So I had to run a few tests.

Methodology

WordPress does all of the conversion from URLs to parameters for [cci]WP_Query[/cci] in the [cci]parse_request()[/cci] method of the global [cci]wp[/cci] object.

Conveniently, this method uses a hook both at the beginning of its execution (to determine whether or not to parse the request) and at the end (to invoke action handlers when the request is parsed). I simply chose to create a timer at the beginning of the function's execution and check the value of that timer against the current system time when the function is complete.

For precision, I decided to use PHP's [cci]microtime()[/cci] function so we can drill down to the microsecond.

I ran my code on a single article, using the same article on each iteration to verify that nothing else changed. I ran the test 10 times for each permalink option and averaged the time reported by each run. The results were ... unexpected.[ref]I ran this on a clean install of WordPress running in a virtual machine. There is always a chance, though, that some part of my system configuration is causing faulty readings, so I encourage you to re-run my tests so we can verify things independently.[/ref]

Results

On the surface, it seems that the "Post Name" option, once the least performant permalink option, is apparently the fastest.

The average of 10 loads of a single article using the various permalink options are:

  • Default: 1.326ms
  • Day and Name: 2.016ms
  • Month and Name: 1.784ms
  • Numeric: 2.194ms
  • Post Name: 0.994ms

My objective with this experiment was merely to prove that switching from a "Day and Name" URL format to a "Post Name" format wouldn't cause lower performance on the site. The numbers above definitely give me the confidence I need to advocate for a "Post Name" format on projects.

The said, it also raises a few questions: mostly, why are statistics like this not created more frequently?

We're so concerned about performance that we advocate offloading scripts and styles to CDNs, installing reverse-proxy caching, and migrating PHP applications to HHVM. Why aren't we concerned with monitoring the time involved in executing such basic functionality in the system so we can optimize?

[Update 10:30am]

A colleague asked me a quick question today regarding whether or not a large database would impact query performance. I can say for sure that a large database will result in slightly slower queries. Luckily the [cci]parse_request()[/cci] method depends primarily on RegEx, so the impact there is somewhat minimal.

That said, I did re-run my tests from above on a very large network site I have mirrored on my local machine. Keep in mind, the original tests was against a clean WordPress install with no plugins and the default theme. My second round of tests used the exact same methodology, but against an in-use WordPress installation with upwards of 30 plugins and a highly-custom theme built to run on WordPress.com VIP.

  • Default: 1.882ms
  • Day and Name: 6.002ms
  • Month and Name: 4.418ms
  • Numeric: 4.263ms
  • Post Name: 6.065ms

Keep in mind, this theme has several custom rewrites defined, which is why everything tends to be slower. But in the context of evaluating the performance of "Day and Name" versus "Post Name" performance, there's really not much of a difference.