Improving Maintenance and Backup Efficiency in WordPress Multisite by Cleaning Orphaned Upload Folders


In large, high-traffic WordPress Multisite environments, system maintenance extends beyond the database and application layer. One area that is sometimes overlooked is the accumulation of orphaned directories within the uploads structure.

When sites are deleted from a WordPress network, their corresponding file directories often remain in the filesystem. Over time, this can create minor overhead in certain scenarios, especially when directories are very numerous or actively scanned by maintenance tools.

Disclaimer: The scripts and procedures below involve bulk filesystem operations. Always have a fresh, verified backup before running them. The author assumes no responsibility for accidental data loss or system damage.

Do Empty Folders Matter?

A common misconception is that empty folders are “harmless” since they occupy zero disk space. It is true that they do not consume meaningful disk space, and their impact on day-to-day system performance is negligible. The actual benefits, however, are realized primarily during maintenance operations that iterate over the entire directory structure:

  • Filesystem cache efficiency: The Linux kernel caches directory metadata (dentries) in RAM. Empty folders don’t pollute the cache meaningfully.
  • Directory scanning latency: In very large directories, creating files or scanning hundreds of thousands of entries may experience minor delays.
    For the vast majority of multisite networks, this effect is rarely noticeable during normal web serving.
  • Maintenance & Backup Efficiency: This is the primary use case. Tools such as rsync, rclone, or cloud backup agents must perform a stat() call on every object during full scans. In directories with tens of thousands of orphaned folders, these scans spend significant time and I/O just traversing “ghost” structures. Cleaning up truly orphaned directories can noticeably reduce backup windows and the load on the storage controller during integrity scans.

Quick, Admin-Friendly Summary

  • Empty folders generally do not affect your site’s day-to-day performance.
  • Only consider cleaning them up if you run full backups, scans, or replication tasks that traverse the entire uploads structure.
  • Focus on truly orphaned directories from deleted sites, not random empty folders, to gain meaningful improvements in operational efficiency.

The Optimization Workflow: A Data-Driven Approach

For multisite installations where cleanup is justified, a systematic approach must ensure safety and efficiency. Here’s a step-by-step method using WP-CLI and Bash:

1. Dynamic Discovery of Empty Folders

  1. Retrieve the latest blog IDs from the WordPress database to define the scan boundaries instead of using static ranges, using wpcli.
    Note: We use wp_blogs as the blogs table name.
  • For each number between 2 and MAX_ID, check if a corresponding directory exists and, if so, determine if it is empty. We use the -print -quit flags with find to ensure the process stops at the first file encountered, making the scan significantly faster.
Bash
# Fetch the maximum blog_id
MAX_ID=$(wp db query "SELECT MAX(blog_id) FROM wp_blogs" --skip-column-names --allow-root)
# Safety check for MAX_ID
if [[ -z "$MAX_ID" || ! "$MAX_ID" =~ ^[0-9]+$ ]]; then
    echo "Error: Could not fetch a valid MAX_ID from database."
    exit 1
fi
echo "Starting filesystem scan up to ID: $MAX_ID..."
for i in $(seq 2 $MAX_ID); do
    dir="YOURFOLDER/$i/"
    # Identify directories that exist but contain no files
    if [ -d "$dir" ] && [ -z "$(find "$dir" -type f -print -quit)" ]; then
        echo "$i" >> empty_folders.txt
    fi
    [[ $((i % 1000)) -eq 0 ]] && echo "Processed up to $i..."
Done

2. Database Cross-Referencing – Empty folder doesn’t mean a deleted blog

An empty folder doesn’t mean a deleted blog. Ensure the folder corresponds to a blog that no longer exists in the database records.

Bash

# Export active blog IDs from the DB
wp db query "SELECT blog_id FROM wp_blogs" --skip-column-names --allow-root > ids_in_db.txt
# Filter for IDs that exist in the filesystem but NOT in the database
grep -F -v -x -f ids_in_db.txt empty_folders.txt > folders_of_deleted_blogs.txt

3. Real-Time Re-Verification (The Safety Net)

Account for race conditions, such as new uploads occurring during the initial scan.

Bash

ROOT_PATH="YOURFOLDER"
cat folders_of_deleted_blogs.txt | xargs -I {} sh -c "find $ROOT_PATH/{} -type f -print -quit | grep -q . && echo {}" > folders_with_files.txt
# Create the final list of confirmed orphaned and empty directories
grep -F -v -x -f folders_with_files.txt folders_of_deleted_blogs.txt > safe_to_delete.txt

4. Controlled Migration (Quarantine) – Move, don’t delete

Move folders to a quarantine directory instead of deleting them immediately to prevent accidental data loss.

Bash

dest="/quarantine/deleted_blog_folders"
mkdir -p "$dest"
while IFS= read -r id || [ -n "$id" ]; do
src="YOURFOLDER/$id"
if [ -d "$src" ]; then
echo "Quarantining: $src"
# Using ionice (idle priority) to protect production I/O
ionice -c3 mv -- "$src" "$dest/"
fi
done < safe_to_delete.txt
# Final Cleanup of temporary metadata files
rm empty_folders.txt ids_in_db.txt folders_of_deleted_blogs.txt folders_with_files.txt safe_to_delete.txt
echo "Maintenance metadata cleared."

Conclusion

  • Empty folders rarely affect system performance in isolation.
  • Cleanup is an operational measure intended to streamline background tasks like backups, replication, and security audits.
  • Following a data-driven, cautious workflow ensures safety while reducing unnecessary filesystem clutter.
  • In large-scale infrastructure, managing orphaned directories is a matter of long-term operational health, rather than a quick fix for site speed.
  • Focus on data-driven cleanup rather than aggressive deletion.

#WordPress #DevOps #SysAdmin #LinuxPerformance #WebInfrastructure #WPCLI #MultisiteOptimization

Translating WordPress with Zero Tech Skills: My Talk at Patras Tech Talks


Last Saturday, November 15, 2025, I had the absolute thrill of speaking at Patras Tech Talk 2025.11 – Going International about how anyone—yes, even with absolutely no tech background—can pitch in to make WordPress fully Greek.

From my own mom, Kyra Chrysoula, scratching her head at “Login” and asking, “What on earth is that, dear?“, to those pesky “Add to Cart” buttons scaring off customers from Greek online shops, we unpacked why translation isn’t just nice to have—it’s a total game-changer.

We dove into the amazing WordPress Polyglots team, the three super straightforward ways to contribute translations to WordPress.org, some hilariously epic (and cringeworthy) translation mishaps, and how you can jump in and start translating in under 5 minutes right here.

  • My full presentation – translated in English is up for grabs right here.

Huge shoutout to the Patras Tech Talks organizers and everyone who showed up with killer questions—the Greek WordPress community is leveling up because of you all!

#WordPressGR #Polyglots #PatrasTechTalks #Translation #WordPress

Παρουσίαση στο Patras Tech Talks: «Μετάφραση WordPress με 0% τεχνικές γνώσεις»


To Σάββατο 15 Νοεμβρίου 2025 είχα την τιμή να παρουσιάσω στο Patras Tech Talk 2025.11 [Going international] το πώς μπορεί ο καθένας, ακόμα και χωρίς ίχνος τεχνικών γνώσεων, να βοηθήσει να γίνει το WordPress 100% ελληνικό και γιατί αυτό είναι σημαντικό.

Από την κυρά Χρυσούλα, την μητέρα μου, που βλέπει το “Login” και απορεί «Τι είναι αυτό παιδί μου;», μέχρι τα κουμπιά “Add to Cart” που διώχνουν πελάτες από ελληνικά e-shop, δείξαμε γιατί η μετάφραση δεν είναι πολυτέλεια – είναι αναγκαιότητα.

Μιλήσαμε για την ομάδα Polyglots του WordPress, τους 3 τρόπους που μπορεί κανείς να μεταφράσει για το WordPress.org, τα επικά (και τραγικά) μεταφραστικά λάθη, και πώς ξεκινάς σε 5 λεπτά στο https://translate.wordpress.org.

H παρουσίαση στα ελληνικά είναι διαθέσιμη εδώ:

Μεγάλο ευχαριστώ στους διοργανωτές του Patras Tech Talks και σε όλους εσάς που ήρθατε και ρωτήσατε – η ελληνική κοινότητα WordPress μεγαλώνει μαζί σας!

#WordPressGR #Polyglots #PatrasTechTalks #Μετάφραση

Φυσικά μετά ως γνήσιοι Έλληνες είχαμε και συνέχεια σε ταβέρνα

Restrict W3 Total Cache Admin Interface in Multisite WordPress


If you’re running a WordPress multisite site and using the W3 Total Cache plugin, you may have noticed that non-super admin users (like subsite admins) can access the plugin’s settings and see all it’s dashboard elements, such as help tabs and meta boxes. This can be problematic in multisite environments where you want to limit access to critical configuration options while keeping the interface clean for subsite admins.

To address this need, I (and AI) have created a PHP snippet that customizes the W3 Total Cache admin interface in multisite setups. It solves the following issues:

  • Restricts Admin Bar Access: Allows subsite admins with manage_options capability to access only the main W3 Total Cache menu and non-sensitive sub-menus (e.g., “Purge Current Page”), while restricting sensitive options (e.g., “Purge All Caches,” “General Settings”) to super admins only.
  • Improved User Experience: Non-super admins no longer see the “You do not have sufficient permissions to access this page.” message—access is cleanly limited without triggering permission errors.
  • Removes Meta Boxes: Clears all meta boxes from the W3 Total Cache dashboard page (toplevel_page_w3tc_dashboard) for non-super admins, ensuring a streamlined interface.
  • Removes Help Tabs: Hides all W3 Total Cache help tabs (with IDs starting with w3tc_faq_) from the dashboard for non-super admins.
  • Multisite Compatibility: The code only runs in multisite environments, leaving single-site installations unaffected.

You can find the code at: https://gist.github.com/lenasterg/cd7b43087735e4f170d81e90cf21c00c

How to Use It

  1. Ensure you’re using WordPress multisite and the W3 Total Cache plugin.
  2. Copy the code from the Gist.
  3. Paste it into a custom plugin or into your /wp-content/mu-plugins folder.
  4. Test in a staging environment first to confirm compatibility with your setup.

Fixing Greek Filenames for og:image Compatibility in WordPress


While working with WordPress and social media, I noticed an issue when sharing images on Facebook. Specifically, images with Greek characters in their filenames wouldn’t show up as og:image thumbnails, even though they were properly uploaded.

To address this, I developed a simple WordPress plugin LS Sanitize Greek Filename, that automatically sanitizes Greek filenames. It converts Greek characters into their Latin equivalents, making the filenames compatible with platforms like Facebook, ensuring that images appear correctly when shared.

This plugin is useful for WordPress users dealing with Greek filenames, helping ensure their images display as thumbnails in social media previews. It’s also multisite compatible!

You can find the plugin on https://wordpress.org/plugins/ls-sanitize-greek-filename/

BP Group Documents 2.0


BP Group Documents is a BuddyPress plugin that creates a dedicated page within each group, allowing members to upload and manage any type of file or document. This makes it easy for group members to share and store documents relevant to the group.

The latest update 2.0 brings key improvements:

Compatibility with the latest WordPress & BuddyPress versions
🛠 Bug fixes for better stability and document management

Download the latest version from the WordPress.org repository:
https://wordpress.org/plugins/bp-group-documents/

Auto-increase subsite’s Upload Space when Low in a WordPress Multisite


If you’re managing a WordPress Multisite network, you might run into an issue where a site reaches its upload limit. This can cause problems for users who need to upload new media files. To address this, you can use the following PHP function to automatically notify the super admin and increase the available space when it falls below 200MB.

How the Code Works

  • The function ls_blog_space_mail() checks the available upload space.
  • If the space drops below 200MB, it increases the limit to 4500MB (or another predefined value).
  • An email is sent to the super admin notifying them of the change.
  • If the space is low but the limit is already at or above 4500MB, an email is sent without increasing the limit, simply warning the admin about low space.
  • In a WordPress Multisite setup, this function is now hooked into the welcome panel, ensuring it runs when an admin visits the dashboard.

Where to Add This Code

This function should be placed in your WordPress Multisite installation’s mu-plugins directory.

Steps to Add It:

  1. Navigate to wp-content/mu-plugins/. If the mu-plugins folder doesn’t exist, create it.
  2. Create a new PHP file, such as auto-expand-space.php.
  3. Copy and paste the function inside the file.
  4. Save and upload the file to the mu-plugins directory.

Since mu-plugins (Must-Use Plugins) load automatically in WordPress Multisite, this script will run without requiring activation.

<?php
/**
 * Auto email to super admin when the blog's available space is less than 200MB.
 * If space is below 200MB, it auto-expands the storage and notifies the super admin.
 *
 * @return void
 */
function ls_blog_space_mail() {
    $space_left = round( get_upload_space_available() / 1024 / 1024 );
    
    if ( $space_left < 200 ) {
        $new_space_limit = 4500;
        $space_allowed = get_space_allowed();
        
        if ( $space_allowed < $new_space_limit ) {
            // Increase the space for the blog
            update_option( 'blog_upload_space', $new_space_limit );
            
            // Send notification to super admin
            $message = 'Site ' . get_site_url() . ' had only ' . $space_left . 'MB space left, from total: ' . $space_allowed . 'MB.
' .
                       'We auto-expanded the available space to ' . $new_space_limit . 'MB.
' .
                       'If you want to change it, visit ' . network_admin_url( 'site-settings.php?id=' . get_current_blog_id() ) . ' and change the "' . __( 'Site Upload Space Quota' ) . '".';
            
            wp_mail( get_site_option( 'admin_email' ), '[ ' . wp_specialchars_decode( get_option( 'blogname' ) ) . ' ] Auto-increased upload space to ' . $new_space_limit, $message );
        }
     else {
        // Send notification about low space without auto-expansion
        $message = 'Site ' . get_site_url() . ' has only ' . $space_left . 'MB space left, from total: ' . $space_allowed . 'MB.
' .
                   'If you wish to expand the available space, visit ' . network_admin_url( 'site-settings.php?id=' . get_current_blog_id() ) . ' and increase the "' . __( 'Site Upload Space Quota' ) . '". (Currently: ' . $space_allowed . 'MB)';
        
        wp_mail( get_site_option( 'admin_email' ), '[ ' . wp_specialchars_decode( get_option( 'blogname' ) ) . ' ] Low available space', $message );
    }
}
}

/**
 * Hook the function into the welcome panel in a multisite setup.
 */
if ( is_multisite() ) {
    add_action( 'welcome_panel', 'ls_blog_space_mail' );
}

Related posts:

Informing Subsite Admins about Media Storage space in WordPress Multisite


In WordPress Multisite networks, site administrators (or subsite admins) are often responsible for managing their own site’s content, including media uploads like images and documents. However, there’s a common issue that can go unnoticed: the lack of information regarding their site’s media storage usage. This typically arises from the fact that the storage information displayed only in the Dashboard > At a Glance section is often overlooked, leading to potential space management issues.

The plugin ls-media-storage-info-multisite solves this problem by providing info about the storage usage where is needed most, in Media Library admin page.

The Problem: Overlooked Media Usage Data

In a WordPress Multisite environment, each subsite often has its own collection of uploaded media files. Each subsite admin only sees the info about the storage space usage in their dashboard under At a Glance.

Many admins neglect to check this section, either due to lack of awareness or because the information is not presented in a way that emphasizes the importance of storage management. As a result, subsites might quickly run into storage issues, especially if multiple large files are being uploaded without a clear overview of the available space.

How ls-media-storage-info-multisite Helps

The ls-media-storage-info-multisite plugin tackles this problem by providing info about the storage usage where is needed most by the subsite admins, in Media Library admin page and in the ‘Upload file’ window across all subsites within a WordPress Multisite network.

The Key Benefits for Subsite Admins

  1. Greater Awareness of Storage Space: With more accessible data about how much space their media is consuming, subsite admins are less likely to overlook this crucial aspect of site management.
  2. Proactive Management: Admins can take preventive action, such as cleaning up unused files or asking for additional storage, before hitting critical limits.
  3. Improved User Experience: By maintaining smooth media uploads and avoiding storage overload, subsites ensure that their visitors experience faster load times and fewer issues with media content.

How to Make Use of the Plugin

The plugin is simple to install and set up. Once installed on a Multisite network, it provides an enhanced view of media storage directly from the subsite’s Media Library page.
Admins can use this data to:

  • Regularly check their media storage statistics.
  • Actively manage large media files by deleting unnecessary items or optimizing images.
  • Report storage concerns to the main network admin if space is becoming scarce.

Conclusion

By making storage visibility a priority and addressing the tendency for subsites to overlook the At a Glance storage info, ls-media-storage-info-multisite significantly improves the management of media files in WordPress Multisite networks. It’s a simple yet powerful tool for ensuring that admins are aware of their site’s storage status, ultimately contributing to better performance and easier scalability across the entire network.

If you’re an admin in a WordPress Multisite setup and want to gain better control over your media storage, consider installing ls-media-storage-info-multisite. It’ll help keep your network running smoothly and prevent storage issues before they become a problem.

Related post: How to notify the superadmin when a subsite has low available storage space

Plugin “All Sites Columns for Multisite”


The new plugin available at https://wordpress.org/plugins/all-sites-columns-for-multisite/ is Multisite specific for the superadmin and adds the columns:

  • blog_id
  • public
  • archived
  • mature
  • spam
  • deleted
  • site_id

into the ‘Sites’ admin table in Network administration page, allowing this way the superadmin to sort blogs by the desired column and spot sites which are for example deleted by their owners.

The superadmin can hide the Columns, which are useless for her/him via the ‘Screen Options’ tab.

New plugin released: Easy search and use CC-licensed images for WP


The Creative Commons image search plugin for WordPress we created in Greek School Network is now available as a plugin in WordPress.org with the name “Easy search and use CC-licensed images for WP

The plugin helps you search millions of free photos using the Creative Commons Catalog API then insert the original image into content or set as featured image very quickly.

screenshot-3

The plugin’s features are:

  • Works in WordPress editor and add a button above the content text area and into the “Add Media” pop-up window.
  • Via a pop-up window, allows searching through millions of images using Creative Commons Catalog API power.
  • Allows filtering by a provider
  • Paginated results
  • Quick insert original image or thumbnail with a link to the image URL
  • Use image as a featured image for the blog post
  • WPML compatible
  • Multisite compatible
  • Translation ready (it’s already translated in Greek)
  • Tested up to WordPress 5.2 with Classic Editor plugin

As intended, we already use the plugin in https://blogs.sch.gr, which hosts more than 50.000 blogs. The plugin is available to all its blogs and users since middle May, who has been using it without any issues reported yet.

Read the complete story behind the creation of this plugin at CC Open Source Blog