Root Access Daily
20 subscribers
16 photos
1 link
Trench-level VPS tips for webmasters who SSH in and fix it themselves. Cheap droplet stacks, nginx tweaks, and the commands that saved our uptime at 3am.
Download Telegram
'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 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:

find dist -name '*.css' -o -name '*.js' | xargs gzip -9 -k
— enable gzip_static on; in nginx

Now 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:
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 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:

sysctl vm.swappiness=10 (default is 60, way too eager)
sysctl vm.vfs_cache_pressure=50

Make 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.

[recidive]
enabled = true
bantime = 1w
findtime = 1d
maxretry = 5

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.
If you're into what we post, @HostingHeresy is the natural next follow — they work the Web hosting reviews beat hard. We debunk the affiliate-fueled hosting hype. The 'best host' lists are mostly paid…
php-fpm dynamic is lying to you on a small box

Default pm = dynamic spawns and kills workers constantly, and each PHP worker eats 30-50MB. On a 2GB VPS that thrashing is your slowdown. Switch to static and do the math yourself:

pm = static
pm.max_children = 12 (12 × 40MB = 480MB, leave room for nginx+MySQL)

No spawn overhead, predictable memory, no OOM-killer surprises at 2am. Handles 8k visits/day on a $6 box without breaking a sweat. Try it tonight.
Move your PHP sessions off the disk

Every logged-in pageview writes a tiny session file to disk. On cheap VPS SSDs that's thousands of pointless writes burning your I/O and IOPS budget. Put them in RAM:

mount -t tmpfs -o size=128M tmpfs /var/lib/php/sessions
— add it to /etc/fstab so it survives reboot

Sessions are throwaway data anyway; if the box reboots, everyone re-logs, who cares. Disk I/O on my forum box dropped 60%. Same trick works for nginx's proxy cache. Try it tonight.
Your cron job is running 4 copies of itself right now

That */5 job that pulls feeds? If it ever takes longer than 5 min, cron fires another while the first is still chewing. Now you've got overlapping processes eating RAM until the box falls over. Wrap it in flock:

*/5 * * * * flock -n /tmp/feeds.lock php /var/www/pull.php

-n means: if the lock's held, just skip this run, don't queue. One running copy, ever. This single fix has saved more $5 boxes than any RAM upgrade. Try it tonight.
Cache dynamic pages for 1 second. Yes, dynamic.

WordPress on a tiny box dies the moment you hit the front page from Reddit. Microcaching: cache even logged-out dynamic HTML for ONE second.

fastcgi_cache_path /tmp/ngx levels=1:2 keys_zone=mc:10m inactive=60m;
fastcgi_cache_valid 200 1s;

A traffic spike of 500 req/s means PHP only runs ~1 time per second; nginx serves the other 499 from cache. Content's at most 1s stale, nobody notices. A $5 box ate a front-page Hacker News hit and never blinked. Try it tonight.
One MySQL setting matters. The rest is noise.

People paste 40-line my.cnf 'optimizations' from 2012. On a small box, exactly one knob moves the needle:

innodb_buffer_pool_size = 512M (set it to ~50-60% of RAM)

This is the cache that keeps your hot tables and indexes in memory instead of reading disk on every query. Default on a fresh install is a laughable 128M. Bumping it on a 2GB box cut my average query time in half with zero query changes. Set it, restart, done. Try it tonight.
IPv6-only VPS = same box for half the money

Providers charge a premium for a dedicated IPv4 now that they're scarce. But you don't need one for a backend. Grab an IPv6-only instance ($2-3/mo at Hetzner/Netcup) and front it with Cloudflare, which speaks IPv4 to visitors and IPv6 to your origin for free.

— Visitors hit CF over v4
— CF reaches your box over v6
— You never pay for an IPv4

Runs my whole staging fleet for pennies. Just make sure your apt mirror has v6. Try it tonight.
Your dead box isn't out of RAM. It's out of inodes.

df -h says 40% free but everything's failing to write? Run df -i. A runaway log or a session dir with 2 million tiny files exhausts inodes long before disk space. The box is full of nothing.

df -i to confirm
for d in /var/lib/php/sessions; do find $d -type f | wc -l; done

Fix the source, then add logrotate with maxsize 100M. Most 'disk full' panics on cheap VPS are actually this. Try it tonight.
Patch 40 boxes without touching any of them

You will not manually apt upgrade across a fleet. You'll forget, and an unpatched OpenSSL eats you. Set security patches to auto-apply and leave everything else alone:

apt install unattended-upgrades
— enable ONLY the -security origin in 50unattended-upgrades
Unattended-Upgrade::Automatic-Reboot-Time "04:00";

Security fixes land overnight, feature updates that might break things stay manual. Set it once per box, never think about CVEs again. Try it tonight.