Plugins Documentation How It Works About Support My Account Browse Plugins
Backup

Bodholdt Backup for Google Drive

Automated WordPress backups to Google Drive

v6.26.0
PHP 7.4+
WP 6.0+
GPL-licensed
14-day money-back

Get Bodholdt Backup for Google Drive

Lifetime licenses available · 14-day money-back · Cancel anytime

Free

$0

Free forever:

  • 1 site
  • Full plugin functionality
  • Full restore + unlimited backup retention
  • Community support
Get it free →

Solo

$29.00 /yr

Everything in Free, plus:

  • A paid license for 1 site
  • Selective restore — choose what to restore (database, plugins, themes, uploads, core)
  • Streaming restore (FK-safe, BLOB-safe)
  • Lifetime license available
  • Email support while active
Buy Solo →
Most popular

Pro

$59 /yr

Everything in Solo, plus:

  • 5 sites on a single license
  • Slack & Discord notifications on backup success, failure, restore, and stale-alert events
Buy Pro →

Agency

$129 /yr

Everything in Pro, plus:

  • Unlimited sites
  • Priority email support while active
Buy Agency →
See full feature comparison →
Feature FreeSoloProAgency
Sites 115
Full plugin functionality
Full restore
Backup retention UnlimitedUnlimitedUnlimitedUnlimited
Selective restore
Slack & Discord alerts
Lifetime license option
Support WordPress.org forumEmail while activeEmail while activePriority email
Try it free

Start free with the Lite edition

Full automated backups and full restore, free forever. Upgrade to Pro for selective restore, multi-site, and Slack/Discord alerts.

Get Bodholdt Backup for Google Drive (free)

The free version is yours. No card, no license key. Enter your email and we will send you a download link.

A 6-digit verification code will be emailed to you.

Real screens from Bodholdt Backup for Google Drive

These are real admin screens, not mockups. Click any one to view it full size.

The dashboard shows a health summary, your last backup's status, a size estimate, and a one-click Start Backup button.
The dashboard shows a health summary, your last backup's status, a size estimate, and a one-click Start Backup button.
The Google Drive settings tab, where you set your OAuth credentials, the schedule, Full or Incremental mode, and how many backups to keep.
The Google Drive settings tab, where you set your OAuth credentials, the schedule, Full or Incremental mode, and how many backups to keep.
Your Backups is a sortable browser of everything stored in Drive, with restore and delete on each one.
Your Backups is a sortable browser of everything stored in Drive, with restore and delete on each one.
The restore panel, where you confirm a one-click full restore of your database, plugins, themes, uploads, and core files.
The restore panel, where you confirm a one-click full restore of your database, plugins, themes, uploads, and core files.
A paginated log of every run, with clear success, error, and running labels and troubleshooting tips on each row.
A paginated log of every run, with clear success, error, and running labels and troubleshooting tips on each row.
A guided four-step wizard that walks you through the first run, from connecting Drive to setting a schedule and taking the first backup.
A guided four-step wizard that walks you through the first run, from connecting Drive to setting a schedule and taking the first backup.

Automated WordPress backups to Google Drive with selective restore, setup wizard, and a cyberpunk-themed admin panel. Built with accessibility in mind (keyboard navigation, reduce-motion gating, ARIA semantics) and security-hardened against XSS.

Streaming restore that stays FK-safe and BLOB-safe

Full and incremental backups, scheduled or on demand

Complete multisite-network backup

Selective restore of the database, plugins, themes, uploads, and core (Solo and up)

Cross-server migration installer

Resumable chunked upload with auto-retry

Pre-restore safety snapshot

Guided setup wizard with an OAuth walkthrough

  • Streaming restore that stays FK-safe and BLOB-safe
  • Full and incremental backups, scheduled or on demand
  • Complete multisite-network backup
  • Selective restore of the database, plugins, themes, uploads, and core (Solo and up)
  • Cross-server migration installer
  • Resumable chunked upload with auto-retry
  • Pre-restore safety snapshot
  • Guided setup wizard with an OAuth walkthrough
Version
6.26.0
PHP Required
7.4+
WordPress
6.0+
License
Annual
v6.26.0
  • More emerald polish. "Start Backup Now" cloud icon is now pure white; the "Your Backups" table (column headers, file/Download/Restore icons, row hover) is now emerald instead of cyan/purple; in-app "Upgrade to Pro" notices and the troubleshooting path now use the emerald accent.
  • Logs toolbar. The "Apply" filter button is now a gradient button and "Clear History" is clearly marked red as a destructive action.
v6.25.0
  • Admin polish. Dashboard "Success" and "Connected" status pills now use the emerald theme accent; "Refresh Estimate", "Test Connection", "Send Test Email", and "Send Test Notification" are now gradient buttons; and "Reset to Defaults" is now clearly marked red as a destructive action.
  • Fixed "Your Backups" showing empty. The plugin could read a stray duplicate "Bodholdt Backups" folder in Google Drive and report no backups even when backups existed. It now reliably resolves the original folder (oldest match) and will no longer create a duplicate folder if a Drive lookup briefly fails.
v6.24.0
  • Consistent buttons. The "Start Backup Now" button now uses the same green gradient as the "Save Settings" button, so the primary actions match across the admin.
v6.23.0
  • Green admin theme. The Google Drive admin now uses an emerald-green accent that matches its product page — so it reads as distinct from the cyan Bodholdt Backup for OneDrive admin at a glance. Same layout and dark canvas; accent colour only.
v6.22.0
  • Admin styling now sourced from the shared Bodholdt Labs design system. The admin UI consumes the canonical `bod-admin.css` (the same dark-admin stylesheet shipped across Bodholdt Labs plugins) instead of a plugin-local copy, so the look stays consistent and future polish lands everywhere at once. This release brings the Google Drive admin up to full parity with the OneDrive edition: entrance animations on cards/modals/toasts, standardized title/progress gradients, a tooltip layering fix, the upsell/locked-feature polish, and an accessible purple text colour. No functional or behavioural change.
v6.21.0
  • Pro edition with licensed auto-updates. This is the paid, off-directory build of Bodholdt Backup for Google Drive, distributed by Bodholdt Labs. It enables in-dashboard automatic updates delivered from the Bodholdt Labs licensing server when a valid license key is active (license key + site URL + product identifier only; never site content or backup data).
  • Selective restore available on every paid tier, including Solo — pick exactly which components (database, system files, themes, plugins, uploads) to restore. Retention is uncapped on all tiers (bounded only by a per-install sanity limit).
  • Slack/Discord webhook notifications for backup success/failure, restore-initiated, and stale-backup watchdog events (Pro and Bundle tiers).
  • Hardening (parity with the directory edition): first-party download streaming now uses the WordPress HTTP API; admin-notice scripts moved to `wp_add_inline_script`; staging/uninstall paths resolved via `wp_get_upload_dir()`; installer CSRF/lockfiles relocated to the system temp directory with a table-prefix validation guard; all request inputs run through `wp_unslash()` before sanitization.
  • Added an "External services" section to this readme documenting the Google Drive / Google OAuth endpoints, the Bodholdt Labs licensing/update server, and the WordPress.org secret-key (salt) request used during cross-server migration.
v6.20.2
  • Fixed: Duration column in the Logs view showed a stray trailing "s" (e.g. "2 minutess" instead of "2 minutes"). The duration string from `human_time_diff()` already includes the unit word, but the Logs table cell appended an extra `'s'` — a leftover from when duration was rendered as a numeric-seconds value. The cell now renders the duration string as-is. Cosmetic only — no data, scheduling, or backup behavior changes.
v6.20.1
  • Fixed: footer line missing on installs that run third-party plugins which globally blank the WP admin footer. Some plugins (e.g. Taxonomy CSV Import/Export) register `__return_empty_string` against `admin_footer_text` at priority 11 across every admin page — which silently wiped our v6.20.0 footer line (Bodholdt Backup for Google Drive v6.X.X · Documentation · Support). Our filter now runs at priority 99, so it executes last and the footer renders as designed regardless of any other plugin's behavior.
v6.20.0
  • UI: version moved out of the page title. The big "BODHOLDT BACKUP FOR GOOGLE DRIVE V6.X.X" plugin-page heading is now just the product name + the tier badge ("FREE" / "Pro" / etc.). The version still appears, but now in the WordPress admin footer alongside Documentation and Support links — discreet and out of the way. Aligned with how WordPress core, WooCommerce, Yoast, and most established plugins handle this.
v6.19.1
  • Brand consistency follow-up. The License sub-page heading still showed the short-form "Bodholdt G-Drive" label after the v6.19.0 rebrand. Now reads "Bodholdt Backup for Google Drive — License" to match the rest of the plugin. No behavior change.
v6.19.0
  • Renamed to "Bodholdt Backup for Google Drive." Adopts the trademark-safe "for [destination]" naming pattern across all customer-facing surfaces (plugin header, admin menus, dashboard, email subjects, logs). Functionally identical — no settings or backups affected.
  • Setup wizard — inline OAuth setup guide. Step 2 of the first-run wizard now spells out exactly how to create the OAuth Client ID and Client Secret in Google Cloud Console — including the redirect URI you need to paste, inline with a copy-to-clipboard helper. Previously this guidance lived only in the Settings tab, and the wizard alone left first-time users without enough information to complete the connection.
  • Setup wizard — improved "Testing on a local site?" callout. The advisory now correctly explains Google's policy that redirect URIs must be either `http://localhost` or HTTPS at a public TLD (`.com`, `.org`, etc.), so `.local` development sites (Local by Flywheel, MAMP) are rejected even with HTTPS enabled. Recommends using Local's "Live Link" feature for an HTTPS public URL when testing.
  • Tested up to: WordPress 7.0. Verified compatibility with the current stable release.
  • Honest claims. Softened a few storefront descriptions to be evergreen rather than time-specific ("accessibility-minded" rather than a literal compliance grade; "security-audited each release" rather than a specific score) so they stay accurate without periodic updates.
  • wp.org Contributors handle updated to `bodholdtlabs` in preparation for wp.org plugin directory submission.
v6.18.0
  • Per-site backup folders. Each site now backs up to its own uniquely-named folder in your Google Drive (identified by a per-site ID), so multiple WordPress sites sharing one Google account no longer write into the same folder. If a shared folder from an earlier version is detected, the plugin moves this site to its own folder and shows a one-time notice — nothing is deleted and your existing backups stay untouched.
v6.17.2
  • Licensing fix + brand consolidation. License activation, validation, and auto-updates now point at the correct server (bodholdtlabs.com) and use the correct product reference, so license keys validate reliably (a mismatch previously prevented validation). Author byline, support email, and account links updated to Bodholdt Labs / bodholdtlabs.com.
v6.17.1
  • Retention tier fix. Solo and Agency licenses now get their correct backup-retention limits (Solo 50, Agency unlimited up to the system maximum), and Agency now includes selective restore and Slack/Discord notifications. Previously these tiers fell back to the Free 10-backup limit because the entry tier is issued as "default" and the top tier as "agency" — both are now recognized. Pro and Bundle are unchanged.
v6.17.0
  • Fun + accessibility + consistency pass. Brings the celebration moments, accessibility, and copy up to full parity with Bodholdt Backup for OneDrive, plus a few new-for-both delights.
  • New: cumulative "backups protected" stat. The Backup Health card now shows a running total — "🛡️ N backups protected · X GB kept safe" — counted from a dedicated counter so it survives clearing your activity log.
  • New: first-backup celebration. Your very first successful backup now gets a bigger one-time celebration ("Your first backup is done — your site is officially protected! 🛡️").
  • New: restore-complete celebration. Finishing a restore now greets you with a gentle celebration and a "Site restored — welcome back." confirmation.
  • Richer backup-complete celebration — multi-burst branded confetti, a green-to-teal glow on the progress bar, and a success notification (matching Bodholdt Backup for OneDrive).
  • Accessibility: confetti now respects "reduce motion." All celebration animations are skipped when your system requests reduced motion. Tab navigation also gained proper ARIA tablist semantics for screen readers.
  • Friendlier first-run guidance: the connect-success banner is now warmly themed with a "Run First Backup →" button; the Start Backup button is disabled with a "Connect your Google Drive first — Open Settings" prompt until you've connected; and a "Your site stays online during the backup." reassurance now sits under the button.
  • Clearer empty states + copy: the activity log empty state is now two reassuring lines; health-card placeholders read "Ready to start" / "Awaiting first backup"; and destructive confirmations now state exactly what happens and what's reversible.
  • Help sidebar now links to the plugin homepage and email support. Page heading standardized to "Bodholdt Backup for Google Drive."
v6.16.1
  • Cross-plugin parity follow-ups.
  • "Reset to Defaults" now restores a sensible Daily 3:00 AM backup (both backup plugins now reset to the same default). And a scheduled backup on a site that hasn't connected its cloud account yet now skips quietly, instead of emailing a daily "backup failed" alert.
  • Removed the extra pre-backup confirmation dialog — clicking "Start Backup Now" begins immediately, matching Bodholdt Backup for OneDrive's one-click flow. The "Force Full Backup" option is still right there as an inline checkbox above the button.
v6.16.0
  • Steve Jobs / Grandma Test Pass — Rounds 2-5 (error states, settings parity, micro-interactions, visual polish). Brings the plugin to full feature/UX parity with Bodholdt Backup for OneDrive. Bundles three internal batches:
  • *Error handling (R2):* OAuth failures now show a friendly, recoverable banner instead of a blank WordPress error page; an expired or revoked Google Drive authorization now prompts you to reconnect instead of showing "no backups yet"; a dropped network request during a backup or restore no longer freezes the progress bar silently (you get a clear error + retry path); a mistyped notification email is no longer saved silently; cancelling at Google's consent screen is handled gracefully; backup-download errors are now friendly with a back link.
  • *Settings (R3):* added Notification-Email and Backup-Type help tooltips, a copy-paste real-cron helper, a friendlier Google Drive destination display, and clearer "Backups to Keep" / "Migration Tools" / file-exclusion copy.
  • *Polish (R4/R5):* modern navigation guard during in-progress backups, a green "saved" confirmation, and all admin brand colors moved onto the shared design-token system (so the warning color is now consistent across both backup plugins). Build pipeline excludes editor/OS cruft from the distributed zip.
v6.15.0
  • Fixed: Staging directory now has a graceful fallback when `/var/lib/bodholdt-staging/` isn't writable. Pre-v6.15.0 the plugin defaulted `BODHOLDT_GDRIVE_DIR` to `/var/lib/bodholdt-staging/gdrive/<random-suffix>/` with no fallback — a path that only exists on operator-prepared hosts. On any host without root access (most managed WordPress hosts, every local development environment, every WP.org reviewer install), the `mkdir()` call returned false, the next `fopen()` failed silently, and the backup or restore died mid-flight with the AJAX progress indicator simply disappearing at "Fetching Download link…" — no error to the user. v6.15.0 adds a three-tier fallback hierarchy resolved at plugin-load time: (1) `/var/lib/bodholdt-staging/gdrive/<suffix>/` if writable (preserves the post-2026-05-05 security model on operator-prepared hosts), (2) `sys_get_temp_dir() . '/bodholdt-staging-gdrive/<suffix>/'` if `/var/lib/` isn't writable (system temp, ephemeral but still isolated from the web document root), (3) `wp-content/uploads/.bodholdt-staging-gdrive/<suffix>/` as a last resort with three hardening layers (an `.htaccess` deny-all rule for Apache, an `index.php` returning HTTP 403 as defense-in-depth, and a docs-recommended nginx `location` deny rule in the FAQ). Each fallback transition is logged via `error_log()` so operators on hardened hosts can see why the plugin moved off the primary. Override via `define('BODHOLDT_GDRIVE_DIR', __DIR__ . '/your/custom/path/')` in wp-config.php to bypass the resolution entirely. Plan §4.5.13.
  • Fixed: Backup engine was silently omitting WordPress drop-ins (`object-cache.php` / `advanced-cache.php` / `db.php` / `maintenance.php`) at the root of `wp-content/`. v6.14.1 closed the matching gap for `wp-content/mu-plugins/` and v6.14.2 closed the matching gap on the restore side for drop-ins, but the backup engine itself never added drop-ins to the zip — its scope-dirs helper enumerates directories only, and drop-ins are single files. v6.14.2's restore-side `is_file()` guard masked the gap by degrading quietly (file missing from temp dir → no error → drop-in silently absent from the destination). v6.15.0 adds an unconditional drop-ins block to the backup engine (symmetric to v6.14.1's mu-plugins always-include treatment) with `is_file()` guards so installs without drop-ins degrade quietly. Drop-ins now ride through end-to-end on the backup/restore round-trip. Plan §4.5.19.
v6.14.2
  • Fixed: Restore engine was silently dropping `wp-content/mu-plugins/`, `wp-content/languages/`, and WordPress drop-ins (object-cache.php / advanced-cache.php / db.php / maintenance.php). v6.14.1 closed the matching backup-side gap so mu-plugins now ride along inside the zip — but the restore engine still only copied `themes/`, `plugins/`, and `uploads/` from the extracted backup to the destination's `wp-content/`. Result: any disaster-recovery restore from any prior version landed a site without its must-use plugins (custom auth handlers, debug-log filters, multisite-shared utilities, etc.) and without its drop-ins (Redis object cache, full-page cache, custom DB layer, maintenance-mode override). The restore engine now treats `mu-plugins/` and `languages/` like the database — always copied, no user-facing scope toggle — and copies the four standard wp-content drop-ins when they're present in the backup. Surfaced 2026-05-17 night during the §4.5.10 GDrive end-to-end retest. Plan §4.5.15.
  • Fixed: Restore engine no longer unconditionally drops your other Bodholdt backup plugin. Prior versions hard-skipped both `bodholdt-google-drive-backup` AND `bodholdt-onedrive-backup` directories during restore. The self-skip is necessary (a plugin can't safely overwrite itself mid-execution), but the sibling-skip meant customers running both plugins as belt-and-suspenders backup would lose one on every restore. The restore engine now skips the sibling only when it's currently network-active (i.e. running and could collide); installed-but-inactive siblings are restored normally. Plan §4.5.18.
v6.14.1
  • Fixed: `wp-content/mu-plugins/` was silently omitted from every backup. The backup engine's scope-dirs helper enumerated four directory scopes — `core` (wp-admin + wp-includes only), `themes`, `plugins`, and `uploads` — but had no entry for mu-plugins. Result: every GDrive backup zip was missing must-use plugins entirely. Restoring from one of these backups would leave the destination site without any of its mu-plugins (custom auth handlers, debug-log filters, multisite-shared utilities, etc.), silently corrupting site behavior. Surfaced 2026-05-17 during the §4.5.5 GDrive parity retest — OneDrive's wholesale ABSPATH `core` scan picked them up as a side effect, masking the bug across plugins until this retest. Fix: mu-plugins are now treated like the database — always included, no user-facing scope toggle, no way to accidentally omit. Plan §4.5.11.
  • Note on Bodholdt Backup for OneDrive: Bodholdt Backup for OneDrive v5.14.0 is not affected. Its `core` scope walks `ABSPATH` wholesale with skip-prefixes for plugins/themes/uploads, so mu-plugins were already included via the wider walk. No OneDrive hotfix is required.
v6.14.0
  • New: Welcome step added to the setup wizard. The wizard now opens on a friendly Welcome screen ("Let's get your site backed up to Google Drive in just a few steps") instead of dropping the user straight into a Client ID / Client Secret form. The 3-step shape becomes 4-step: Welcome → Connect Google Drive → Schedule → Run First Backup. Mirrors the new Bodholdt Backup for OneDrive v5.14.0 wizard structure for cross-plugin consistency. Closes Steve Jobs pass Round 1. P1-B + P1-C.
  • New: Wizard JS state machine refactored. Step navigation is now driven by a single `showWizardStep(n)` helper that handles step visibility, dot indicators, and the step-counter text consistently. The previous per-step JS handlers had subtle drift; this refactor unifies them.
v6.13.0
  • New: "Set up" link on the Plugins page. After activating, a "Set up" / "Backups" quick-link now appears next to Activate/Deactivate in the WordPress Plugins list, giving you one-click access to the dashboard. Standard WP pattern; we should have shipped this in v4. Steve Jobs pass Round 1, P1-A.
  • New: Friendlier setup-guide language. Wizard welcome copy and the OAuth Setup Guide on Settings have been rewritten to drop "Google Cloud credentials" / "Google Cloud Console" jargon in favor of consumer-friendly framing ("free Google project", "Google Cloud (free)") that explains *why* each step is needed. Technical terms ("Client ID", "Client Secret", "Redirect URI") stay where they're necessary, but the welcome copy no longer reads like enterprise IT. P1-D.
  • New: OAuth consent-screen step is now correctly ordered. The Setup Guide previously listed "Configure Consent Screen (if prompted)" as Step 4, but Google requires consent-screen configuration before they'll let you create credentials at all — so it's *always* prompted on a new project, not optional. The step is now Step 3 (before Create Credentials), the "if prompted" misleading wording is gone, and the External-vs-Internal user-type choice is called out explicitly. P2-C.
  • New: OAuth Setup Guide Step 5 is split into Save + Authorize. The old single step packed three actions ("paste, save, authorize") into one line, and new users routinely missed the second click. Now Step 5 saves the credentials and Step 6 authorizes the connection. P2-D.
v6.12.1
  • Fixed: "Could not calculate estimate" error on the dashboard. The pre-flight size estimator's "Core Root Files" section called `new DirectoryIterator($root)` against a never-defined variable, which threw a PHP fatal on every dashboard load and the Refresh Estimate button. Vestigial reference left over from the v6.10 `getSubPathname()` refactor. Defined `$root` from `ABSPATH` the same way the scope-dirs helper does. Single-line fix, no behavior change beyond the estimate now actually rendering. OneDrive was unaffected (its core-scope walk handles root files in the main iterator).
v6.12.0
  • Fixed: Multisite retention manifest + retention setting were per-blog (architectural). The retention manifest (`bodholdt_gdrive_backup_ids`) and the configured backup-retention count (`bodholdt_gdrive_retention`) were stored as per-blog WordPress options, but the Google Drive folder they track is per-account — shared across every blog in the network. On multisite installs, a customer who activated the plugin from a non-main blog would hit a manifest scoped to that blog only; subsequent backup runs under a different blog context could see an empty manifest, skip the cap enforcement, and let the cloud grow silently past the configured retention. Both values are now stored as network-wide `site_option`s, mirroring the v6.8.0 license-storage migration. A one-time on-upgrade helper merges every existing blog's manifest into a single network manifest (de-duped by Drive file ID, so no data loss) and promotes the main blog's retention setting to network scope. Single-site installs are unaffected (`site_option` transparently falls back to `option` there). Plan §4.2 v6.12.
  • Fixed: Manifest seed could only run once per install (Bug C). The function that reconciles the manifest against the actual cloud folder was gated by `if ( ! empty( manifest_get() ) ) return;` — meaning seed only ran ONCE in the install's lifetime, the first time the manifest was empty. After that, no source of cloud↔manifest desync (manual operator file ops, pre-v6.1.1 backups inherited at upgrade time, etc.) could ever self-heal. Surfaced 2026-05-16 when Kyle's GDrive showed 9 files vs configured retention of 7 — 7 pre-v6.1.1 backups were already in the cloud at v6.1.1 install time, the first new backup populated the manifest, the seed never ran again, and the 7 pre-existing orphans were never caught. The function is now a reconciliation pass that runs every enforcer call. Healthy installs pay zero option writes per pass. Plan §0a 2026-05-16 evening.
  • Improved: HTTP-status logging in the manifest reconcile pass. Non-2xx Drive API responses are now logged to `error_log()` with the status code + body excerpt, matching the parity hardening already shipped on OneDrive in v5.11.1.
  • Improved: Uninstall now cleans up the network-scoped options + transients introduced in v6.8 (license keys) and v6.12 (manifest + retention).
v6.11.0
  • New: Cross-engine collation portability. Backups taken on MariaDB 10.10+ (which defaults to the `utf8mb4_uca1400_*` collation family) now restore cleanly on MySQL 5.7 / 8.x and older MariaDB. The dump rewrites every `*_uca1400_*` collation to the closest portable equivalent (`utf8mb4_unicode_520_ci`, `utf8mb3_unicode_ci`, etc.) at emit time across CREATE TABLE / VIEW / TRIGGER / PROCEDURE / FUNCTION / EVENT statements. Set option `bodholdt_gdrive_translate_collations` to 0 if you need byte-for-byte fidelity (e.g., restoring back to the same MariaDB version).
  • New: Progress bar resumes on page reload. Refresh the WP admin tab while a backup is mid-run and the progress UI now picks up where it was — bar, status text, and poll loop all re-attach automatically from the server-side job-status transient. No more "did my backup die?" anxiety.
  • New: Default-exclusion patterns for dev artifacts. `apply-bodholdt-*-v*.py`, `__pycache__/`, `*.pyc`, and `*.source.php` are now excluded by default. Pairs with the v6.10.0 readability probe — the probe defends against batch-poisoning regardless, but pre-excluding keeps the manifest tidy and the zip leaner.
v6.10.0
  • Fixed: Backup-engine drops Bodholdt-prefixed plugins/theme on symlinked-deploy patterns. Common deploy pattern (a separate clone of in-house plugins symlinked into `wp-content/plugins/`) used to silently drop those plugins from backup zips. Three independent root causes contributed; all three close in this release. Plan §4.5.6.
  • 1. The relpath calc used `getRealPath()` + `substr($path, strlen(ABSPATH))`, which on symlinked subtrees returned paths outside ABSPATH and produced corrupted relpath entries (e.g., `oldt/bodholdt-wordpress/plugins/...`). Replaced with `RecursiveIteratorIterator::getSubPathname()` (iteration-depth-tracked, symlink-safe) plus a per-scope `relpath_prefix` (`wp-content/plugins/` etc.). `bodholdt_gdrive_get_scope_dirs()` now returns each entry shaped as `[ 'path', 'relpath_prefix' ]` (back-compat-tolerant of older callers passing plain-string paths).
  • 2. PHP's `RecursiveDirectoryIterator::hasChildren()` defaults to `$allowLinks = false`, so the iterator emits symlinked DIR entries but never descends into them — the entire symlinked subtree gets skipped silently. Fixed via a small RDI subclass (`Bodholdt_Gdrive_FollowSymlink_RDI`) that overrides `hasChildren()` to pass `$allowLinks=true`.
  • 3. `ZipArchive::close()` silently drops the entire ~500-file staged batch when even one staged file is unreadable. Pre-validate readability with `@fopen($path, 'rb')` + `fclose()` before `addFile()`; unreadable files are skipped cleanly with optional `WP_DEBUG` logging. `addFile()` and `close()` return values are also checked + logged.
  • Fixed: VIEW emission order regression in multisite-network mode. v6.9.0 emitted each blog's views at the end of that blog's iteration, BEFORE the network-shared group ran. Views that JOIN `wp_users` (network-shared) failed at CREATE time on restore because wp_users hadn't been created yet. All non-table schema objects (views, triggers) are now deferred to the absolute tail of the dump, after every CREATE TABLE across every blog + the network-shared group. Plan §4.5.8.
  • New: Proper self-exclusion. The backup zip no longer includes the Bodholdt Backup for Google Drive plugin's own directory (Russian-doll prevention). Sibling Bodholdt plugins and the bodholdt-labs theme are deliberately INCLUDED so customers with multiple Bodholdt plugins get a complete backup. Self-exclusion uses canonical-relpath equality, not name-prefix substring matching.
  • New: Unreadable files are skipped cleanly instead of poisoning a 500-file batch. Previously, ZipArchive's deferred-read behavior meant a single 0600/0700 file could silently drop dozens of unrelated legitimate backups. The pre-`addFile` readability probe defends against this regardless of what's on disk.
v6.9.0
  • New: Multisite-network backup mode (Free-tier-included). The backup engine now auto-detects single-site vs multisite and defaults to a complete-network backup on multisite installs. Network mode walks every blog via `switch_to_blog()`, dumps each blog's content tables, then dumps the network-shared tables (`wp_users`, `wp_usermeta`, `wp_blogs`, `wp_blogmeta`, `wp_site`, `wp_sitemeta`, `wp_registration_log`, `wp_signups`) exactly once. Restoring such a backup recreates the full multisite layout.
  • New: Per-blog mode (opt-in). Multisite admins who want per-customer subsite isolation can switch to per-blog mode in the network admin's Settings tab. Per-blog backups contain only that blog's content tables.
  • New: Backup manifest (`bodholdt-manifest.json`). Every zip now includes a manifest describing mode, plugin version, WP version, blog topology, tables dumped, and shared-table inclusion. The restore engine reads it first.
  • New: Restore-side mode compatibility check. Refuses incompatible mode combos (multisite backup → single-site target) to prevent orphan tables.
  • Single-site installs unchanged — no UI changes, no feature flag, no migration required.
v6.8.0
  • New: Multisite-network compatible. License state (key, tier, status, last-seen-valid timestamp) is now stored as a network-wide site option. A customer who activates a Solo license on blog 1 of a multisite network has the license recognized automatically on every other blog. One-time migration runs on upgrade.
  • Single-site installs are unaffected.
v6.7.0
  • New: Slack and Discord webhook notifications (Pro+). One URL field, auto-detected provider. Per-event toggles for backup success, backup failure, restore initiated, and watchdog stale-alert. Send-Test-Notification button in Settings.
  • New: Helper `bodholdt_gdrive_notifications_allowed()` returns true only for Pro/Bundle. Filterable for one-off overrides.
  • Failure notifications include the same auto-diagnosis hint as the email notification.
v6.6.0
  • New: Free tier is now the default experience. No license required for full backup + restore at the Free cap (10 retained).
  • New: Tier badge inline in the plugin header (Free / Solo / Pro / Bundle).
  • New: Lapse banner — when a previously-active license becomes invalid, a dismissible banner reminds you to renew while backups continue at Free-tier limits.
  • New: Soft-degrade on lapse — backups keep running even with an invalid license. Retention auto-clamps to 10; selective restore disables.
  • Removed: Three hard-locks that previously blocked the admin UI, manual backups, and scheduled backups on non-valid licenses.
  • Setup wizard now also surfaces to Free users for OAuth-flow guidance.
v6.4.0
  • New: Tier-gated selective restore. Pro and Bundle customers can choose what to restore (database, plugins, themes, uploads, core). Free + Solo restore everything.
  • New: Inline "Upgrade to Pro" hint shown next to disabled scope chooser on Free + Solo.
  • Server-side defense: restore handler coerces submitted scope to full on tiers without selective access.
v6.3.0
  • New: Tier-aware retention cap helper. Free=10 / Solo=50 / Pro=100 / Bundle=100. Save handler clamps; settings input cap is dynamic.
  • New: Over-cap inline notice when a previously-saved retention value exceeds the current tier cap (e.g., after a downgrade).
  • New: Pre-flight `force_refresh()` before retention enforcement so tier downgrades take effect within one backup, not 12 hours later.
  • Licensing client now captures `tier_key` from server responses.
v6.1.1
  • Critical fix: added backup-filename allowlist to retention enforcement. Previously the enforcer listed every child of the backup folder; user-dropped files in `Bodholdt Backups/<site>` could have been auto-deleted. Now the enforcer uses an ID-manifest written at upload time plus a filename regex check.
  • New: One-time seed migration on upgrade for existing backups.
v6.1.0
  • New: Watchdog last-success timestamp with stale-alert.
  • New: Out-of-web-root staging directory.
v6.0.0
  • New: Multipart-leak fix in email rendering.
v5.12.0
  • Security hardening — strict base64 decoding, WP_DEBUG-gated error logs, Windows zip-path validation, OAuth state-transient race fix, path-traversal protection in uninstall, API response structure validation, hex-format validation on directory suffix.
  • GPL-2.0-or-later license file added. Languages directory added. CHANGELOG.md added.
v5.11.0
  • Incremental backup mode. Selective backup scope. Setup wizard. Test email. Force unlock for stuck backup processes.
v5.10.0
  • Selective restore. Sentinel-based SQL statement splitting. Pre-restore safety snapshot.
v5.9.0
  • Sodium encryption support. HMAC-authenticated AES-256-CBC. Dark cyberpunk admin theme.
v5.8.0
  • Resumable chunked upload to Google Drive. Backup retention policy with automatic cleanup. Email notifications.
v5.7.0
  • Migration installer (standalone restore tool). Custom file/folder exclusions. Scheduled backups.
v5.0.0
  • Initial release with Google Drive integration.
After purchase, you'll receive a download link and license key by email. In your WordPress admin, go to Plugins → Add New → Upload Plugin, choose the ZIP you downloaded, click Install, then Activate. The plugin will prompt you for your license key on its settings page. Paste it in and you're live.
A single WordPress install with a unique domain. Subdomains, staging clones, and dev environments don't count against your site limit as long as they're flagged as non-production in the plugin settings.
Yes. Stripe pro-rates the difference. If you bought Solo in January and upgrade to Pro in April, you pay the prorated difference between Pro and Solo for the remaining 8 months. Lifetime-to-lifetime upgrades just pay the difference.
At renewal, yes. Pick a lower tier when your license is up. We don't refund the difference for mid-cycle downgrades.
Lifetime means lifetime of the product. You pay once, you get updates and your license stays active forever. Lifetime licenses also include a bucket of support credits that never expire, so you always have a way into support. If we ever sunset a product (announced 12 months in advance), lifetime customers get a free transfer to the equivalent successor.
Yes. Stripe handles cancellation in one click from your account dashboard. You keep access until the end of the billing period.
14 days, no questions asked, full refund. Open a ticket on our Support page (bodholdtlabs.com/support) using the email you bought with.
Two reasons: Stripe's per-transaction fees compound when you charge 12 times instead of once, and monthly subs have higher churn risk for us. Annual or lifetime is the better deal if you know you're sticking around.
One purchase gives you two separate license keys, one for each plugin (Bodholdt Backup for Google Drive and Bodholdt Backup for OneDrive), both at the 5-site Pro tier. You activate each plugin independently. If you cancel, both licenses expire at the same time.
The Agency tier covers unlimited sites for $129/yr, which is already below what most agencies pay for one site of competing plugins. If you need invoicing, an MSA, or a multi-product enterprise bundle, open a ticket on our Support page (bodholdtlabs.com/support) and we'll work something out.
A free edition is on its way to the WordPress.org directory. Until it's approved, the 14-day money-back guarantee is your trial: buy it, try it, and refund within 14 days if it doesn't work.