Daily snapshot backups in 6 lines, no tools
Forget paid backup add-ons. rsync with
—
— rotate: keep 7,
30 days of daily 'full' backups of a 2GB site can fit in ~3GB because only the deltas are real. Push to a $1.50 storage box. Cheapest insurance you'll ever buy. Try it tonight.
Forget paid backup add-ons. rsync with
--link-dest gives you hardlinked snapshots: every day looks like a full copy, but unchanged files cost zero extra disk.—
rsync -a --link-dest=/bak/prev /var/www /bak/$(date +%F)— rotate: keep 7,
rm -rf the oldest30 days of daily 'full' backups of a 2GB site can fit in ~3GB because only the deltas are real. Push to a $1.50 storage box. Cheapest insurance you'll ever buy. Try it tonight.
'Connection refused' under load and it's NOT your app
Box is fine, app is fine, but new connections randomly drop during a traffic spike. Check dmesg for
—
— or drop conntrack entirely for stateless web traffic if you don't need it
Default max on a small box is tiny. This is the invisible ceiling that makes people 'upgrade their VPS' when they didn't need to. Try it tonight.
Box is fine, app is fine, but new connections randomly drop during a traffic spike. Check dmesg for
nf_conntrack: table full. The kernel's connection-tracking table maxed out and started dropping packets silently.—
sysctl net.netfilter.nf_conntrack_max=131072— or drop conntrack entirely for stateless web traffic if you don't need it
Default max on a small box is tiny. This is the invisible ceiling that makes people 'upgrade their VPS' when they didn't need to. Try it tonight.
Stop compressing the same file on every request
nginx gzip is fine, but it re-compresses your CSS on every single hit, burning CPU you don't have on a cheap box. Pre-compress static assets ONCE at deploy time:
—
— enable
Now nginx serves the
nginx gzip is fine, but it re-compresses your CSS on every single hit, burning CPU you don't have on a cheap box. Pre-compress static assets ONCE at deploy time:
—
find dist -name '*.css' -o -name '*.js' | xargs gzip -9 -k— enable
gzip_static on; in nginxNow nginx serves the
.gz file straight off disk, zero CPU per request. Add brotli precompression too if your build supports it. CPU dropped, and the bytes on the wire are smaller because you used -9. Try it tonight.Admin CPU dropped 35% by throttling WP heartbeat
Just did this on a $6 box where two editors working in wp-admin would spike PHP-FPM. Heartbeat was firing autosave/lock AJAX every 15s per open tab.
Throttled it in a mu-plugin:
—
— set interval to 60s in admin, killed it on post-edit lock checks
Those constant admin-ajax.php POSTs fell ~75%. PHP-FPM CPU during editing dropped ~35%, no more spikes when both editors were live. Front-end never needed heartbeat at all.
Try it tonight.
—
Если log analysis tools — твоя тема, посмотри @LogfileRoundup
Just did this on a $6 box where two editors working in wp-admin would spike PHP-FPM. Heartbeat was firing autosave/lock AJAX every 15s per open tab.
Throttled it in a mu-plugin:
—
wp_deregister_script('heartbeat') on front-end— set interval to 60s in admin, killed it on post-edit lock checks
Those constant admin-ajax.php POSTs fell ~75%. PHP-FPM CPU during editing dropped ~35%, no more spikes when both editors were live. Front-end never needed heartbeat at all.
Try it tonight.
—
Если log analysis tools — твоя тема, посмотри @LogfileRoundup
Your nginx is stat()-ing the same file 10k times
Just did this on a $5 box: 80 static sites, disk was wheezing on every request. The fix nobody mentions is
—
—
—
nginx stops hitting the kernel for the same file descriptor on repeat hits. CPU on the box dropped from 40% to 9% serving the same traffic. Costs you nothing. Try it tonight.
Just did this on a $5 box: 80 static sites, disk was wheezing on every request. The fix nobody mentions is
open_file_cache. Drop this in the http block:—
open_file_cache max=10000 inactive=60s;—
open_file_cache_valid 80s;—
open_file_cache_errors on;nginx stops hitting the kernel for the same file descriptor on repeat hits. CPU on the box dropped from 40% to 9% serving the same traffic. Costs you nothing. Try it tonight.
More swap won't save a 1GB box. Lower swappiness will.
Everyone adds a 4GB swapfile and calls it done. On a 1GB VPS that just means your MySQL gets paged to disk and the site crawls. The real knob:
—
—
Make it stick in
Everyone adds a 4GB swapfile and calls it done. On a 1GB VPS that just means your MySQL gets paged to disk and the site crawls. The real knob:
—
sysctl vm.swappiness=10 (default is 60, way too eager)—
sysctl vm.vfs_cache_pressure=50Make it stick in
/etc/sysctl.d/99-swap.conf. Now the kernel keeps your hot pages in RAM and only swaps as a real last resort. Same $5 box, page loads went from 1.8s to 400ms under load. Try it tonight.The fail2ban jail that actually stops bot armies
Basic sshd jail bans for 10 min, then the same IP comes back forever. Enable the recidive jail: it watches fail2ban's own log and nukes repeat offenders for a week.
—
—
—
—
—
IP gets banned 5 times in a day across any jail, it's gone for 7 days. My auth.log went from 3k lines a night to nearly silent. Try it tonight.
Basic sshd jail bans for 10 min, then the same IP comes back forever. Enable the recidive jail: it watches fail2ban's own log and nukes repeat offenders for a week.
—
[recidive]—
enabled = true—
bantime = 1w—
findtime = 1d—
maxretry = 5IP gets banned 5 times in a day across any jail, it's gone for 7 days. My auth.log went from 3k lines a night to nearly silent. Try it tonight.
