When I deploy a Linux server, usually Ubuntu, I make sure to include some changes that differs from default. The default config is fine, but since the virtual hardware my server is running on is quite limiting, I need to do some fine tuning.

So, first up, let’s benchmark the performance with the default config, then the fine tuned config.

Setup /etc/sysctl.d/99-sysctl.conf


Setting Default Fine tuned
vm.swappiness 60 10
vm.dirty_writeback_centisecs 500 2000
net.ipv4.tcp_fastopen 1 3
net.ipv4.tcp_congestion_control cubic bbr
net.core.default_qdisc fq_codel cake
net.ipv4.tcp_window_scaling 1 1
net.ipv4.tcp_mtu_probing 0 1
net.ipv4.tcp_low_latency 0 1
net.ipv4.tcp_slow_start_after_idle 1 0

Do note that this config is tuned for better latency.

Server Hardware


My server (Virtual Private Server) is quite low powered, but cheap nontheless. Hardware goes as follows:

  • OS: Ubuntu 22.04.4 LTS x86_64
  • Host: KVM/QEMU
  • Kernel: 5.15.0-116-generic
  • CPU: QEMU Virtual version 2.5+ (1) @ 2.593GHz
  • Memory: 957MiB
  • Zram: 1.9G lzo-rle

Numbers


Do note that I’m testing this on my virtual machine
The test I will do is very simple. I have a program Vegeta that will thow as many GET requests at my site running in a virtual machine, that my computer can handle. The test is run 1 minut after server reboot. Example command used for this test:

echo "GET http://localhost:1313/" | ./vegeta attack -duration=1s -rate=10 | tee results.bin | ./vegeta report
Duration rate Latency (mean) Default Succes Ratio Latency (mean) Fine tuned Succes Ratio
1s 10 2.764s 100% 0.899s 100%
1s 1.000 3.180s 100% 0.99s 100%
1s 5.000 11.499s 50.66% 11.804s 48.85%
10s 500 19.649s 40.20% 0.0200s 100%
10s 1.000 0.0203s 100% 0.0201s 100%
60s 500 0.0206s 100% 0.0200s 100%

Although there is not much we can do when we only have one virtual thread to work with, I would say it was worth researching and fine tuning. We don’t see much improvement, except for 10 seconds with 500 request/sec, and some marginal improvements.

If the server had more threads, or maybe even an actual CPU core, that would be better. But we have to work with what we have, and optimizing software before paying for new hardware, seems to be worth it.

Changes To /etc/sysctl.d/99-sysctl.conf


net.ipv4.tcp_fastopen=3
net.ipv4.tcp_congestion_control=bbr
net.core.default_qdisc=cake
net.ipv4.tcp_window_scaling=1
net.ipv4.tcp_mtu_probing=1
net.ipv4.tcp_low_latency=1
net.ipv4.tcp_slow_start_after_idle=0