I'm trying to tune a wordpress website which suffers slow loading times, and I found out that the home page seems to take a lot more time to load. It's not due to content because I'm just considering the time it takes for the base request to end (viewable via firebug in firefox).

Also I tried copying the index.php code in a custom page, and the same exact code loads in about 1 sec while the main home loads in about 7. I noticed that single pages loaded faster, and at first I thought it was due to the difference in content, but after this test I'm not sure what's causing this.

Is there much stuff that wordpress does behind the scenes only for the main index? Is there any other way to explain this situation and, more importantly, fix it so that the home page loads faster?


After a lot of blind tries, I created a new page called home which uses index.php as custom template (not a copy, the same file). I redirected any call to the base path to it (via wordpress' internal rewrite) and I have the same homepage as before, just loaded in 1/6th of the time. While I'm happy with the result, I'd really like to understand what's going on.


So the point seems to be that I cannot use a dynamic (in wordpress' sense) page with this site, it only works fine with a custom "static" page where I insert content via various functions, the normal Loop makes the home either very slow (with high memory limit) or just blank (low memory limit, script fails).

As suggested in this question, I created a static home linked to a custom page and it works fine. I also created a blog page (again with a custom template) which also works fine (where "fine" means it shows my empty test page containing just one word and no code) unless I specify it as "Posts page" in admin -> Reading settings. In other words it looks like as soon as wordpress sees a dynamic page (the one that's supposed to hold The main Loop) it does something very heavy which eats up a lot of ram.

Still looking for the cause of this, I can work around it but I'd really like to understand what the problem is.

Edit: added bounty

More info: I tried disabling all plugins, wordpress is updated to the latest version.



KEY `type_status_date` (`post_type`,`post_status`(1),`post_date`,`ID`),
KEY `post_status_date_gmt` (`post_status`(1),`post_date_gmt`),
KEY `post_date` (`post_date`),
KEY `post_date_gmt` (`post_date_gmt`),
KEY `post_parent` (`post_parent`),
KEY `post_name` (`post_name`),
KEY `post_status` (`post_status`),
KEY `post_author` (`post_author`),
FULLTEXT KEY `post_related` (`post_name`,`post_content`),
FULLTEXT KEY `post_content` (`post_content`,`post_title`),


PRIMARY KEY  (`object_id`,`term_taxonomy_id`),
KEY `term_taxonomy_id` (`term_taxonomy_id`)


PRIMARY KEY  (`term_taxonomy_id`),
UNIQUE KEY `term_id_taxonomy` (`term_id`,`taxonomy`),
KEY `taxonomy` (`taxonomy`)
  • @kemp - Unless I'm missing it you haven't included a link that to home page so we can see it for ourselves. Can you do that? Nov 28, 2010 at 4:48
  • 1
    Also, please add these profiling tools to your site: wordpress.stackexchange.com/questions/1567/… so as to allow to view: http://example.com?debug=sql Nov 28, 2010 at 11:59
  • @Denis tried that, can't seem to get any output. I get a blank page and the occasional internal server error with this message in the log: Premature end of script headers: index.php Nov 28, 2010 at 12:58
  • @kemp did you delete the cache contents and retried the tests with 2 identical pages (dynamic / static) ?
    – edelwater
    Nov 28, 2010 at 14:52
  • Duh, I just noted that your URLs use a verbose permalink structure. What happens when you use one of the suggested date/name based structures, e.g. /YYYY/MM/slug/? Nov 28, 2010 at 16:55

5 Answers 5


I beg to differ with the previous two comments.

Using a static home page results in WP using an index scan on the posts table's primary key, vs an (oh so occasional) index scan on post_date, status or post_parent in the posts table.

In essence, the home page is dead slow because of the poor database design in WP. The schema has ludicrous multicolumn indexes on the taxonomy tables which MySQL simply ignores once you've a meaningful amount of posts. The fact that we're using a table too much for taxonomies doesn't help either.

In the database, safely add indexes on:

CREATE INDEX extra_posts ON posts (post_type,post_status,post_date DESC)
CREATE INDEX extra_term_rel ON term_relationships(term_taxonomy_id,object_id)
CREATE INDEX extra_term_tax ON term_taxonomy(taxonomy,term_taxonomy_id,term_id)

It won't be perfect, but at least WP will be able to use index-based nested loop plans on your front page...

Oh, and... if you're using any kind of custom post type on your front page, you also need to add:

posts(post_status,post_date DESC)

Else no index will be used at all for the main query because of the OR clauses.

  • @Denis can you please review the indexes? I updated the question as they wouldn't fit in a comment. Also, can 13.200 posts be considered just too many? What's also strange from my point of view is that the normal loop in categories pages work perfectly fine. Nov 28, 2010 at 10:31
  • 13200 rows is very few in a database unless they're poorly queried. My dev site with a couple of odd posts reads the whole disk page and quicksorts the result in no meaningful time. My live site, by contrast, has a bit over 1000 posts and php takes in the order of 50ms to retrieve the front page's posts. To put this in perspective, my PgSQL dev site pulls top-10 rows out of a few hundred thousands in 20ms... Nov 28, 2010 at 11:40
  • Re your current indexes: type_status_date is so wide that MySQL usually prefers to use post_status or post_date. post_status_date_gmt/post_date_gmt get used internally for very specific queries. Usually the first in my experience. post_parent/post_name are used when querying for hierarchical types; the first would benefit from having the post_type prepended in there to retrieve root pages quickly. post_author is useful for author pages, and in the admin area. For the front end's author pages, this would be more ideal: (post_author, post_type, post_status, post_date DESC). Nov 28, 2010 at 12:09
  • Continuing... term_tax (object_id,term_taxonomy_id) is good to get tags/cats/etc from posts. Last I checked, none of the other indexes on terms get used. My above-mentioned extra_term_tax allows to actually get the terms using an index, and extra_term_rel would allow to fetch posts that match a term. Nov 28, 2010 at 12:19
  • @Denis -- great answer here... I just wanted to ask you if your proposed solution to his problem is something you implement on your wordpress sites by default? Nov 29, 2010 at 17:43

By default there isn't any difference for performance of home page. There is however a possibility that some plugin does something slow on that page alone.

There are plenty plugins to profile WP performance. I usually use WP Tuner but it seems to be broken for latest WP version, so I have no immediate replacement to suggest.

Simplest way is packing template full of time/memory markers.

printf(  '%d queries in %.3f seconds, using %.2fMB memory', get_num_queries(), timer_stop( 0, 3 ), memory_get_peak_usage() / 1024 / 1024 );

It's crude but often allows to pinpoint location where slowdown occurs.

  • Rarst is right. You likely have a plugin or widget that is only running on the homepage and is doing long queries about something (like maybe checking for a category or something?)
    – jerclarke
    Sep 11, 2010 at 20:09
  • @Jeremy: but that doesn't explain why an exact copy of the home loads faster under another page name. Sep 11, 2010 at 21:11
  • @Rarst: thanks for the suggestion but I can't seem to get it working right. I see the report on the admin page but nothing on the regular ones. Might depend on the fact that wordpress is bridged with vbulletin and the plugin doesn't recognize me as a logged in admin Sep 11, 2010 at 21:12
  • 1
    It may be exact code of page's code but it's not exact copy of environment. Conditional tags are very basic WordPress code technique - home page and regular page can be identical in code, but conditional tags will return different values and so different code might fire on hooks. | Not working - you mean plugin or snippet?
    – Rarst
    Sep 11, 2010 at 21:25
  • 2
    Kemp: Try disabling all your plugins and see if the difference is still there. If its gone enable them one by one. Another way of testing this would be to install a brand new site with not plugins and run your theme on it, see if the home page still takes longer.
    – jerclarke
    Sep 12, 2010 at 14:20

After almost 4 years I got back on this and finally found the problem. Turns out the site had a lot of articles ALL marked as sticky. Due to the unbelievably dumb way wordpress uses to mark sticky posts (a serialized array in wp_options), the main loop of the dynamic home page took an incredibly long time. Clearing the sticky_posts field in the table fixed the problem.


If the home page is taking that long to load, most likely you have a plugin or a function in the theme that is making a remote request some time when the home page is rendering.

I would do a recursive search through your wp-content directory for calls to 'wp_remote_' to look for any functions that may be causing this.

  • It must be something that wordpress does before loading the template, because it's not due to the code of the page. Sep 12, 2010 at 7:46
  • 2
    The code might not be on the page itself, but functions like wp_head() call action hooks that plug-ins can use to call secondary functionality. That's why @prettyboymp suggested a search through the entire wp-content directory and why @Jeremy Clarke recommended disabling all plug-ins above.
    – EAMann
    Nov 27, 2010 at 17:04
  • Yes but the same exact page works fine called as "static", it hangs only when called as "dynamic". Nov 27, 2010 at 19:03

At first, check the quereis of WOrdPress and the included images, scripts and stylesheets. You can check the queries with the plugin Debug Queries and you become more information about your install and mistakes with the plugin Debug Objects.

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.