BuddyPress 2.0 “Juliana” has been…

BuddyPress 2.0 “Juliana” has been released: http://buddypress.org/2014/04/buddypress-2-0-juliana/

Special thanks to the readers of this blog who have helped with development and testing during this dev period. Go enjoy a slice of pizza!

BP 2.0 RC 1: http://buddypress.org/2014/04/buddypress-2-0-release-candidate/

BP 2.0 RC 1: http://buddypress.org/2014/04/buddypress-2-0-release-candidate/

BP 2.0-beta2 is now available:…

BP 2.0-beta2 is now available: http://buddypress.org/2014/04/buddypress-2-0-beta2/

One of the primary focuses…

One of the primary focuses of BP 2.0 development has been performance. In this post, I’ll share a few numbers that demonstrate the improvements you can expect in the new version.

For testing, I set up a fresh installation of WP 3.8.1, running Twenty Fourteen and the default widget configuration. Using wp-cli-buddypress, I generated 30,000 members and 60,000 activity items. I toggled between various setups, running the latest BP 1.9.x as well as the latest BP trunk (2.0.x). The tests labeled “APC On” were run using APC with a default config (specifically, APCu on PHP 5.5.10) and the WP APC plugin. In these cases, I also primed the cache with a page refresh. Tests labeled “APC Off” do not have persistent object caching enabled.

What follows are statistics about MySQL (number of queries and the total query time). In many cases, there are corresponding improvements in script execution time and memory footprint, but these latter numbers are so dependent on other environmental features that I’ve decided not to include them here. You should take things like “query time” with a grain of salt; the numbers are useful mainly to visualize relative gains. But it’s worth noting that the improvements in query time will become more significant as sites become larger than the dummy site that these numbers come from.

  1. Baseline
    Here are some numbers with BP deactivated, so you can get a sense of what the default WP installation is doing:

    Home page – BP deactivated – APC Off

    # queries: 30
    query time: 0.005503s


    Home page – BP deactivated – APC On

    # queries: 9
    query time: 0.002269s

  2. Activity
    Several important changes were made to the way that BuddyPress activity is queried, including significant improvements in object caching and splitting the query to avoid costly JOINs. Here are some results of looking at the main Activity directory page, default filters, as a logged-out visitor.

    BP 1.9.2 – APC Off

    # queries: 80
    Query time: 0.111316s


    BP 2.0 – APC Off

    # queries: 59
    Query time: 0.046568s


    BP 1.9.2 – APC On

    # queries: 10
    Query time: 0.002157s


    BP 2.0 – APC On

    # queries: 5
    Query time: 0.001317s

  3. Members
    The efficiency of members queries was another area of intense focus during the 2.0 dev cycle. The way that last_activity data is stored and queried was overhauled, and a large number of improvements were made to userdata caching. The following data is from the 234th page of the Members directory, sorted by Last Active (/members/?upage=234), as seen by a logged-out visitor.

    BP 1.9.2 – APC Off

    # queries: 63
    Query time: 0.197926s


    BP 2.0 – APC Off

    # queries: 39
    Query time: 0.0952112s


    BP 1.9.2 – APC On

    # queries: 17
    Query time: 0.184889s


    BP 2.0 – APC On

    # queries: 10
    Query time: 0.091074s

  4. Logged-in data
    Users who are logged in to a BP site carry a lot of data along with them on every page of the site. Userdata is used to build navigation links, to build the admin bar, to populate the Notifications dropdown, etc. We’ve made an effort to make these queries less redundant and more efficent. Here are some numbers from a home page visit by a logged-in user.

    BP 1.9.2 – APC Off

    # queries: 49
    Query time: 0.010246s


    BP 2.0 – APC Off

    # queries: 45
    Query time: 0.008786s


    BP 1.9.2 – APC On

    # queries: 16
    Query time: 0.0042662


    BP 2.0 – APC On

    # queries: 4
    Query time: 0.0012240

You can see that the improvements are significant. The number of queries per page load in each case has been cut by up to 50%, and query time, on average, has been cut by more than 50%. And remember that these numbers are total values – it’s BP on top of WP’s standard queries. That is to say that the query footprint attributable to BP itself has been reduced by up to 75% in many places.

This is not an exhaustive list of benchmarks, but it’s indicative of improvements you should see across most sections of BP sites after the 2.0 upgrade. The improvements will be especially noticeable on very BP installations. If this isn’t good motivation for you to help with the 2.0 beta, I don’t know what is :)

2.0 Beta 1 is now…

2.0 Beta 1 is now available! http://buddypress.org/2014/03/buddypress-2-0-beta-1-is-now-available/

User last_activity data and BuddyPress 2.0

BuddyPress uses ‘last_activity’ data extensively: for display purposes (‘last active 3 days ago’), to sort results, and to determine whether a WP user is a valid site member. At the same time, ‘last_activity’ has been a perennial performance bottleneck. In the case of users, the information was stored in wp_usermeta. This table gets exceptionally bloated on busy sites, and it’s not properly indexed for the sorts of ORDER BY queries we were performing on it. See #5128 for more background.

A fix for this longtime issue is in place for BuddyPress 2.0. (See r7860.) Short version: user last_activity data is now stored in a ‘last_activity’ row in the wp_bp_activity table. We’ve modified our core queries to take advantage of the new location. And we’ve done a bit of trickery to make sure that the wp_bp_activity table is available for storage, even if the Activity component is disabled. The performance improvements are pretty extreme; I’ll post benchmarks as we near 2.0′s release.

Plugin developers who use user ‘last_activity’ data are urged to account for the new schema. In the past, you may have accessed user last_activity like this:

update_user_meta( $user_id, 'last_activity', $time );
$last_activity = get_user_meta( $user_id, 'last_activity', true );

You are urged to use our API functions instead:

bp_update_user_last_activity( $user_id, $time );
$last_activity = bp_get_user_last_activity( $user_id );

In cases where you are making direct database queries based on this info, please consider using BP_User_Query instead. At the very least, you should refactor your queries to use the new schema.

For the time being, ‘last_activity’ data will continue to be mirrored in wp_usermeta, so your plugins will continue to work. However, you’ll get deprecated notices every time you use the _user_meta() functions to access the information. And hey, the new way performs much better, so you’ll want to update anyway.

Here’s a list of the plugins I found in the wordpress.org plugin repo that will need updating:

  • bp-group-control
  • bp-default-data
  • welcome-pack
  • activate-users-in-buddypress
  • bp-groups-suggestions
  • hts-display-active-members
  • bp-member-widget
  • buddypress-community-stats
  • buddypress-sitemap-generator
  • bp-ninja

Questions regarding this change? Need help migrating your code? Please leave a comment below.

(A quick note regarding ‘last_activity’ for groups and blogs. The basic problem there is the same as for users, but the scaling issues are much less severe, so they have not been touched for now. Keep an eye out for relevant updates.)

#2-0, #last_activity