Make WordPress Core

Opened 13 years ago

Closed 13 years ago

Last modified 7 years ago

#10952 closed defect (bug) (invalid)

Wordpress checks for core/plugin/theme upgrades upon every hit to [almost] any admin page

Reported by: archon810's profile archon810 Owned by:
Milestone: Priority: normal
Severity: normal Version: 2.8.4
Component: Performance Keywords:
Focuses: Cc:


This seems insane to me. Diagnosing performance issues, I'm digging through the code with a profiler and seeing calls to http.php, specifically WP_Http_Curl::request() function taking the longest time.

After adding a few prints into that function, I found that the Wordpress API is getting called upon every single page load, for example the Comments page, Posts, Settings, etc.

Here are the calls, with duration added at the end. 0.13813519477844s 0.58831095695496s 0.34422087669373s 0.13466596603394s 0.5711510181427s 0.35010981559753s 0.1392650604248s 0.57304692268372s 0.41575598716736s

The crazy part here is that these 3 updates take over a second and are done EVERY SINGLE TIME, without any kind of rate limiting. I understand if they were done at most once an hour or only when the Plugins or Themes pages were hit, respectively but this is a huge overkill and performance monster.

Additionally, I don't understand why would want that many more hits to the API - I'm sure somebody on the team had to have noticed this before.

The only relevant ticket I found is #8590.

The fix should be rate-limiting, IMO. Thoughts please.

Attachments (1)

update-plugins.php (2.0 KB) - added by Denis-de-Bernardy 13 years ago.

Download all attachments as: .zip

Change History (23)

#1 @dd32
13 years ago

  • Keywords reporter-feedback added

These checks are rate limited to once every 12 hours.

These checks are performed in a seperate Cron thread, not the main thread (Except when visiting hte plugins page with a >1hr plugin result, or themes page with >1hr theme result, etc.)

Can you post the contents of the update_plugins option? Or transient_update_plugins perhaps (Not sure if transients are 2.8 or 2.9)

#2 @archon810
13 years ago

  • Cc admin@… added

I just stepped through a bunch of code and the problem seems to be that the calls to get_transient( 'update_themes' ); and the 2 other similar functions return FALSE, every time.

_maybe_update_themes( )
get_transient( 'update_themes' );
$pre is false
$_wp_using_ext_object_cache is true but I forced it to false to see where it's getting the data from
if ( !isset( $alloptions[$transient_option] ) ) is true because $transient_option
"_transient_update_themes" doesn't exist in $alloptions
Then $transient_timeout = "_transient_timeout_update_themes"
get_option($transient_timeout)is false
Then this block runs:

return false;

So, it looks like the option doesn't exist in my 2.8.4 and neither does it get created or stored. I'd be glad to provide more information.

#3 @dd32
13 years ago

if you step through the code some more, After the update check (Well, actually, Before AND after it in the update function) set_transient will be called. You might want to trace that function and see why its not storing it.

Are you using an Object cache? Does disabling that help?

#4 @archon810
13 years ago

I tried tracing it for a bit, turning off wp-super-cache and switch define('WP_CACHE', false); in the wp-config.php but still saw the same requests. I am not really sure what these transient values are all about as well as Object cache but I don't have the ability to look all over the code for this.

What I do see is get_transient always returns false. Then, only after that the set_transient is called. Can you be more specific with what to look for?

#5 @dd32
13 years ago

Object cache = A Caching functionality in WordPress to cache data rather than entire pages. Enabled by adding a file ini wp-content/object-cache.php

What i'm interested in finding out, And to solve your problem, is why get_transient() is returning false all the time, Is it because set_transient() isnt setting the option? Or is it because get_transient() isnt checking properly, etc.. Its impossible to say, Since as far as i'm aware, no-one else has had this issue..

#6 @archon810
13 years ago

get_transient() works fine after the set_transient() calls, just not before.

#7 @dd32
13 years ago

get_transient() should work on the next page load as well after a set_transient() call, as long as the cache timeout has not been exceeded.

#8 @archon810
13 years ago

Yup, but it doesn't. If you want, we can take it offline (IM, skype, VNC?)

#9 @dd32
13 years ago

$_wp_using_ext_object_cache is true but I forced it to false to see where it's getting the data from

..I missed that, Which is the problem.

Do you have a file 'object-cache.php' in your Wp-content directory?

Its set by this code in wp-settings.php:

if ( file_exists(WP_CONTENT_DIR . '/object-cache.php') ) {
	require_once (WP_CONTENT_DIR . '/object-cache.php');
	$_wp_using_ext_object_cache = true;
} else {
	require_once (ABSPATH . WPINC . '/cache.php');
	$_wp_using_ext_object_cache = false;

It sounds like your external object cache is malfunctioning..

wordpress@… if you'd like some offline help.

#10 @archon810
13 years ago

  • Severity changed from normal to major
  • Version changed from 2.8.4 to 2.8.5

I haven't been able to connect with you. Do you or anyone else wanting to nail this bug have some time as I'd like to resolve this?

I keep seeing these every time I load admin pages 0.12612009048462s 0.40104913711548s 0.33010601997375s 0.36449790000916s

This is still eating over a second of my time every time I'm in admin.

#11 @Denis-de-Bernardy
13 years ago

I had to fix this in a plugin of mine earlier this year. If memory serves, it was due to logic errors in the timeout related to the checked variable, or something like that. I'm attaching the code I'm currently using for plugin version checking, in case it helps.

#12 @archon810
13 years ago

  • Priority changed from normal to high
  • Version changed from 2.8.5 to 2.9.1

Since dd32 is too busy to help me diagnose the root cause of this bug, I'd like to raise the priority in hopes that someone else from the WP team can work with me to squash this.

I'm willing to commit any time needed to get this resolved, as long as someone who understands the ideas behind the internals can help a bit.

I'm a PHP programmer that debugs using a proper debugger, so this should really be quite painless to diagnose - I'm just missing knowledge about transient and other caches.

#13 @dd32
13 years ago

  • Version changed from 2.9.1 to 2.8.5

#14 @archon810
13 years ago

Still happening to me in 2.9.1. Why the change back, dd32?

#15 @nacin
13 years ago

  • Version changed from 2.8.5 to 2.8.4

archon810 -

Not sure you ever answered a question from above. Are you using an external object cache? Check for a file called "object-cache.php" in your wp-content directory. If you're running an object cache, rename the file to something else to temporarily turn off object-cache.php.

Also, have you also tried deactivating your plugins?

Version numbers are for when the problem was initially reported, which helps in narrowing down bugs. They shouldn't be bumped with each version tested thereafter.

#16 @archon810
13 years ago

@nacin, thanks, got it about the version reported.

Looks like the problem is indeed related to the object-cache.php file. I did discover it in wp-content, svn status'ed it, and it wasn't in the repo (that is obvious now).

I have a feeling a lot of people might still have this file on their servers and it would cause this bug to appear quite stealthily (most people wouldn't be able to trace it or figure out what is slow - they'll just think WP admin is slow), as a lot of people upgrade by overwriting their WP installation. Even though I update to new WP versions via svn switch, I guess somehow this file evaded being deleted.

What is the history here? Was this file there before and then was removed? In that case, is there merit to trying to detect it somewhere in the admin code and warn the user about it?

Thanks again.

#17 @nacin
13 years ago

  • Keywords reporter-feedback removed
  • Milestone Unassigned deleted
  • Priority changed from high to normal
  • Resolution set to invalid
  • Severity changed from major to normal
  • Status changed from new to closed

Object caching, the feature, was removed from core in 2.5 (I think). But wp-content/object-cache.php has never existed in core -- that file is a drop-in for an external object cache. Thus, if that file exists, then it is used and object caching is turned enabled. A similar drop-in scenario works for wp-content/db.php, as a way to replace the wpdb class.

Just to emphasize then, this isn't a bug or problem with WordPress. You just have a borked object-cache.php file.

#18 @archon810
13 years ago

You're right. The file was dated 2007. Found this in the comments. Son of a...

Name: eAccelerator for WordPress
Description: eAccelerator backend for the WP Object Cache.
Version: 0.6
Author: Computer Guru
Author URI:
* Install this file to /wp-content/object-cache.php
* If on Windows, restart IIS after installing for best results
Thanks to Ryan Boren for his original memcached code.

#19 follow-ups: @dd32
13 years ago

I would suggest another ticket raising the idea of having an alert on the Plugins page that a custom db.php and/or object-cache.php is in use. Along with the Name header if its listed..

#20 in reply to: ↑ 19 @nacin
13 years ago

Replying to dd32:

I would suggest another ticket raising the idea of having an alert on the Plugins page that a custom db.php and/or object-cache.php is in use. Along with the Name header if its listed..

And must-use plugins, as well, something I've thought about for a while. Hmm. Could be a good plugin, and possibly something for core.

#21 in reply to: ↑ 19 @archon810
13 years ago

Replying to dd32:

I would suggest another ticket raising the idea of having an alert on the Plugins page that a custom db.php and/or object-cache.php is in use. Along with the Name header if its listed..

Good idea. #11861 filed.

#22 @lkraav
7 years ago

Yep, definitely check for random stuff filtering site_transient_update_core to nothing. It will cause version checks on every admin request.

Note: See TracTickets for help on using tickets.