Voxfor - All rights reserved - 2013-2025
We Accepted





WordPress Multisite is a powerful feature that allows developers to operate multiple websites from a single installation. However, working with Multisite introduces unique challenges, especially when interacting with data across different subsites. Two critical functionsโswitch_to_blog() and restore_current_blog()โare essential for navigating this environment, but their misuse can lead to significant performance bottlenecks.
This comprehensive guide explores the purpose of these functions, their ideal use cases, and strategies to mitigate their performance costs. By the end, you’ll understand how to leverage them effectively while maintaining optimal efficiency in your Multisite network.
Before diving into switch_to_blog(), let’s clarify how Multisite works:
This structure allows centralized management but requires careful handling when accessing subsite-specific data.
Switches the execution context to a specific subsite, allowing you to interact with its data as if you were on that site. Internally, it:
Reverts the context to the original subsite, undoing the changes made by switch_to_blog().
Example: A custom network dashboard displaying recent posts from all subsites.
// PHP Code
$sites = get_sites(['number' => 50]);ย ย
foreach ($sites as $site) {ย ย
ย ย switch_to_blog($site->blog_id);ย ย
ย ย $recent_posts = wp_get_recent_posts(['numberposts' => 3]);ย ย
ย ย // Display postsย ย
ย ย restore_current_blog();ย ย
}
Example: Copy default settings from the primary site to new subsites.
// PHP Code
function sync_default_settings($new_blog_id) {ย ย
ย ย switch_to_blog(1); // Primary siteย ย
ย ย $default_options = get_option('my_plugin_settings');ย ย
ย ย restore_current_blog();ย ย
ย ย switch_to_blog($new_blog_id);ย ย
ย ย update_option('my_plugin_settings', $default_options);ย ย
ย ย restore_current_blog();ย ย
}ย ย
add_action('wp_initialize_site', 'sync_default_settings');
Example: Update a plugin option for all subsites.
// PHP Code
$sites = get_sites(['fields' => 'ids']);ย ย
foreach ($sites as $blog_id) {ย ย
ย ย switch_to_blog($blog_id);ย ย
ย ย update_option('my_plugin_option', 'new_value');ย ย
ย ย restore_current_blog();ย ย
}
Example: Display a global activity feed combining comments from all subsites.
// PHP Code
$sites = get_sites(['number' => 20]);ย ย
$activity = [];ย ย
foreach ($sites as $site) {ย ย
ย ย switch_to_blog($site->blog_id);ย ย
ย ย $comments = get_comments(['number' => 5]);ย ย
ย ย $activity[$site->blog_id] = $comments;ย ย
ย ย restore_current_blog();ย ย
}
Example: Grant a user privileges across multiple subsites.
// PHP Code
$user_id = 5;ย ย
$target_blogs = [1, 3, 7];ย ย
foreach ($target_blogs as $blog_id) {ย ย
ย ย switch_to_blog($blog_id);ย ย
ย ย add_user_to_blog($blog_id, $user_id, 'editor');ย ย
ย ย restore_current_blog();ย ย
}
While switch_to_blog() is indispensable, it’s resource-intensive. Here’s why:
Switching blogs clears the current object cache, requiring re-fetching data like taxonomies and post types.
Plugins and themes may hook into switch_blog or restore_current_blog, adding latency.
A test switching 100 subsites took 2.1 seconds without caching. With 1,000 subsites, this could exceed 20 seconds, making the process impractical for real-time use.
Inefficient Approach:
// PHP Code
foreach ($sites as $site) {ย ย
ย ย switch_to_blog($site->blog_id);ย ย
ย ย $option = get_option('my_option');ย ย
ย ย restore_current_blog();ย ย
}
Optimized Approach: Fetch data in bulk using direct SQL:
// PHP Code
global $wpdb;ย ย
$site_ids = implode(',', array_column($sites, 'blog_id'));ย ย
$results = $wpdb->get_results("ย ย
ย ย SELECT blog_id, meta_valueย ย
ย ย FROM {$wpdb->base_prefix}blogsย ย
ย ย JOIN {$wpdb->base_prefix}{$blog_id}_optionsย ย
ย ย WHERE option_name = 'my_option'ย ย
ย ย AND blog_id IN ($site_ids)ย ย
");
Cache subsite data to avoid repeated switches:
// PHP Code
$cache_key = 'network_wide_posts';ย ย
$data = wp_cache_get($cache_key);ย ย
if (false === $data) {ย ย
ย ย $data = [];ย ย
ย ย foreach ($sites as $site) {ย ย
ย ย ย ย switch_to_blog($site->blog_id);ย ย
ย ย ย ย $data[$site->blog_id] = get_posts(['numberposts' => 5]);ย ย
ย ย ย ย restore_current_blog();ย ย
ย ย }ย ย
ย ย wp_cache_set($cache_key, $data, 'network', 3600);ย ย
}
Run heavy operations via WP-CLI to avoid PHP timeouts:
// PHP Code
class Batch_Processor {ย ย
ย ย public function update_all_posts() {ย ย
ย ย ย ย $sites = get_sites(['fields' => 'ids']);ย ย
ย ย ย foreach ($sites as $blog_id) {ย ย
ย ย ย ย ย ย WP_CLI::log("Processing blog $blog_id");ย ย
ย ย ย ย ย ย switch_to_blog($blog_id);ย ย
ย ย ย ย ย ย // Batch process postsย ย
ย ย ย ย ย ย restore_current_blog();ย ย
ย ย ย ย }ย ย
ย ย }ย ย
}ย ย
WP_CLI::add_command('batch', 'Batch_Processor');
Run with:
wp batch update_all_postsย
Use get_sites() parameters to narrow down subsites:
// PHP Code
// Target only active sites in a specific networkย ย
$sites = get_sites([ย ย
ย ย 'archived' => 0,ย ย
ย ย 'spam' ย ย => 0,ย ย
ย ย 'deleted'ย => 0,ย ย
ย ย 'network_id' => 1,ย ย
]);
Nesting switch_to_blog() calls can cause context mismatches. Always restore before switching again:
// PHP Code
// โ Dangerousย ย
switch_to_blog(1);ย ย
switch_to_blog(2);ย ย
restore_current_blog(); // Restores to 1ย ย
restore_current_blog();ย ย
// โ
Safeย ย
switch_to_blog(1);ย ย
// Do workย ย
restore_current_blog();ย ย
switch_to_blog(2);ย ย
// Do workย ย
restore_current_blog();
Use $wpdb to query subsite tables directly:
// PHP Code
global $wpdb;ย ย
$posts = $wpdb->get_results("ย ย
ย ย SELECT * FROM {$wpdb->base_prefix}2_postsย ย
ย ย WHERE post_type = 'post'ย ย
");
Expose subsite data via REST API and fetch it remotely:
// PHP Code
// On subsite 1ย ย
register_rest_route('my-plugin/v1', '/data', [ย ย
ย ย 'callback' => 'get_subsites_data',ย ย
]);ย ย
// On the main siteย ย
$response = wp_remote_get("https://subsite1.com/wp-json/my-plugin/v1/data");
Store subsite data in a network-wide table for quick access:
// PHP Code
// On subsite switchย ย
update_network_option(null, "site_{$blog_id}_data", $data);
Problem: A network dashboard displaying user activity across 500 subsites took 12 seconds to load due to excessive switch_to_blog() calls.
Solution:
Results:
switch_to_blog() and restore_current_blog() are powerful tools in a WordPress Multisite developer’s arsenal, enabling cross-site data management and global operations. However, their performance costs demand careful optimization. By minimizing switches, leveraging caching, and using direct database queries, you can maintain efficiency even in large networks.
Hassan Tahir wrote this article, drawing on his experience to clarify WordPress concepts and enhance developer understanding. Through his work, he aims to help both beginners and professionals refine their skills and tackle WordPress projects with greater confidence.