# Boosting Linux Host Performance for Containerized Workloads (Nginx Benchmarking Guide)

## 🚀 Why Host Tuning Matters

Even though containers provide abstraction, they still rely on the host’s kernel, CPU scheduler, memory handling, and I/O layers. With smart tuning:

* Network throughput can rise 📈
    
* Memory management can become more efficient 🔁
    
* Latency can be reduced for disk and CPU operations ⚡
    

## 📊 Flow of the Optimization Process

This clear 5-step flow ensures reproducibility and insight into performance improvements.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1747737129655/6cf6e053-3b42-49e0-b96a-99bd1b8c6943.png align="center")

## 🛠️ Setup and Preliminaries

* **OS:** Ubuntu 22.04
    
* **Application:** Nginx inside a Docker container
    
* **Benchmark Tools:** `stress-ng`, `iperf3`, `dd`, `htop`, `iotop`, `iftop`, `sysstat`
    

### Prerequisites

**Ensure Docker is installed and running:**

```bash
docker --version
```

**Install benchmarking and monitoring tools:**

```bash
sudo apt update
sudo add-apt-repository universe
sudo apt update
sudo apt install -y htop iotop iftop sysstat
```

## 📦 Step 1: Launch the Nginx Container

```bash
docker run -d --name nginx-test -p 8089:80 nginx
```

Verify by navigating to: [`http://localhost:8089`](http://localhost:8089)

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXdGNG6gvLTfeZL_w_tJPblsdNK4890-erZZciWQ12IFsSSMGiT-h_T__J7nFhnZjtkCHyacF9hy-W8HMXkP4VMSXMseceZXpDnwtLfe5xve6Ro5cReVovEBNVA6JhkF7Bk7gl-FFQ?key=Ef__CL8GAMxaKEucTOeICg align="left")

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXd-7kyhgJA014hqHn7plCpzpS3oPRNaMZYEzhmhyuPGJ_tdPXKmczMQynEj79xyBnow_pL3oAgsFzVvP0clilG_PjGSndv0ZIhW8aQ0X7XfisqKy_IUDVa4GuwV8a5xFrjqJXF3IQ?key=Ef__CL8GAMxaKEucTOeICg align="left")

## 📉 Step 2: Baseline Performance (Before Tuning)

### CPU Test

```bash
stress-ng --cpu 4 --timeout 60s --metrics-brief
```

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXe3shVLEKln2xm4-27gleNOCVNbAPvZnvJply-uzmz2zYk6TjpgPvkaIAy2D50qKw0SFaXeKaz3xnEmYcJGOwZJSw0tcoQh_Tfqd3y62pMb7bKAI1pwhMM_XLb2A_upUyl3fEZguA?key=Ef__CL8GAMxaKEucTOeICg align="left")

**Memory Test**

```bash
stress-ng --vm 2 --vm-bytes 1G --timeout 60s --metrics-brief
```

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXf279CU692RxVUss_rNO4fjkOBpYWgyCMa95mIeV7TmDTc8B1L5jus2p-_0n3vMtZVSBpIs5TRwlIv_SP5Xe3ZxXtJisBjURv8_tI1ojbOckqFlGCFe4RZOhnDcS7Z1c3zJU7SoKA?key=Ef__CL8GAMxaKEucTOeICg align="left")

**Disk I/O Test**

```bash
dd if=/dev/zero of=testfile bs=1G count=1 oflag=dsync
rm -f testfile
```

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXf-8_QuJmkL8-P-APShb5KhNGhD5QQ-4U84_6Sgw5UV0Wr0QKaxlH6eitIMdQye2dZA3aZrC2mrWvqjn7bQ77XJfUe2IijQu_ij0iJgqJysHAMIKzJ-Of5ZzW3R_8moPqfk2tgk?key=Ef__CL8GAMxaKEucTOeICg align="left")

### Network Test (Loopback)

**Terminal 1:**

```bash
iperf3 -s
```

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXfpDQk9DOIWOjObTnny4MbwOUswXj-Kk4lCZ-QUkvsgyfFQX7xC8GLDUXTfdV8TTMJn2Em9rzraMCBz4e4jtXSsiEJBvj0ZNIyBHZaqel1wQLuSp7sr-B00YjB69my4KD2zcEHDWg?key=Ef__CL8GAMxaKEucTOeICg align="left")

**Terminal 2:**

```bash
iperf3 -c 127.0.0.1
```

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXcxGTOlX2IcAZTkbsZvcvd5W3QlMIPdVar2YTIzYTRkraamY1FfzHfur2bktaGoKaLAP72AhMpI7fhiGc2eTe4_jlIGnZzVigVQh185Z3zALhvWelvNEcvvqF1uekn4g0UluG1ZPg?key=Ef__CL8GAMxaKEucTOeICg align="left")

## ⚙️ Step 3: Apply Linux Host Tuning

### CPU Tuning

Install the cpupower tools and set the performance governor:

```bash
sudo apt install -y linux-tools-common linux-tools-generic
sudo cpupower frequency-set --governor performance
```

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXfZBHIoiCMzQgJNQOcskFZpRSSNqlT2nQvFsWOrpPcVtPhNDUt-6zKmtuF4jJH5NmTnDZJOzls83HFKwJHwoyiFkJhTRjl_qL3FCVfaZH_Vbs8kQpGF40X4JZLjHhDX-P3FWeIq7A?key=Ef__CL8GAMxaKEucTOeICg align="left")

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXdWHmvnp-EjQjOoR-TS-HChZMGEVstnfKxJClsXddr0UwshTf32FIF6OY28O_3H7jMTzYRybMHL9gR1zSh-c8GjpysP0JHNLXDZiMc9MxZeskhl8q2KeVY45i8iOzt5wFzHvD9RBg?key=Ef__CL8GAMxaKEucTOeICg align="left")

**Memory Tuning**

```bash
sudo sysctl -w vm.swappiness=10
sudo sysctl -w vm.dirty_ratio=20
sudo sysctl -w vm.dirty_background_ratio=10
```

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXe3OuceLXY9M87ecNIj8WpqQ2JCUQTwJ41FMgbi3uMPlkb5fLM25KFewImtKOmMAEgM-QMEs3byx6ik8NXtBe-oxVtzmZJtuj4fsVNRwwnp0P7yYHWIdKQm8d4ZFElre2UZaaoLSA?key=Ef__CL8GAMxaKEucTOeICg align="left")

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXdaFlQQQ2eZNtlDm5ikOsn4ObyOzTbwpUPcJDty02B6ySyhwH3ZUgEEG6bxDA2E_lFNRWhn0Gqakhu7nEiMWCf_-kjHP_tPLCI3dNNe-qwuZu-TajXYtGFptHkBVE-HtVJdOMWQ?key=Ef__CL8GAMxaKEucTOeICg align="left")

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXflSWbdFF0K6aSlRPwGphLjw65wVMk9c8cER4bgtL8oLBHXOTnNazH0AZGn7WIRrIb8oV6qI4MjTwiNtpHels62ZXB7M_46M3aDs5k7GclYFvCd5ZQ4kFSMEgpwpDY-vSv90rNL?key=Ef__CL8GAMxaKEucTOeICg align="left")

### Disk I/O Tuning

Change scheduler (check your block device name, e.g., `nvme0n1`):

```bash
cat /sys/block/nvme0n1/queue/scheduler
echo mq-deadline | sudo tee /sys/block/nvme0n1/queue/scheduler
```

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXco6iuoa_uA4frJhQNzmPYxNhkqXNBsE78DGsUTnC16fx6HPVfE1mLiIoc9C8lXI9Z4LyN-bCsyPOuRZggjKbcolL4jbkzaZ5OThwz2MG7S1g7ltLGaNF4MmjKkhONAJXFP2WlgRQ?key=Ef__CL8GAMxaKEucTOeICg align="left")

**Network Tuning**

```bash
sudo sysctl -w net.core.somaxconn=65535
sudo sysctl -w net.core.netdev_max_backlog=250000
sudo sysctl -w net.ipv4.tcp_max_syn_backlog=8192
sudo sysctl -w net.ipv4.tcp_tw_reuse=1
```

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXcQNnz-pkKJUHD6Ek-rmzTHvIEAOLwG-LzZ6xsfJIuInG8S65uxAijS1H50eTAMtk5GbeEiHSRv5T25jTQ-liz5kKfi4P4JbsysD9Eop8Fj7ANK2C8Ggd10jQ2wZABAyl6D87xq2w?key=Ef__CL8GAMxaKEucTOeICg align="left")

**Kernel Parameters for Containers**

```bash
sudo tee /etc/sysctl.d/99-container-tuning.conf > /dev/null <<EOF
fs.file-max = 2097152
vm.max_map_count = 262144
net.ipv4.ip_local_port_range = 1024 65535
EOF

sudo sysctl --system
```

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXflHmGgnWz2cIrZ3K9jAiF6QzevjGpofRL9r2zn-W5rcnXP3I9jwEVp8oMinjkY3yDFFUks8TIQ9O4g9qfnZpJf3KYLP5LCFHDVyANMXBsVfMCCc2RJwZ8FqCM3cTlVPRXK4nUbCQ?key=Ef__CL8GAMxaKEucTOeICg align="left")

## 🔁 Step 4: Re-deploy and Re-test

Recreate the container:

```bash
docker rm -f nginx-test
docker run -d --name nginx-test -p 8089:80 nginx
```

Repeat benchmarks as earlier to observe improvements.

## **Step 5: Re-run the NGINX Container**

```bash
docker rm -f nginx-test
docker run -d --name nginx-test -p 8089:80 nginx
```

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXfhWI-tb6PD8BUFNJAOBsdiFrpA6RpqvtiqTpoyTeFsS8GQ58YiGcaHkHdy2_PEp3okeEyZ9RBhAOPvZVTdsCNnSzkq8PQUjMTfGqqgrRgz6T1UMMZ4w4VV-VdgjwRXJOW-NNJDlA?key=Ef__CL8GAMxaKEucTOeICg align="left")

## 🔁 Step 6: Re-test the Performance (Post-Tuning)

After applying system-level optimizations, it's time to **benchmark again** and compare the performance with the baseline.

### ✅ CPU Re-test

Use the following command to stress the CPU with 4 workers for 60 seconds:

```bash
stress-ng --cpu 4 --timeout 60s --metrics-brief
```

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXfJVGWvpQ_QzxHQJyU9ZZNauHnoHhVHPMt9ASphq7TPeDYLrYxbJgw8oe3FZBtm0LwWuGweM_mr6IGufX73mUcEVbX2vNAdXZSEABt5hPwljBLwVGFd2s5hyJJHw4NJVDBo9aeqpQ?key=Ef__CL8GAMxaKEucTOeICg align="left")

### ✅ Memory Re-test

Run a memory stress test with 2 workers using 1 GB each for 60 seconds:

```bash
stress-ng --vm 2 --vm-bytes 1G --timeout 60s --metrics-brief
```

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXfClHvTniyvnvn44H-uCNAQ3n8QSzZ8oftTxC5yWR5al93f1bk2tpxMB_MRgvf1XPYiY3L3K_IMSV9gbbISDFHyknslNd9zBbGYkNJGSfC8XIYnvFlDqwnanEGTbjwfpxIVEJG9?key=Ef__CL8GAMxaKEucTOeICg align="left")

### ✅ Disk I/O Re-test

Evaluate sequential disk write speed using `dd`:

```bash
if=/dev/zero of=testfile bs=1G count=1 oflag=dsync
rm -f testfile
```

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXcF7WTq1EMmHlE4Qw_Pp1_7hw24WKlnGwMMT_fkwfxxWUd3M2NWhlU-ctxakbQtNRC1xlOdr_sVvqTr-kQZct53NbADWZYBQ5FG2NZKdhol_0ZvnsCPR6BLuI5AdeoWmproIG2U?key=Ef__CL8GAMxaKEucTOeICg align="left")

### ✅ Network Re-test (Loopback Throughput)

**Step 1: Start the iperf3 server**

```bash
iperf3 -s
```

**Step 2: In another terminal (same host), run the iperf3 client**

```bash
iperf3 -c 127.0.0.1
```

This will test internal loopback throughput after networking optimizations.

## 📊 Benchmark Results: Before vs. After

| **Metric** | **Before Tuning** | **After Tuning** | **Result** |
| --- | --- | --- | --- |
| CPU (stress-ng) | 4367.92 bogo ops/s | 4300.34 bogo ops/s | 🔻 1.6% Decrease |
| Memory (stress-ng) | 92099.68 bogo ops/s | 91439.94 bogo ops/s | 🔻 0.7% Slight Decrease |
| Disk I/O (dd) | 1.4 GB/s | 1.4 GB/s | ➖ No Change |
| Network (iperf3) | 67.3 Gbps | 69.7 Gbps | 🔺 3.6% Improvement |

## 📌 Analysis

* **CPU & Memory:** Minor decrease in throughput—likely due to more deterministic scheduling from tuning.
    
* **Disk I/O:** No change—indicating the scheduler change didn’t affect sequential write speed.
    
* **Network:** Solid improvement in throughput thanks to buffer tuning and backlog increase.
    

## ✅ Summary

Tuning a Linux host for containerized workloads **isn't just about maxing out performance**—it's about tailoring the system to match your application’s behavior.

### Key Takeaways:

* Network stack tuning had the **most measurable benefit** (3.6% gain).
    
* Memory and CPU tuning had **slight trade-offs**, possibly due to overhead or governor changes.
    
* Always **benchmark before and after** to validate changes.
    
* Apply these techniques to **any containerized app**, not just Nginx.
