ARTICLE

DMIT Performance Tuning: Kernel, Nginx, DB and App

Performance tuning from kernel to Nginx, database and application layers with bottleneck detection.

Performance tuning philosophy

DMIT cloud server performance tuning is not a one-time task — it's a "measure → analyze → adjust → verify" cycle. Blindly changing configs often makes things worse. This article covers tuning from system level to application level.

All recommendations are based on general Linux best practices and do not involve modifying DMIT's underlying infrastructure.

Step 1: Establish a baseline

Record current performance metrics before tuning, so you can measure the effect:

# System load baseline
uptime
cat /proc/loadavg

# CPU info
nproc
lscpu | grep "Model name"

# Memory baseline
free -h

# Disk I/O baseline
dd if=/dev/zero of=/tmp/test bs=1M count=500 oflag=direct 2>&1 | tail -1
rm /tmp/test

# Network baseline
ping -c 10 8.8.8.8
curl -o /dev/null -s -w "Connect: %{time_connect}s\nTTFB: %{time_starttfb}s\nTotal: %{time_total}s\n" https://www.dmit.io

Save baseline data to a file for comparison after tuning.

System-level tuning

Kernel parameters

Edit /etc/sysctl.conf for network and memory:

# TCP connection optimisation
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_keepalive_time = 300

# Memory optimisation
vm.swappiness = 10
vm.overcommit_memory = 1

# File descriptors
fs.file-max = 65535

Apply with sysctl -p.

File descriptor limits

High-concurrency services need more file descriptors. Edit /etc/security/limits.conf:

* soft nofile 65535
* hard nofile 65535

For systemd services, edit the service unit:

[Service]
LimitNOFILE=65535

Nginx tuning

Worker config

worker_processes auto;
worker_rlimit_nofile 65535;

events {
    worker_connections 16384;
    use epoll;
    multi_accept on;
}

HTTP config

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    
    gzip on;
    gzip_min_length 1024;
    gzip_comp_level 4;
    gzip_types text/plain text/css application/json application/javascript;
    
    open_file_cache max=1000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    
    keepalive_timeout 30;
    keepalive_requests 100;
    client_body_timeout 10;
    client_header_timeout 10;
}

FastCGI cache (PHP-FPM)

fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=php:100m inactive=10m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache php;
fastcgi_cache_valid 200 301 302 10m;
fastcgi_cache_use_stale error timeout invalid_header;

Database tuning

MySQL/MariaDB

[mysqld]
innodb_buffer_pool_size = 1G   # ~50-70% of RAM
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 2
max_connections = 200
thread_cache_size = 16
table_open_cache = 512

PostgreSQL

shared_buffers = 1GB            # ~25% of RAM
effective_cache_size = 3GB     # ~75% of RAM
work_mem = 16MB
maintenance_work_mem = 256MB
max_connections = 100
random_page_cost = 1.1          # SSD optimisation
effective_io_concurrency = 200  # SSD optimisation

Application tuning

Node.js

# Cluster mode for multi-core
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
    for (let i = 0; i < numCPUs; i++) cluster.fork();
} else {
    // your app
}

# PM2 process manager
pm2 start app.js -i max
pm2 startup
pm2 save

Python (Gunicorn)

gunicorn app:app \
    --workers $(nproc) \
    --worker-class uvicorn.workers.UvicornWorker \
    --bind 0.0.0.0:8000 \
    --timeout 30 \
    --max-requests 1000 \
    --max-requests-jitter 50

Resource monitoring & bottleneck detection

CPU bottleneck

top -b -n1 | head -20
ps aux --sort=-%cpu | head -10
strace -c -p <pid> -e trace=all 2>&1 | sort -n

Memory bottleneck

ps aux --sort=-%mem | head -10
dmesg | grep -i "out of memory"
swapon --show

Disk I/O bottleneck

iostat -x 1 5
iotop -o
top -b -n1 | grep "wa"

Network bottleneck

ss -s
ss -ant | grep TIME-WAIT | wc -l
speedtest-cli

Tuning checklist

LayerItemTarget
SystemKernel paramsTCP queue sufficient
SystemFile descriptors≥ 65535
SystemSwapswappiness=10
NginxWorkerauto + 16384 connections
NginxGzipon, level 4
NginxCacheopen_file_cache configured
DatabaseBuffer pool50-70% of RAM
DatabaseConnectionsmax_connections reasonable
AppMulti-corecluster/PM2/workers
MonitorBaseline recordedBefore/after comparable

Related: Monitoring and Backup, SSH Hardening, First Deploy Checklist.

Checked 2026-08-18. Tuning parameters depend on your actual workload and resources.

NEXT STEP

Ready to pick your DMIT plan?

Filter the official snapshot by budget and network, or check live stock at DMIT.

Disclosure: purchases through this link may earn the referrer a commission at no extra cost to you.