Skip to content

Web Server and Application Server

James Brucker edited this page Nov 22, 2025 · 2 revisions

The FastAPI back-end service uses asynchronous code and hence needs an ASGI-capable server.

In addition, the application as a whole may require a separate web server to provide access to static files, TLS, and other features needed by scalable web apps.

Purpose and Role

Component Primary Role Use with FastAPI
Gunicorn with Uvicorn workers Python application server Runs the FastAPI app (ASGI).
Nginx Reverse proxy, static file server, TLS termination Fronts the application server.

Nginx is not an ASGI server, so it cannot run FastAPI directly.

Uvicorn (ASGI Server)

Strengths:

  • Native ASGI support for async FastAPI
  • Direct Python process execution
  • Optimized for async frameworks
  • WebSocket support
  • Easy deployment with workers

Weaknesses:

  • Limited static file handling
  • Basic load balancing only
  • No native TLS termination
  • Less robust security

Gunicorn (with Uvicorn workers)

Capabilities

  • Native support for ASGI when using uvicorn.workers.UvicornWorker.
  • Designed to manage multiple worker processes.
  • Handles worker lifecycle, graceful reloads, and resource limits.
  • Good performance under high concurrency with proper worker tuning.

Weaknesses

  • Not a full-featured reverse proxy.
  • No native ability to serve static files efficiently.
  • TLS termination must be handled by another component, e.g., Nginx, Traefik, Caddy.

Nginx

Strengths

  • Excellent reverse proxy and load balancer.
  • Efficient static file serving.
  • Handles TLS, compression, caching, connection buffering.
  • Rate limiting, security headers.
  • Offloads slow clients from the application server.
  • Very stable under heavy network load.

Nginx

  • Rate limiting & security headers
  • Load balancing across multiple Uvicorn instances
  • Caching & compression

Weaknesses

  • Cannot run Python application directly (no ASGI support).
  • Not a Python process manager.
  • Adds configuration overhead if the environment is simple.
  • Provides no insight into Python worker management or graceful reloads.

Which is more suitable for hosting the FastAPI app?

Use Gunicorn with Uvicorn workers as the actual application server. Nginx is optional but beneficial as a front-end reverse proxy, especially in production.

Recommended Setup for Docker

  • Small deployments: Uvicorn or Gunicorn+Uvicorn workers only
  • Larger, public-facing deployments: Nginx → Gunicorn (Uvicorn workers) → FastAPI

Recommended Architecture

Client → Nginx (reverse proxy) → Uvicorn workers → FastAPI → PostgreSQL

Example docker-compose snippet:

services:
  app:
    command: uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - app

This combination gives you async performance + production-grade features.

Clone this wiki locally