Vertical scaling refers to increasing the resources, such as CPU, memory of a single server or container to handle more load.

The MCP server uses Uvicorn with asyncio for high-performance concurrent request handling. Uvicorn is a lightning-fast Asynchronous Server Gateway Interface (ASGI) server designed for Python applications, whereas asyncio is a Python standard library that provides an event loop for asynchronous programming. By default, the server runs with a single worker, which is suitable for most I/O-bound workloads. For CPU-intensive or mixed workloads, you can increase the number of workers to utilize multiple CPU cores effectively.

Default configuration: Single worker

The default configuration uses a single worker process. This setup is optimized for typical MCP operations that are I/O-bound and require efficient concurrency handling.

The following settings describe the default behavior when running with a single worker:
  • Default settingUVICORN_WORKERS=1
  • Best for—I/O-bound workloads that are typical of MCP operations
  • Concurrency—Asyncio event loop handles thousands of concurrent connections
  • Memory usage—Lower memory footprint per connection

Multi-worker configuration

For production environments, you can configure multiple workers to take advantage of available CPU cores. This approach improves scalability and performance for compute-intensive workloads.

These examples show how to configure multiple workers for production scaling based on CPU count:
# Production scaling based on CPU count
export UVICORN_WORKERS=$(nproc)        # Linux: use all CPU cores
export UVICORN_WORKERS=$(sysctl -n hw.ncpu)  # macOS: use all CPU cores

# Conservative approach (recommended)
export UVICORN_WORKERS=$(($(nproc) - 1))     # Leave 1 core for system

Scaling guidelines

Refer to these guidelines for setting worker counts according to workload characteristics:
Workload type Worker count Reasoning
I/O heavy (typical) 1–2 workers Asyncio handles concurrency efficiently
CPU intensive CPU cores minus 1 Enables parallel processing without overcommit
Mixed workload CPU cores divided by 2 Balances parallelism and overhead
Memory constrained 1 worker Each worker loads the full application

Environment variables for production tuning

When you export a production bundle, the generated docker-compose.mcp.yml file includes default Uvicorn settings. These defaults can be overridden using environment variables to tune worker counts, proxy headers, and other parameters for production environments. For example, this code block shows the default environment variable configuration in the auto-generated docker-compose.mcp.yml file:
# In docker-compose.mcp.yml (auto-generated)
environment:
  UVICORN_WORKERS: '${UVICORN_WORKERS:-1}'              # Override via .env file
  UVICORN_PROXY_HEADERS: '${UVICORN_PROXY_HEADERS:-0}'  # Set to 1 behind a Load Balancer
# ... other settings
Where,
  • UVICORN_WORKERS controls the number of worker processes. The default is 1.
  • UVICORN_PROXY_HEADERS should only be enabled when the application runs behind a trusted load balancer.
  • Additional settings can be added or overridden using an .env file or host environment variables.

Methods to override environment variables

To optimize performance and security, you can override the default Uvicorn settings in the generated docker-compose.mcp.yml. The recommended approach is to use an .env file, but other methods are also supported. For production tuning, you can override Uvicorn environment variables in the following ways:
  • Use an .env file (recommended)—Create an .env file in the same directory as docker-compose.mcp.yml and define the following variables:
    # Create .env in same directory as docker-compose.mcp.yml
    UVICORN_WORKERS=4                              # Worker processes based on CPU count
    UVICORN_PROXY_HEADERS=1                       # Enable when behind load balancer
    UVICORN_FORWARDED_ALLOW_IPS="10.0.0.0/8"     # Trust specific proxy IPs (security best practice)
  • Use server environment file—Edit the server.env file in the generated profile directory to tune settings for your workload:
    # Edit generated/<profile>/server/server.env
    UVICORN_WORKERS=2                    # Tune for your workload
    UVICORN_KEEPALIVE=5                 # Keep-alive timeout
    UVICORN_SHUTDOWN_TIMEOUT=0          # Graceful shutdown timeout
  • Use host environment variables—Export environment variables on the host before running Docker Compose:
    # Export before running docker-compose
    export UVICORN_WORKERS=$(nproc)     # Use all CPU cores
    export UVICORN_PROXY_HEADERS=1       # Behind load balancer
    docker-compose up

Security considerations for proxy configuration

When deploying the application behind a load balancer or reverse proxy, it is critical to configure proxy-related settings securely. Incorrect configuration can expose the application to header spoofing attacks or allow untrusted sources to manipulate request routing. Uvicorn provides environment variables to control how proxy headers are handled, but these must be set carefully to prevent security vulnerabilities. The following table lists the environment variables you can define in the .env file and their purpose:
Environment variable Example value Description
UVICORN_WORKERS 4 Safe for direct deployments. Ignores all X-Forwarded-* headers.
UVICORN_PROXY_HEADERS 1 Enable only when the application runs behind trusted load balancers or proxies.
UVICORN_FORWARDED_ALLOW_IPS "10.0.0.0/8" Always set to specific proxy IP ranges in production. The default trusts all IPs, which is not secure.