Console Login

API Gateway Performance: Tuning NGINX & Linux Kernel for <10ms Latency in Norway

API Gateway Performance: Tuning NGINX & Linux Kernel for <10ms Latency

Your API isn't slow because of your Python code. It's slow because your TCP stack is choking on SYN packets, or your gateway is renegotiating SSL handshakes like it's 2015. I've spent the last decade debugging high-traffic clusters across Europe, and the bottleneck is almost always infrastructure misconfiguration.

When you are serving traffic to Oslo or handling GDPR-sensitive data for Norwegian clients, you cannot afford latency. The round-trip time (RTT) from Bergen to a data center in Frankfurt is governed by physics. You can't fix the speed of light, but you can fix how your server handles the packet once it arrives.

This isn't high-level theory. This is the exact tuning guide we use when migrating clients from oversold public clouds to dedicated KVM instances. We are going to tune the Linux kernel, optimize the NGINX worker processes, and eliminate CPU steal time.

1. The OS Layer: Tuning the Linux Kernel

Default Linux distributions—even Ubuntu 22.04 LTS—are tuned for general-purpose usage, not for handling 50,000 concurrent connections. If you run a default install, your API gateway will cap out long before your CPU hits 100%.

The first limit you'll hit is the file descriptor limit. Everything in Linux is a file, including a socket connection.

Increase File Descriptors

Check your current limit:

ulimit -n

If it returns 1024, your gateway will crash under load. You need to edit /etc/security/limits.conf to allow the nginx user (or your gateway user) to open more files.

# /etc/security/limits.conf
nginx       soft    nofile  65535
nginx       hard    nofile  65535
root        soft    nofile  65535
root        hard    nofile  65535

The Sysctl Config

Now, let's touch the network stack. We need to modify /etc/sysctl.conf. This is where we tell the kernel to handle TCP connections more aggressively. In a high-latency environment (like serving Northern Norway from Oslo), the TCP window size and backlog queues matter immensely.

Here is the production configuration we deploy on CoolVDS high-performance instances:

# /etc/sysctl.conf configuration for API Gateways (Nov 2023)

# Maximize the backlog of incoming connections
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535

# Reuse connections in TIME_WAIT state (Crucial for high throughput)
net.ipv4.tcp_tw_reuse = 1

# Increase ephemeral port range to allow more outbound connections to upstreams
net.ipv4.ip_local_port_range = 1024 65535

# Increase TCP buffer sizes for 10Gbps+ links
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

# Protect against SYN flood attacks while maintaining performance
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 4096

# Enable BBR Congestion Control (Kernel 4.9+)
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

Apply these with sysctl -p. The tcp_tw_reuse flag is particularly important if your gateway connects to backend microservices; without it, you will exhaust your ephemeral ports waiting for old connections to close.

2. The Gateway Layer: NGINX Optimization

Whether you use raw NGINX, Kong, or OpenResty, the underlying engine is the same. The biggest mistake I see is not utilizing Keepalive connections to the upstream backend. Without keepalives, NGINX opens a new TCP connection to your backend service for every single request. That adds a full TCP handshake + SSL handshake overhead to every API call.

Here is how you configure the upstream block correctly:

upstream backend_api {
    server 10.0.0.5:8080;
    
    # Keep at least 64 idle connections open to the backend
    keepalive 64;
}

server {
    listen 443 ssl http2;
    server_name api.coolvds-client.no;

    # SSL Optimization for lower latency
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_buffer_size 4k; # Lower buffer size reduces TTFB for API JSON responses

    location / {
        proxy_pass http://backend_api;
        
        # Required to use the 'keepalive' directive in upstream
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        
        # Buffering off for real-time APIs
        proxy_buffering off;
    }
}
Pro Tip: Setting ssl_buffer_size to 4k (default is usually 16k) helps significantly with Time To First Byte (TTFB). Standard HTML pages benefit from 16k, but small JSON API responses get stuck in the buffer waiting to fill up. 4k forces the flush earlier.

3. The Hardware Reality: Why "Cloud" Often Fails

You can tune sysctl all day, but if your underlying hypervisor is stealing your CPU cycles, it's game over. In 2023, many "VPS" providers in the budget sector are effectively selling you a slice of a shared struggle.

Check your "Steal Time" right now:

top -b -n 1 | grep "Cpu(s)"

Look for the st value at the end of the row. If it is consistently above 0.0%, your neighbor is noisy, and your API latency will jitter unpredictably. This is unacceptable for fintech applications or real-time bidding systems.

The NVMe Necessity

API Gateways log heavily. Access logs, error logs, audit trails. If you are on standard SSDs (or worse, spinning rust), your I/O wait times will block the NGINX worker process. We benchmarked this extensively. High-load gateways on CoolVDS NVMe storage show a 40% reduction in 99th percentile latency compared to standard SATA SSD VPS providers.

4. Local Context: Norway, GDPR, and Latency

If your users are in Norway, hosting in a US-east region is a strategic failure. The latency floor is ~90ms. Hosting in Frankfurt drops that to ~25ms. Hosting in Oslo drops it to <5ms via NIX (Norwegian Internet Exchange).

Furthermore, following the Schrems II ruling, transferring personal data to US-owned cloud providers creates a compliance headache regarding the US CLOUD Act. Keeping your stack on European infrastructure like CoolVDS simplifies your Datatilsynet audits significantly.

Summary of Infrastructure Requirements

Component Requirement Why?
Virtualization KVM (Kernel-based Virtual Machine) Full isolation, no container neighbor noise.
Storage NVMe High IOPS for logging and local caching.
Network 1Gbps+ Port Burstable bandwidth for traffic spikes.
Kernel Custom Tuned BBR congestion control enabled.

Final Thoughts

Performance isn't magic. It's a combination of physics, kernel interrupts, and configuration. Don't let a default Ubuntu config throttle your business logic.

If you need an environment where st (steal time) is zero and the hardware doesn't get in your way, deploy a test instance. We built CoolVDS to respect the raw commands you run.

Ready to drop your API latency? Deploy a high-performance NVMe VPS in Norway on CoolVDS in under 55 seconds.