← Back to DevBytes

Manjaro Performance Tuning for Web Servers

Understanding Manjaro for Web Server Deployments

Manjaro is a rolling-release Linux distribution derived from Arch Linux, designed with a strong emphasis on user-friendliness and hardware support. While traditionally seen as a desktop-oriented system, Manjaro's access to the latest kernel versions, cutting-edge packages, and minimal base installation make it a surprisingly capable platform for web servers. Its rolling release model means you never need to perform major version upgrades—packages arrive continuously, keeping your stack modern without disruptive migration cycles.

Why Performance Tuning Matters on Manjaro

Unlike Debian or Ubuntu Server editions, Manjaro does not ship with "server-optimized" defaults out of the box. The kernel is configured for general-purpose desktop responsiveness, file descriptor limits are conservative, and network stack parameters prioritize fairness over raw throughput. When serving HTTP traffic, WebSocket connections, or reverse-proxy workloads, these defaults become bottlenecks. Tuning bridges the gap between Manjaro's desktop heritage and the demands of production web serving, giving you control over connection handling, memory allocation, I/O scheduling, and process management.

Pre-Tuning Audit and Baseline

šŸš€ Deploy your AI agent in 10 minutes

Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.

Try it free →

Before adjusting any parameters, establish a performance baseline. This allows you to measure the impact of each change and revert regressions systematically.

Install Monitoring Tools

sudo pacman -Syu sysstat htop nethogs iperf3 httpie

Capture Baseline Metrics

Run a benchmark against your web server before tuning. For example, using wrk (install via sudo pacman -S wrk):

# Run a 30-second benchmark with 4 threads and 100 concurrent connections
wrk -t4 -c100 -d30s --latency http://localhost:8080

Record the requests per second, average latency, and 99th percentile latency. Save this data for comparison after each tuning phase.

Kernel-Level Tuning with sysctl

The kernel exposes hundreds of tunable parameters via /proc/sys. For web servers, the most impactful settings relate to networking, memory, and file handling. On Manjaro, persistent sysctl values go into /etc/sysctl.d/ rather than a monolithic config file.

Network Stack Optimization

Create a dedicated configuration file for web server tuning:

sudo nano /etc/sysctl.d/99-web-server-tuning.conf

Add the following parameters with explanatory comments:

# Increase TCP connection backlog for high-concurrency scenarios
# Default 128 is inadequate for web servers handling hundreds of connections
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 4096

# Enable TCP Fast Open for reduced latency on repeated connections
# 3 = enable for both client and server
net.ipv4.tcp_fastopen = 3

# Increase the number of outstanding socket connections
net.core.netdev_max_backlog = 2500

# Reuse sockets in TIME_WAIT state for new connections
# Reduces resource exhaustion under high connection turnover
net.ipv4.tcp_tw_reuse = 1

# Lower TIME_WAIT timeout to free ports faster
# Default 60s can exhaust ephemeral ports under load
net.ipv4.tcp_fin_timeout = 15

# Expand ephemeral port range for outgoing connections
# Essential for reverse-proxy and load-balancer roles
net.ipv4.ip_local_port_range = 1024 65535

# Enable TCP keepalive with aggressive timing
# Detects dead connections faster than default 2-hour interval
net.ipv4.tcp_keepalive_time = 60
net.ipv4.tcp_keepalive_intvl = 10
net.ipv4.tcp_keepalive_probes = 6

# Use TCP BBR congestion control for higher throughput
# Modern algorithm outperforms CUBIC on lossy or high-latency links
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

# Increase receive and send buffer sizes for high-throughput transfers
# Max values are set high to allow auto-tuning
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

# Optimize for low-latency connections by disabling Nagle's algorithm
# TCP_NODELAY ensures small packets are sent immediately
net.ipv4.tcp_low_latency = 1

Apply the changes immediately without rebooting:

sudo sysctl --load=/etc/sysctl.d/99-web-server-tuning.conf

Verify that BBR congestion control is active:

sysctl net.ipv4.tcp_congestion_control
# Should output: net.ipv4.tcp_congestion_control = bbr

File Descriptor and Process Limits

Web servers like Nginx and Apache open numerous files—configuration files, log files, static assets, and socket connections. The default per-process limit of 1024 is a severe bottleneck. Manjaro uses /etc/security/limits.conf for persistent user limits, but systemd service limits require separate configuration.

Set global file descriptor limits:

sudo nano /etc/security/limits.conf
# Add:
*                soft    nofile          1048576
*                hard    nofile          1048576
root             soft    nofile          1048576
root             hard    nofile          1048576

For systemd-managed services like Nginx, override the service file limits:

sudo mkdir -p /etc/systemd/system/nginx.service.d
sudo nano /etc/systemd/system/nginx.service.d/override.conf
# Add:
[Service]
LimitNOFILE=1048576
LimitNPROC=65535
LimitMEMLOCK=infinity
TasksMax=infinity

Reload systemd and restart the service:

sudo systemctl daemon-reload
sudo systemctl restart nginx

Verify the limits are applied to the running process:

cat /proc/$(pgrep nginx | head -1)/limits | grep "Max open files"

I/O Scheduler Selection

Manjaro defaults to the mq-deadline or bfq scheduler depending on storage type. For SSDs serving web workloads, none (no-op scheduling, also called kyber or none in modern kernels) is often optimal because the drive's internal controller handles queuing more efficiently than the kernel can. Check your current scheduler:

cat /sys/block/nvme0n1/queue/scheduler
# Example output: [none] mq-deadline kyber

To persist the scheduler selection across boots, create a udev rule:

sudo nano /etc/udev/rules.d/60-iosched.rules
# For NVMe drives:
ACTION=="add|change", KERNEL=="nvme*", SUBSYSTEM=="block", ATTR{queue/scheduler}="none"
# For SATA SSDs:
ACTION=="add|change", KERNEL=="sd*[!0-9]", SUBSYSTEM=="block", ATTR{queue/scheduler}="mq-deadline"

Apply immediately and reload udev:

sudo udevadm trigger
sudo udevadm control --reload-rules

Web Server-Specific Tuning

Nginx Optimization

Nginx ships with reasonable defaults, but several adjustments unlock substantial throughput gains on Manjaro.

Worker configuration: Set worker_processes to auto to match available CPU cores. Set worker_connections based on the file descriptor limits you configured earlier.

sudo nano /etc/nginx/nginx.conf
# Adjust in the events block:
user www-data;
worker_processes auto;
worker_rlimit_nofile 1048576;

events {
    worker_connections 40960;
    use epoll;
    multi_accept on;
    accept_mutex off;  # Reduces contention on modern multi-core systems
}

http {
    # Reduce sendfile() syscall overhead
    sendfile on;
    sendfile_max_chunk 512k;
    tcp_nopush on;
    tcp_nodelay on;

    # Aggressive keepalive for client connections
    keepalive_timeout 65;
    keepalive_requests 1000;

    # Disable unnecessary logging in production
    access_log off;
    # Or buffer logs to reduce I/O contention:
    # access_log /var/log/nginx/access.log combined buffer=64k flush=5m;

    # Increase hash table sizes for large virtual host configurations
    server_names_hash_bucket_size 128;
    types_hash_max_size 4096;
    types_hash_bucket_size 128;

    # Gzip compression tuning
    gzip on;
    gzip_comp_level 5;  # Balance CPU vs. compression ratio
    gzip_min_length 256;
    gzip_proxied any;
    gzip_vary on;
    gzip_types
        application/atom+xml
        application/javascript
        application/json
        application/ld+json
        application/manifest+json
        application/rss+xml
        application/vnd.geo+json
        application/vnd.ms-fontobject
        application/x-font-ttf
        application/x-web-app-manifest+json
        application/xhtml+xml
        application/xml
        font/opentype
        image/bmp
        image/svg+xml
        image/x-icon
        text/cache-manifest
        text/css
        text/plain
        text/vcard
        text/vnd.rim.location.xloc
        text/vtt
        text/x-component
        text/x-cross-domain-policy;

    # Open file caching for static assets
    open_file_cache max=10000 inactive=30s;
    open_file_cache_valid 60s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
}

PHP-FPM pool tuning (if using PHP):

sudo nano /etc/php/php-fpm.d/www.conf

# Dynamic process management with generous limits
pm = dynamic
pm.max_children = 200
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
pm.max_requests = 500  # Restart workers after 500 requests to prevent memory leaks

# Connection settings
request_terminate_timeout = 30s
request_slowlog_timeout = 10s
slowlog = /var/log/php-fpm/slow.log

Restart both services:

sudo systemctl restart php-fpm
sudo systemctl restart nginx

Apache (httpd) Optimization

If you use Apache instead of Nginx, the tuning approach differs due to its process-based architecture. On Manjaro, Apache uses mpm_event by default, which is the correct choice for high concurrency.

sudo nano /etc/httpd/conf/httpd.conf

# Ensure event MPM is loaded
LoadModule mpm_event_module modules/mod_mpm_event.so

# Event MPM configuration

    StartServers             8
    MinSpareThreads          75
    MaxSpareThreads          250
    ThreadsPerChild          64
    ServerLimit              128
    MaxRequestWorkers        8192
    MaxConnectionsPerChild   10000
    AsyncRequestWorkerFactor 2


# Disable .htaccess lookups for performance

    AllowOverride None
    Options -Indexes -Includes -MultiViews


# KeepAlive settings
KeepAlive On
KeepAliveTimeout 5
MaxKeepAliveRequests 500

# Cache commonly accessed files with mod_socache_memcache or mod_cache
# Install mod_cache and mod_cache_disk if needed:
# sudo pacman -S mod_cache mod_cache_disk

Enable caching modules and restart:

sudo sed -i 's/#LoadModule cache_module/LoadModule cache_module/' /etc/httpd/conf/httpd.conf
sudo sed -i 's/#LoadModule cache_disk_module/LoadModule cache_disk_module/' /etc/httpd/conf/httpd.conf
sudo apachectl restart

Database Tuning (MariaDB / PostgreSQL)

MariaDB / MySQL

On Manjaro, MariaDB's default configuration is conservative—it assumes a shared hosting environment with minimal RAM. Tune it aggressively for dedicated web server hardware.

sudo nano /etc/my.cnf.d/server.cnf

[mysqld]
# InnoDB is the default engine—optimize it
innodb_buffer_pool_size = 4G          # 60-80% of total RAM for dedicated DB servers
innodb_log_file_size = 512M           # Larger log files reduce checkpoint frequency
innodb_flush_log_at_trx_commit = 2    # Slightly less durable, significantly faster
innodb_flush_method = O_DIRECT        # Avoid double-buffering with filesystem cache
innodb_io_capacity = 2000             # Match modern SSD IOPS capability
innodb_read_io_threads = 8
innodb_write_io_threads = 8

# Query cache is deprecated in modern MariaDB; use it only if profiling shows benefit
query_cache_type = 0
query_cache_size = 0

# Connection tuning
max_connections = 500
thread_cache_size = 64
table_open_cache = 4096
table_definition_cache = 4096

# Temporary table optimization
tmp_table_size = 128M
max_heap_table_size = 128M

# Slow query logging for debugging
slow_query_log = 1
slow_query_log_file = /var/log/mariadb/slow-queries.log
long_query_time = 2

# Binary logging for replication (disable if not needed)
# skip-log-bin
# If enabled, use row-based replication for consistency
binlog_format = ROW
sync_binlog = 0  # Reduce disk sync overhead

Restart MariaDB and verify the buffer pool size:

sudo systemctl restart mariadb
mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"

PostgreSQL

PostgreSQL relies heavily on shared memory and process management. Manjaro's kernel memory limits may need adjustment.

sudo nano /var/lib/postgres/data/postgresql.conf

# Memory configuration (adjust based on available RAM)
shared_buffers = 4GB                  # 25% of system RAM
effective_cache_size = 12GB           # 75% of system RAM (PostgreSQL uses this for query planning)
work_mem = 64MB                       # Per-operation sort memory (increase for complex queries)
maintenance_work_mem = 512MB          # For VACUUM, CREATE INDEX operations
wal_buffers = 64MB

# Write-Ahead Log tuning
wal_level = replica                   # Or 'minimal' if no replication needed
fsync = on                            # Keep on for crash safety; use 'off' only for disposable data
synchronous_commit = off              # Improves throughput, minimal risk with battery-backed RAID
full_page_writes = off                # Safe to disable with checksums enabled and non-sandby setup

# Planner optimization
random_page_cost = 1.1                # Default 4.0 assumes spinning disks; 1.1 reflects SSD reality
effective_io_concurrency = 200        # SSD concurrency limit

# Connection and parallelism
max_connections = 300
max_worker_processes = 16
max_parallel_workers_per_gather = 4
max_parallel_workers = 8

# Statistics collection (useful for query optimization)
track_activity_query_size = 2048
track_functions = pl
autovacuum = on
autovacuum_max_workers = 4
autovacuum_naptime = 30s

Apply and reload:

sudo systemctl reload postgresql
# Or for full restart:
# sudo systemctl restart postgresql

Memory and Swap Considerations

Web servers under memory pressure can enter swap thrashing, causing latency spikes that ruin user experience. Manjaro's default swappiness of 60 is too aggressive for server workloads—it encourages swapping even when free memory exists.

Reduce swappiness and configure virtual memory behavior:

sudo nano /etc/sysctl.d/99-web-server-tuning.conf
# Add or modify:
vm.swappiness = 10
vm.vfs_cache_pressure = 50  # Prefer retaining inode/dentry caches over swap
vm.dirty_ratio = 30         # Start writeback when 30% of RAM is dirty pages
vm.dirty_background_ratio = 10  # Background writeback threshold

Apply immediately:

sudo sysctl -w vm.swappiness=10
sudo sysctl -w vm.vfs_cache_pressure=50

For systems with ample RAM (32GB+), consider disabling swap entirely for web workloads that must never stall on disk I/O:

sudo swapoff -a
# To persist: comment out swap partitions/UUIDs in /etc/fstab

Network Card and IRQ Affinity

On multi-core Manjaro servers, network interrupt processing can saturate a single CPU core. Distributing IRQ handling across cores prevents this bottleneck. Install irqbalance or configure manual affinity.

sudo pacman -S irqbalance
sudo systemctl enable --now irqbalance

For manual control, identify your network interface and its IRQs:

# Find interface name (e.g., enp3s0, eth0)
ip link show

# List IRQ numbers for the interface
grep "enp3s0" /proc/interrupts | awk '{print $1}' | tr -d ':'

Set CPU affinity masks (example for 8-core system, distributing IRQs across cores 1-7, leaving core 0 for system tasks):

# For IRQ 45, assign to CPU cores 1,2,3,4 (mask 0x3E = binary 00111110)
echo "3E" | sudo tee /proc/irq/45/smp_affinity

# Verify
cat /proc/irq/45/smp_affinity

Security Considerations During Tuning

Performance tuning often involves relaxing constraints that exist partly for security reasons. Balance speed with safety:

Monitoring and Iterative Refinement

Performance tuning is not a one-time event. After applying changes, re-run your baseline benchmarks and compare results:

# Re-run wrk benchmark
wrk -t4 -c100 -d30s --latency http://localhost:8080

# Monitor CPU utilization during the test
mpstat 1 &

# Watch disk I/O
iostat -x 1 &

# Check for bottlenecks in real time
htop

Set up continuous monitoring with collectd or netdata for long-term trend analysis:

sudo pacman -S netdata
sudo systemctl enable --now netdata
# Access dashboard at http://localhost:19999

Iterate on tuning parameters based on observed bottlenecks. If CPU is saturated, investigate Nginx worker count or PHP-FPM pool sizing. If disk I/O is the bottleneck, tune database buffer pools or enable more aggressive caching. If network throughput plateaus, revisit sysctl buffer sizes and BBR behavior.

Best Practices Summary

Conclusion

Manjaro's rolling-release foundation, when paired with deliberate performance tuning, transforms it into a formidable web server platform capable of matching purpose-built server distributions. The tuning journey spans kernel networking parameters, file descriptor limits, I/O scheduler selection, web server worker configuration, database memory optimization, and swap behavior. Each adjustment compounds, and the cumulative effect often yields a 2x to 5x throughput improvement over stock Manjaro defaults. The key to sustained performance is continuous monitoring and iterative refinement—measure, adjust, measure again. With the practical configurations outlined above, your Manjaro web server stack will handle high-concurrency workloads with lower latency, higher throughput, and greater resource efficiency. Keep your rollback plans ready, stay current with rolling updates, and let empirical benchmarks guide your tuning decisions rather than cargo-cult configuration copying.

šŸš€ Need a reliable AI agent for your project?

Deploy Hermes Agent in 10 minutes. Managed hosting, zero DevOps.

Get Started — $23.99/mo
← Back to all articles