Understanding Performance Tuning for Web Servers on Fedora
Performance tuning on Fedora for web servers involves adjusting system parameters, kernel settings, and application configurations to maximize throughput, minimize latency, and ensure stability under heavy load. Whether you are running Apache, Nginx, or a custom HTTP server, the default Fedora installation is optimized for general desktop or server workloads. For a web server handling thousands of concurrent connections, you must tailor the operating system to efficiently manage network sockets, memory, CPU scheduling, and disk I/O.
Why does it matter? A poorly tuned server may experience dropped connections, slow response times, excessive CPU usage, or even crash under load. Proper tuning allows you to serve more requests per second, reduce time-to-first-byte (TTFB), and maintain reliability during traffic spikes. It's a critical skill for any developer or system administrator managing production web infrastructure.
How to Tune Your Fedora Web Server
🚀 Deploy your AI agent in 10 minutes
Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.
Try it free →The tuning process is a combination of kernel parameter adjustments, system limits, hardware resource management, and application-level configurations. Below we walk through each key area with practical commands and configuration snippets that you can apply directly on Fedora 38+ (compatible with later releases).
1. Kernel Network Parameters via sysctl
The kernel exposes hundreds of tunable parameters through /etc/sysctl.conf and the sysctl command. For web servers, the most impactful are related to network socket handling, TCP behavior, and memory buffers.
Create a dedicated configuration file or append to /etc/sysctl.d/99-web-performance.conf:
# /etc/sysctl.d/99-web-performance.conf
# Increase the maximum number of pending connections for TCP sockets (backlog)
net.core.somaxconn = 65535
# Increase the maximum number of orphaned sockets (sockets not owned by a process)
net.ipv4.tcp_max_orphans = 65535
# Enable TCP Fast Open (reduces latency for repeated connections)
net.ipv4.tcp_fastopen = 3
# Use TCP keepalive to detect dead connections faster
net.ipv4.tcp_keepalive_time = 60
net.ipv4.tcp_keepalive_intvl = 10
net.ipv4.tcp_keepalive_probes = 5
# Increase the time a connection in TIME_WAIT stays (recycle quickly)
net.ipv4.tcp_tw_reuse = 1
# Allow reuse of TIME_WAIT sockets for new connections
net.ipv4.tcp_tw_recycle = 1 # Note: removed in kernel 4.12+, use caution
# Lower the timeout for FIN_WAIT_2 sockets
net.ipv4.tcp_fin_timeout = 15
# Increase maximum number of memory buffers allocated for TCP
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# Increase the maximum length of the per-CPU packet backlog queue
net.core.netdev_max_backlog = 5000
# Disable slow start after idle (keeps window size high for subsequent requests)
net.ipv4.tcp_slow_start_after_idle = 0
# Enable TCP window scaling
net.ipv4.tcp_window_scaling = 1
# Use modern TCP congestion control (e.g., BBR or cubic)
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
Apply the changes immediately:
sudo sysctl --system
Verify that BBR is active:
sysctl net.ipv4.tcp_congestion_control
2. File Descriptor and Process Limits
A web server under high concurrency can run out of file descriptors (open sockets, files). Fedora's default limit per process is often 1024, which is far too low. Raise both the system-wide and per-process limits.
Edit /etc/security/limits.conf:
# Increase nofile (open file descriptors) for all users
* soft nofile 1000000
* hard nofile 1000000
# Optionally for the specific web server user (e.g., nginx, apache)
nginx soft nofile 1000000
nginx hard nofile 1000000
Also adjust the systemd limits for the service. For example, for nginx, edit the service file override:
sudo systemctl edit nginx
Add:
[Service]
LimitNOFILE=1000000
LimitNPROC=65535
Reload systemd and restart the service:
sudo systemctl daemon-reload
sudo systemctl restart nginx
3. TCP Congestion Control and Buffer Tuning
As configured in sysctl, BBR (Bottleneck Bandwidth and Round-trip propagation time) is Google's congestion control algorithm that can significantly improve throughput for web traffic, especially on high-latency links. Fedora kernels support BBR. Ensure the module is loaded:
sudo modprobe tcp_bbr
To make it permanent, add the module to /etc/modules-load.d/bbr.conf:
tcp_bbr
Verify available congestion control algorithms:
sysctl net.ipv4.tcp_available_congestion_control
The buffer sizes set in sysctl above control how much data can be queued in kernel buffers before the application reads it. Large buffers help absorb bursts, but too large can cause latency. The values given (max 16 MB) are reasonable for a typical 1 Gbps or 10 Gbps web server.
4. I/O Scheduler Optimization
Modern Fedora uses the mq-deadline or kyber schedulers for multi-queue block devices. For SSD storage, none (noop) or kyber is optimal because it reduces overhead. For NVMe drives, the kernel usually bypasses the scheduler entirely. Verify the current scheduler for your disk (e.g., sda):
cat /sys/block/sda/queue/scheduler
To change temporarily:
echo kyber | sudo tee /sys/block/sda/queue/scheduler
Make it permanent via udev rules or by adding the kernel parameter elevator=kyber to the kernel command line in /etc/default/grub and updating grub. For a web server with heavy static file serving (disk I/O), reducing I/O latency is key. Kyber balances throughput and latency well.
5. CPU Affinity and IRQ Balancing
High packet rates can saturate a single CPU core due to network interrupt handling. Fedora's irqbalance service automatically distributes interrupts across cores, but you can tune it. Ensure it's running:
sudo systemctl enable --now irqbalance
For extreme tuning, you can manually pin network card IRQs using /proc/irq/*/smp_affinity or use tuna tool. For most web servers, irqbalance with its default configuration is sufficient. Additionally, consider CPU isolation via tuned profiles (see below).
If you run a multi-queue NIC, enable RPS (Receive Packet Steering) to spread processing across cores. Add to /etc/rc.local or a systemd service:
for i in /sys/class/net/eth0/queues/rx-*; do
echo ffffffff > $i/rps_cpus
done
Replace eth0 with your network interface. This distributes incoming packet processing across all cores.
6. Using tuned-adm Profiles
Fedora includes the tuned daemon that applies sets of performance optimizations. The tuned-adm command lets you switch profiles. For a web server, the network-latency or throughput-performance profiles are good starting points. To list available profiles:
tuned-adm list
Activate the network-latency profile:
sudo tuned-adm profile network-latency
This profile adjusts kernel parameters, CPU governor, and other settings for low latency networking. You can also create a custom profile in /etc/tuned/ combining aspects of different profiles. After setting the profile, verify it's active:
tuned-adm active
7. Web Server Configuration Tweaks (Apache/Nginx)
Beyond the OS, your web server software itself must be tuned. Below are examples for Nginx and Apache.
Nginx
Edit /etc/nginx/nginx.conf:
user nginx;
worker_processes auto; # one worker per CPU core
worker_connections 4096; # per worker, set high
use epoll;
multi_accept on;
keepalive_timeout 15;
keepalive_requests 1000;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
events {
worker_connections 4096;
use epoll;
}
Increase the worker_connections to match your expected concurrent connections. For serving static files, sendfile and tcp_nopush improve throughput. For HTTPS, enable session caching and stapling.
Apache (httpd with event MPM)
In /etc/httpd/conf/httpd.conf or MPM configuration:
<IfModule mpm_event_module>
StartServers 4
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
ServerLimit 32
MaxRequestWorkers 800
MaxConnectionsPerChild 10000
</IfModule>
Ensure you use the event MPM (not prefork) for high concurrency. Adjust MaxRequestWorkers based on available memory (each thread consumes ~20–30 MB for typical PHP modules). Enable KeepAlive On and set KeepAliveTimeout to a low value (e.g., 5 seconds) to reuse connections without holding them too long.
8. Systemd Service Resource Controls
You can limit resources for the web server service to prevent a runaway process from starving the system, but also ensure it has sufficient CPU and memory shares. For example, override nginx.service:
sudo systemctl edit nginx
Add:
[Service]
CPUWeight=1000
MemoryMax=2G
MemoryHigh=1.5G
CPUQuota=200% # allows use of up to 2 full cores
This ensures the service has higher CPU scheduling priority (default weight is 100) and caps memory usage to avoid OOM kills but still allow burst.
Best Practices for Sustained Performance
- Measure before and after: Use tools like
ab(ApacheBench),wrk, orvegetato benchmark your server. Record baseline metrics (requests per second, latency percentiles, CPU/memory usage). - Incremental tuning: Change one parameter at a time and test. This helps identify which settings actually improve performance.
- Monitor in production: Deploy monitoring (Prometheus, Grafana, node_exporter) to track file descriptors, socket states, CPU, and network errors.
- Disable unnecessary services: On a dedicated web server, stop services like
cups,bluetooth, or desktop-related daemons to free memory and CPU cycles. - Use a CDN for static assets: Offload static file serving to reduce I/O pressure on the server.
- Keep the system updated: Fedora's kernel updates often bring performance improvements, especially in network stack and schedulers.
- Test under realistic load: Simulate real-world traffic patterns, not just simple GET requests. Include TLS handshakes, dynamic responses, and database queries.
- Document changes: Maintain a configuration management script or Ansible playbook to replicate tuning across servers.
Conclusion
Fedora provides a powerful, modern platform for web servers, but extracting maximum performance requires deliberate tuning. By adjusting kernel network parameters, file descriptor limits, TCP congestion control, I/O scheduler, CPU/IRQ balancing, and leveraging tuned profiles, you can handle significantly higher loads with lower latency. Combine these system-level tweaks with application-specific optimizations in Nginx or Apache, and always validate changes with rigorous benchmarking. With these techniques, your Fedora-based web server will be ready to serve millions of requests reliably and efficiently.