A cPanel backup that only lives on the same disk as the accounts it protects is not a backup. WHM’s built-in backup system can push daily, weekly and monthly archives to an S3-compatible bucket with no third-party software, and on current builds (134 LTS and 138 RELEASE) the transport works with any provider that speaks the S3 API and accepts path-style or virtual-host-style requests. This guide walks through the configuration, the settings that matter for cost and speed, and, more importantly, a restore test.
Applies to cPanel & WHM 134 LTS and 138 RELEASE
Table of Contents
Short answer: In WHM » Backup » Backup Configuration, choose Compressed backups with account, system and per-account database options, then add an S3 Compatible destination with the bucket, endpoint, region and keys and click Save and Validate Destination. Trigger /usr/local/cpanel/bin/backup --force, watch cpbackup_transporter.log for a successful upload, and prove the result by restoring a small account with /scripts/restorepkg and checking its site, mail and database.
Prepare the bucket and credentials
Create a dedicated bucket per server, not one shared bucket for your whole fleet. A per-server bucket makes lifecycle rules and access keys easy to revoke if a server is compromised. Generate an access key pair that is limited to that bucket with list, get, put and delete permissions; WHM needs delete rights to prune old backups.
Note the endpoint hostname and region string for your provider. Examples of the form you will need:
- Wasabi:
s3.eu-central-1.wasabisys.com, regioneu-central-1 - Backblaze B2:
s3.us-west-004.backblazeb2.com, regionus-west-004 - MinIO or Ceph RGW: your own hostname, region can usually be
us-east-1
If the provider requires path-style addressing, keep that in mind; WHM exposes a toggle for it in the destination form.
Configure the backup schedule in WHM
Open WHM » Backup » Backup Configuration. The choices that matter most on a shared server:
- Backup Type: Compressed is the safe default. Incremental is faster and uses hard links, but incremental backups cannot be sent to remote destinations, so choose Compressed or Uncompressed for S3.
- Daily/Weekly/Monthly retention: keep at least three daily and one weekly locally, and let the remote destination hold longer retention.
- Retain backups in the default backup directory: enable this only if you have the local disk. If the server is tight on space, disable it and the local copy is removed after a successful upload.
- Backup Accounts / System Files / Databases: enable all three. “Per account only” for databases keeps user databases inside each account archive, which is what you want for single-account restores.
Set the same values from the shell if you manage many servers:
whmapi1 backup_config_set backupenable=1 backuptype=compressed backupdays=0,1,2,3,4,5,6 backup_daily_retention=3 backup_weekly_enable=1 backup_weekly_retention=2 backupaccts=1 backupsuspendedaccts=1 backupdirs=1 backupmysql=accounts keeplocal=1
Add the S3-compatible destination
Still in Backup Configuration, scroll to Additional Destinations, choose S3 Compatible and click Create new destination. Fill in a name, the bucket, the endpoint hostname, the region, and the access and secret keys. Leave the folder field empty or set it to the server’s hostname so several servers can share one account cleanly. Set a timeout of at least 300 seconds; large account archives on slow uplinks will otherwise abort.
Click Save and Validate Destination. Validation writes a small test object to the bucket and deletes it. If it fails, the error string tells you whether it is a DNS, TLS, signature or permission problem.
The equivalent API call, useful for Ansible or a provisioning script:
whmapi1 backup_destination_add name='offsite-s3' type='S3Compatible' bucket='srv01-backups' host='s3.eu-central-1.wasabisys.com' region='eu-central-1' aws_access_key_id='AKIA...' password='SECRET' timeout=300 disabled=0
whmapi1 backup_destination_validate id='<id returned above>'
Run a backup now and watch it
Do not wait for the 01:00 cron. Trigger a run in the foreground so you can see the transport working:
/usr/local/cpanel/bin/backup --force
tail -f /usr/local/cpanel/logs/cpbackup/$(date +%Y-%m-%d)*.log
The log shows each account being packaged and then queued for transport. Transport itself is handled by a separate process; its log is /usr/local/cpanel/logs/cpbackup_transporter.log. A healthy upload line ends with the object key in the bucket. Watch for 403 responses (clock skew or wrong secret) and RequestTimeTooSkewed, which means the server clock is out; fix with chronyc makestep.
A common pitfall is the upload queue silently stalling because the destination was created while disabled, or because keeplocal=0 combined with a failed upload leaves you with nothing at all. Until you have seen one full successful cycle, keep the local copy.
Test a restore, not just the backup
A backup you have never restored is a hypothesis. Pick a small, low-risk account and run through the full path. In WHM » Backup » Backup Restoration, select the account, choose a date, and restore to the same server with a different username if you want to keep the original untouched, or restore to a staging server that has the same destination configured.
From the shell, the equivalent is to fetch the archive from the bucket and restore it:
/scripts/restorepkg --force /home/cpbackup-restore/backup-2026-09-28_testacct.tar.gz
Then log in as the account, open the site, check a mailbox, and run a quick database sanity check:
mysql -e "SELECT COUNT(*) FROM testacct_wp.wp_posts;"
We also recommend the backup-verify script to check archive integrity across every account automatically rather than by sampling.
Keep it running
Schedule a monthly restore drill and record the result. Set a lifecycle rule on the bucket so objects older than your longest retention are expired by the provider, which stops surprise storage bills. Enable the backup failure notification under WHM » Contact Manager and route it to a mailbox someone reads. Finally, review whmapi1 backup_destination_list after every major cPanel upgrade; destination settings rarely break, but the transporter code does change between tiers, and one quick validation after upcp is cheap insurance. If you would rather have this monitored and drilled for you, our managed services cover it.
WHM backups S3 at a glance

Official documentation: cPanel & WHM documentation, Linux man pages.
Related guides: Deploying a Node.js app with cPanel’s AI-Native Node.js Toolkit · Whitelisting MailBaby in cPanel greylisting, CSF and SpamAssassin · AutoSSL failed: fixing DCV errors, CAA records, CDN proxies and blocked /.well-known/.
Frequently asked questions
Can WHM send incremental backups to S3?
No. Incremental backups rely on hard links and can only be kept locally, so a remote S3 destination needs the Compressed or Uncompressed backup type. Compressed is the usual choice because it reduces transfer time and storage cost.
Does WHM work with Wasabi, Backblaze B2 and MinIO?
Yes. The S3 Compatible destination type accepts any provider that speaks the S3 API; supply the provider’s endpoint hostname and region string, and enable path-style addressing if the provider requires it.
How often should I test restoring a WHM backup?
Monthly is a sensible minimum, with a restore of one small account to the same or a staging server, plus a check of the site, a mailbox and a database query. Also run a validation after every major cPanel upgrade, because the transporter code changes between tiers.
Maintenance record
This guide changes servers, data or security settings, so we re-check it against current versions on a fixed schedule. Take a backup or snapshot before you start.
- Maintained by
- srvScripts editorial team
- Supported versions
- cPanel & WHM 134 LTS and 138 RELEASE
- Last full review
- Next review
- Sources
- docs.cpanel.net