Optimizing the “Who is Online” Widget in BuddyPress: A Real-World Solution

One of its useful tools of Buddypress and Buddyboss for overall UX is the “Who is Online” widget, which displays a list of users who have been active in the last few minutes. On the surface, this feature seems simple, but as your community grows, it can introduce significant performance challenges. Read here how you can reduce the amount of queries and therefore load and runtime by 99%.

The Problem: Query Overload

When a user visits the page with the “Who is Online” widget embedded, BuddyPress needs to identify which members have been active recently. To do this, the widget performs several tasks:

  • It queries the database to find members active in the last X minutes – one query mostly, no problems!
  • It than iterates through all the given user ids and retrieves the username, avatar, and permalink to the user’s profile (queries within a loop – arghhh)
  • It performs additional checks, like whether a user is hidden or suspended (even more queries within a loop – arghhh!!!)

While this process works well in smaller communities, it quickly becomes inefficient as the number of active users increases.

Believe it or not – this can trigger hundreds of individual queries, causing a substantial overhead; not only to the pageload itself, but load on the database in general. This slows down page load times, strains the server, and ultimately degrades the user experience.

The Solution: Efficient Query Management and Caching

The key to optimizing this widget lies in reducing the number of database queries and offloading the heavy lifting to background processes.

Here’s how we did it:

  1. Implement a Cron Job for Data Collection
    • Instead of querying the database every time the widget loads, a cron job can be set up to run once per minute. This background job can perform all the necessary queries, such as fetching active users and gather the necessary user-data like avatar url, permalink, username, suspension status etc…
    • The runtime of this cron job doesn’t impact the user experience at all because it runs in the background. Even if it takes a second or two, it’s not noticeable to end-users at all and comes at no cost.
  2. Cache the Results
    • The data collected by the cron job is then cached. Whether we use transients or a persistent object cache, doesn’t really matter. Even caching it in the database is totally fine. The widget can pull the list of these users with all their details from this cache rather than querying the database every time.
  3. Shuffling for a “Live” Appearance
    • To keep the widget looking dynamic, the list of users in the cache can be shuffled randomly before being displayed. This gives the appearance of real-time updates without actually querying the database repeatedly.
  4. Centralize and Simplify Checks
    • Instead of performing individual checks for each user (e.g., whether a user is suspended), a single query can retrieve a central list of suspended, blocked or hidden users. The cached list of active users can then be filtered against this list before displaying them in the widget.

The Results: Insane Performance and User Experience

By implementing these optimizations, the number of queries made by the “Who is Online” widget is drastically reduced. We went from a few hundred queries upon every pageload to 3 queries. This lowers the server load, speeds up page load times, and improves the overall performance of the site. Moreover, the user experience is enhanced, as the widget appears to update in real-time without the lag caused by excessive queries.

In summary, this approach demonstrates the power of custom code optimization in WordPress. By strategically managing when and how data is queried and displayed, it’s possible to maintain a feature-rich user interface while significantly improving performance. This is where custom code consulting truly shines, offering tailored solutions that address specific challenges and scale efficiently with your growing community.

Scroll to Top