{"id":4293,"date":"2026-09-12T15:40:53","date_gmt":"2026-09-12T10:10:53","guid":{"rendered":"https:\/\/cpanelfree.com\/blog\/how-to-use-rsync-over-ssh-server-backups-guide\/"},"modified":"2026-09-12T15:41:11","modified_gmt":"2026-09-12T10:11:11","slug":"how-to-use-rsync-over-ssh-server-backups-guide","status":"publish","type":"post","link":"https:\/\/cpanelfree.com\/blog\/how-to-use-rsync-over-ssh-server-backups-guide\/","title":{"rendered":"How to Use Rsync Over SSH for Automated Server-to-Server Backups and Sync"},"content":{"rendered":"<div style=\"background-color: #0f172a;border-left: 4px solid #38bdf8;padding: 18px 22px;margin-bottom: 25px;border-radius: 6px\">\n  <strong style=\"color: #38bdf8;font-size: 16px\">Quick Technical Answer:<\/strong><\/p>\n<p style=\"color: #cbd5e1;margin: 8px 0 0 0;font-size: 15px;line-height: 1.6\">\n    To synchronize files securely between two Linux VPS servers over SSH, use the standard command: <code>rsync -avzP -e \"ssh -p 22\" \/local\/source\/ user@remote_ip:\/remote\/destination\/<\/code>. The flags <code>-a<\/code> preserves permissions and timestamps, <code>-v<\/code> enables verbose output, <code>-z<\/code> enables gzip transmission compression, and <code>-P<\/code> preserves partial transfers with a live progress bar. To make it automated, use passwordless Ed25519 SSH keys and schedule it inside <code>crontab<\/code>.\n  <\/p>\n<\/div>\n<h2>Why Rsync Remains the King of Linux Backup &amp; Migration Utilities<\/h2>\n<p>When moving large datasets\u2014such as multi-gigabyte WordPress media uploads, database dumps, and application assets\u2014between cloud servers, traditional tools like FTP, SCP, or raw tar archives transfer every single byte sequentially. If a 10GB transfer is interrupted at 99%, standard SCP forces you to re-upload the entire file from scratch.<\/p>\n<p><strong>Rsync (Remote Sync)<\/strong> revolutionized data synchronization by introducing the rolling checksum <strong>delta-transfer algorithm<\/strong>. Rsync compares the source and destination directories, identifies which blocks of a file have changed, and transfers <em>only the differential byte changes<\/em>. If a 5GB database backup file only has 50MB of new entries, rsync transmits only that 50MB delta\u2014slashing transfer times and bandwidth bills by over 95%.<\/p>\n<p>Tunneling rsync through an encrypted SSH connection provides end-to-end cryptographic protection, ensuring credentials and proprietary web assets cannot be intercepted in transit.<\/p>\n<h2>Step 1: Anatomy of Essential Rsync Flags<\/h2>\n<p>Understanding rsync flags prevents catastrophic data loss errors (such as accidentally wiping destination files):<\/p>\n<table style=\"width: 100%;border-collapse: collapse;margin: 25px 0;font-size: 14px;text-align: left\">\n<thead>\n<tr style=\"background-color: #0f172a;color: #38bdf8\">\n<th style=\"padding: 12px;border: 1px solid #334155\">Flag<\/th>\n<th style=\"padding: 12px;border: 1px solid #334155\">Full Parameter<\/th>\n<th style=\"padding: 12px;border: 1px solid #334155\">Operational Function<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr style=\"background-color: #1e293b;color: #f8fafc\">\n<td style=\"padding: 10px;border: 1px solid #334155\"><code>-a<\/code><\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\"><code>--archive<\/code><\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\">Archive mode; preserves file permissions, ownership, symlinks, timestamps, and recursively traverses subdirectories.<\/td>\n<\/tr>\n<tr style=\"background-color: #0f172a;color: #cbd5e1\">\n<td style=\"padding: 10px;border: 1px solid #334155\"><code>-v<\/code><\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\"><code>--verbose<\/code><\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\">Provides detailed console output listing each file being transferred.<\/td>\n<\/tr>\n<tr style=\"background-color: #1e293b;color: #f8fafc\">\n<td style=\"padding: 10px;border: 1px solid #334155\"><code>-z<\/code><\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\"><code>--compress<\/code><\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\">Compresses data in flight using zlib to minimize network bandwidth consumption.<\/td>\n<\/tr>\n<tr style=\"background-color: #0f172a;color: #cbd5e1\">\n<td style=\"padding: 10px;border: 1px solid #334155\"><code>-P<\/code><\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\"><code>--partial --progress<\/code><\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\">Shows a live progress bar and preserves partially transferred files so interrupted jobs resume without restart.<\/td>\n<\/tr>\n<tr style=\"background-color: #1e293b;color: #f8fafc\">\n<td style=\"padding: 10px;border: 1px solid #334155\"><code>--delete<\/code><\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\">Mirror deletion<\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\">Deletes files on the remote destination if they no longer exist on the source, creating an exact mirror.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Step 2: The Critical Trailing Slash Rule<\/h2>\n<div style=\"background-color: #1e293b;border-left: 4px solid #f59e0b;padding: 15px;margin: 20px 0;border-radius: 6px\">\n  <strong style=\"color: #f59e0b\">WARNING: The Trailing Slash Changes Behavior Completely!<\/strong><\/p>\n<p style=\"color: #cbd5e1;margin: 5px 0 0 0;font-size: 14px\">\n    <code>rsync -a \/source\/folder \/dest\/<\/code> creates <code>\/dest\/folder\/file.txt<\/code> (copies the folder itself).<br \/>\n    <code>rsync -a \/source\/folder\/ \/dest\/<\/code> creates <code>\/dest\/file.txt<\/code> (copies only the <strong>contents<\/strong> of the folder).\n  <\/p>\n<\/div>\n<h2>Step 3: Setting Up Passwordless SSH Keys for Automation<\/h2>\n<p>To run rsync inside automated cron scripts, the source server must authenticate to the remote destination server without password prompts using high-security Ed25519 SSH keys:<\/p>\n<pre><code style=\"color: #38bdf8\"># Generate a dedicated backup keypair on the SOURCE server (no passphrase)\nssh-keygen -t ed25519 -f ~\/.ssh\/backup_key -N \"\"\n\n# Copy the public key to the REMOTE destination server\nssh-copy-id -i ~\/.ssh\/backup_key.pub -p 22 backupuser@remote_backup_ip\n\n# Test SSH connection without password\nssh -i ~\/.ssh\/backup_key -p 22 backupuser@remote_backup_ip \"echo SSH Connection Successful\"<\/code><\/pre>\n<h2>Step 4: Real-World Synchronizations with Non-Standard Ports &amp; Exclusions<\/h2>\n<p>If your remote backup server uses a hardened custom SSH port (e.g. port <code>2222<\/code>) and you want to exclude cache and temp files:<\/p>\n<pre><code style=\"color: #38bdf8\"># Rsync with custom SSH port and exclude filters\nrsync -avzP --delete   -e \"ssh -i \/root\/.ssh\/backup_key -p 2222\"   --exclude=\"wp-content\/cache\/*\"   --exclude=\"*.tmp\"   --exclude=\"node_modules\"   --bwlimit=10000   \/var\/www\/html\/   backupuser@remote_backup_ip:\/backups\/live_site\/<\/code><\/pre>\n<p><em>Note: <code>--bwlimit=10000<\/code> caps transfer speeds at 10 MB\/s, preventing rsync from saturating server bandwidth during business hours.<\/em><\/p>\n<h2>Step 5: Automated Nightly Backup Script with Crontab<\/h2>\n<p>Create a production bash backup script that logs all execution output:<\/p>\n<pre><code style=\"color: #38bdf8\">sudo nano \/usr\/local\/bin\/nightly-sync.sh<\/code><\/pre>\n<p>Insert the following automated script:<\/p>\n<pre><code style=\"color: #38bdf8\">#!\/bin\/bash\nset -e\n\nTIMESTAMP=$(date +\"%Y-%m-%d_%H-%M-%S\")\nLOG_FILE=\"\/var\/log\/rsync-backup.log\"\n\necho \"[${TIMESTAMP}] Starting Rsync Backup...\" &gt;&gt; \"$LOG_FILE\"\n\nrsync -aqz --delete   -e \"ssh -i \/root\/.ssh\/backup_key -p 22\"   --exclude=\"*.log\"   --exclude=\"cache\/*\"   \/var\/www\/html\/   backupuser@remote_backup_ip:\/backups\/current\/ &gt;&gt; \"$LOG_FILE\" 2&gt;&amp;1\n\necho \"[$(date +\"%Y-%m-%d_%H-%M-%S\")] Backup Completed Successfully.\" &gt;&gt; \"$LOG_FILE\"<\/code><\/pre>\n<p>Make the script executable and schedule it in crontab:<\/p>\n<pre><code style=\"color: #38bdf8\"># Grant execution permissions\nsudo chmod +x \/usr\/local\/bin\/nightly-sync.sh\n\n# Edit system crontab\nsudo crontab -e\n\n# Run every night at 2:30 AM\n30 2 * * * \/usr\/local\/bin\/nightly-sync.sh<\/code><\/pre>\n<h2>Frequently Asked Questions (FAQ)<\/h2>\n<div style=\"margin: 20px 0\">\n<h3 style=\"color: #38bdf8;margin-bottom: 5px\">How do I perform a safe dry run before running rsync with &#8211;delete?<\/h3>\n<p style=\"color: #cbd5e1;font-size: 15px\">Always add the <code>-n<\/code> or <code>--dry-run<\/code> flag: <code>rsync -avzPn --delete ...<\/code>. Rsync will print exact logs of which files would be transferred or deleted without touching the actual disks.<\/p>\n<h3 style=\"color: #38bdf8;margin-bottom: 5px\">Can rsync preserve extended attributes and ACLs?<\/h3>\n<p style=\"color: #cbd5e1;font-size: 15px\">Yes. Add <code>-A<\/code> (preserve Access Control Lists) and <code>-X<\/code> (preserve extended attributes\/SELinux contexts) to your rsync command flags.<\/p>\n<\/div>\n<div style=\"background-color: #0f172a;border-left: 4px solid #38bdf8;padding: 18px 24px;margin: 30px 0;border-radius: 8px\">\n<h3 style=\"color: #38bdf8;margin-top: 0\">\ud83d\udd17 Recommended Related Technical Guides<\/h3>\n<ul style=\"margin-bottom: 0;color: #cbd5e1\">\n<li><a href=\"https:\/\/cpanelfree.com\/blog\/how-to-create-connect-ssh-keys-linux-vps\/\" style=\"color: #38bdf8;text-decoration: underline\">How to Create and Connect SSH Keys to Any Linux VPS<\/a><\/li>\n<li><a href=\"https:\/\/cpanelfree.com\/blog\/how-to-change-ssh-port-linux\/\" style=\"color: #38bdf8;text-decoration: underline\">How to Change the Default SSH Port on Linux to Stop 99% of Bots<\/a><\/li>\n<li><a href=\"https:\/\/cpanelfree.com\/blog\/how-to-automate-mysql-database-backup-cron\/\" style=\"color: #38bdf8;text-decoration: underline\">Automating MySQL Database Backups with Cron Jobs<\/a><\/li>\n<\/ul>\n<\/div>\n<h2>Advanced Rsync Performance Tuning: SSH Cipher Selection &amp; 10Gbps Links<\/h2>\n<p>When synchronizing vast datasets across modern 1Gbps or 10Gbps high-bandwidth VPS networks, the default SSH encryption cipher (frequently AES-256-CTR) can bottleneck on CPU cryptographic throughput. In tests across modern multi-core Linux servers, switching the transport cipher to <strong>chacha20-poly1305<\/strong> or <strong>aes128-gcm<\/strong> increases transfer throughput by up to 45% while decreasing server CPU overhead:<\/p>\n<pre><code style=\"color: #38bdf8\"># High-throughput rsync utilizing hardware-accelerated ChaCha20 cipher\nrsync -avzP -e \"ssh -c chacha20-poly1305@openssh.com -i \/root\/.ssh\/backup_key -p 22\" \\\n  --numeric-ids \\\n  --inplace \\\n  \/var\/www\/html\/ backupuser@remote_backup_ip:\/backups\/current\/<\/code><\/pre>\n<p>The <code>--inplace<\/code> flag instructs rsync to update the destination file directly instead of writing a temporary file and moving it into place, substantially reducing disk write wear and temporary file IO overhead during massive database file syncs.<\/p>\n<h2>Troubleshooting Common Rsync Exit Error Codes<\/h2>\n<table style=\"width: 100%;border-collapse: collapse;margin: 25px 0;font-size: 14px;text-align: left\">\n<thead>\n<tr style=\"background-color: #0f172a;color: #38bdf8\">\n<th style=\"padding: 12px;border: 1px solid #334155\">Exit Code<\/th>\n<th style=\"padding: 12px;border: 1px solid #334155\">Error Description<\/th>\n<th style=\"padding: 12px;border: 1px solid #334155\">Root Cause &amp; Diagnostic Solution<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr style=\"background-color: #1e293b;color: #f8fafc\">\n<td style=\"padding: 10px;border: 1px solid #334155\"><strong>Code 12<\/strong><\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\">Error in rsync protocol data stream<\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\">SSH connection dropped unexpectedly or remote rsync binary is missing on target server. Install <code>rsync<\/code> on destination.<\/td>\n<\/tr>\n<tr style=\"background-color: #0f172a;color: #cbd5e1\">\n<td style=\"padding: 10px;border: 1px solid #334155\"><strong>Code 23<\/strong><\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\">Partial transfer due to error<\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\">Permission denied on specific destination files. Verify destination directory ownership with <code>chown -R backupuser:backupuser<\/code>.<\/td>\n<\/tr>\n<tr style=\"background-color: #1e293b;color: #f8fafc\">\n<td style=\"padding: 10px;border: 1px solid #334155\"><strong>Code 24<\/strong><\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\">Partial transfer due to vanished source files<\/td>\n<td style=\"padding: 10px;border: 1px solid #334155\">Log or cache files were deleted by an active daemon during transfer. Add <code>--exclude=\"*.log\"<\/code> to suppress warnings.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div style=\"background: linear-gradient(135deg, #0284c7 0%, #0369a1 100%);color: #ffffff;padding: 28px;border-radius: 12px;margin: 35px 0;text-align: center\">\n<h3 style=\"color: #ffffff;margin-top: 0;font-size: 22px\">Build Disaster-Resilient Backups on CpanelFree<\/h3>\n<p style=\"color: #e0f2fe;font-size: 15px;max-width: 650px;margin: 0 auto 18px auto\">Connect multiple cloud locations with unmetered private networking and pure NVMe performance on CpanelFree Cloud VPS.<\/p>\n<p>  <a href=\"https:\/\/cpanelfree.com\/\" style=\"background-color: #ffffff;color: #0284c7;font-weight: 700;padding: 12px 28px;border-radius: 8px;text-decoration: none;display: inline-block\">Deploy Your Backup Cloud Node &rarr;<\/a>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Quick Technical Answer: To synchronize files securely between two Linux VPS servers over SSH, use the standard command: rsync -avzP -e &#8220;ssh -p 22&#8221; \/local\/source\/ user@remote_ip:\/remote\/destination\/. The flags -a preserves permissions and timestamps, -v enables verbose output, -z enables gzip transmission compression, and -P preserves partial transfers with a live progress bar. To make it &#8230; <a title=\"How to Use Rsync Over SSH for Automated Server-to-Server Backups and Sync\" class=\"read-more\" href=\"https:\/\/cpanelfree.com\/blog\/how-to-use-rsync-over-ssh-server-backups-guide\/\" aria-label=\"Read more about How to Use Rsync Over SSH for Automated Server-to-Server Backups and Sync\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":4292,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[88,64,51],"tags":[],"class_list":["post-4293","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cloud-vps","category-security","category-tutorials"],"_links":{"self":[{"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/posts\/4293","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/comments?post=4293"}],"version-history":[{"count":1,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/posts\/4293\/revisions"}],"predecessor-version":[{"id":4294,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/posts\/4293\/revisions\/4294"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/media\/4292"}],"wp:attachment":[{"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/media?parent=4293"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/categories?post=4293"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/tags?post=4293"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}