Skip to content

How to Resolve Python Flask 'WARNING: This is a development server. Do not use it in a production deployment."

Learn how to replace Flask's development server with production-ready WSGI servers like Waitress or Gunicorn to ensure performance, security, and reliability for live deployments.

When you start a Flask application using the standard flask run command, you'll see a prominent warning: WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. This message is crucial – it indicates that the built-in server provided by Flask (Werkzeug's development server) is designed only for local development and testing, not for handling live traffic on a production website.

This guide explains why the development server is unsuitable for production and introduces recommended production-ready WSGI servers like Waitress and Gunicorn.

Understanding the Warning: Development vs. Production Servers

  • Development Server (flask run): Provided by the Werkzeug library (Flask's dependency). It's optimized for ease of use during development, featuring:
    • Automatic code reloading (--reload flag).
    • An interactive debugger in the browser (if enabled).
    • Relatively simple, single-process, often single-threaded operation.
  • Production WSGI Server: Applications like Waitress, Gunicorn, or uWSGI are specifically designed to run Python web applications (following the WSGI standard) in a live production environment. They focus on:
    • Performance (handling multiple requests concurrently).
    • Stability and Reliability.
    • Security (fewer debugging features exposed).
    • Scalability (often running multiple worker processes).

The warning exists because the development server lacks the performance, security, and robustness features required to handle real user traffic reliably.

When the Warning Appears (flask run)

You will see this warning whenever you start your Flask application using the standard flask run command in your terminal.

Example app.py:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "<h1>Hello from Flask!</h1>"

Running the Development Server:

export FLASK_APP=app    # Linux/macOS
set FLASK_APP=app       # Windows CMD
$env:FLASK_APP = "app"  # Windows PowerShell

flask run
python -m flask run

Output:

 * Environment: development
 * Debug mode: off # (or on)
 WARNING: This is a development server. Do not use it in a production deployment.
 Use a production WSGI server instead. # <<< THE WARNING
 * Running on http://127.0.0.1:5000
Press CTRL+C to quit

Why the Development Server is Not for Production

  • Performance: It typically handles only one request at a time (single-threaded/process). Under load, requests will queue up, leading to slow response times.
  • Security: If run with the debugger enabled (FLASK_ENV=development or flask run --debug), it exposes a powerful debugger that could allow attackers to execute arbitrary code if accessible externally.
  • Stability: It's not designed for long-running, high-availability scenarios and may lack robustness compared to dedicated WSGI servers.

Solution: Use a Production WSGI Server

To deploy your Flask app, you need to use a production-grade Web Server Gateway Interface (WSGI) server. Popular choices include Waitress, Gunicorn, and uWSGI.

Option 1: Waitress (Cross-Platform)

Waitress is a pure-Python WSGI server that works well on Windows, macOS, and Linux. It's known for its simplicity.

Installation

Install Waitress into your project's virtual environment.

pip install waitress

Running with waitress-serve (Command Line)

This is a common way to start your app using Waitress from the terminal.

waitress-serve --host=0.0.0.0 --port=8080 app:app
  • --host=0.0.0.0: Makes the server accessible on your network (use 127.0.0.1 for localhost only).
  • --port=8080: Specifies the port number.
  • app:app: Points to the app variable (your Flask(__name__) instance) inside the app.py file. Adjust if your filename or variable name differs (e.g., my_project.main:my_flask_app).

Running Programmatically (in app.py)

You can also start Waitress from within your Python script. This is useful for simple deployments or embedding. Modify your app.py:

from flask import Flask
from waitress import serve

app = Flask(__name__)

@app.route("/")
def hello():
    return "<h1>Hello from Flask via Waitress!</h1>"

if __name__ == "__main__":
    print("Starting Waitress server on http://0.0.0.0:8080")
    serve(app, host="0.0.0.0", port=8080)

Now, instead of flask run, you run the script directly:

python app.py

Option 2: Gunicorn (Linux/macOS)

Gunicorn ('Green Unicorn') is a very popular WSGI server for Unix-like systems (Linux, macOS). It's known for its performance and ease of use. It does not run natively on Windows.

Installation

pip install gunicorn

Running with gunicorn (Command Line)

gunicorn --bind 127.0.0.1:8000 --workers=4 app:app
  • --bind: Specifies the address and port to listen on.
  • --workers: Number of worker processes to handle requests (adjust based on CPU cores).
  • app:app: Points to your Flask app instance within your module.

Other Production Options (uWSGI, etc.)

  • uWSGI: Another powerful and widely used WSGI server, often paired with a reverse proxy like Nginx for high-performance deployments. Configuration can be more complex than Gunicorn or Waitress.
  • Nginx/Apache + WSGI Server: In typical production setups, you often run Gunicorn or uWSGI behind a web server like Nginx or Apache, which handles incoming HTTP requests, serves static files, and forwards dynamic requests to the WSGI server.

Importance of Virtual Environments

Always install your Flask application dependencies, including your chosen WSGI server (Waitress, Gunicorn), inside a project-specific virtual environment (venv). This isolates dependencies and avoids conflicts.

Conclusion

The Flask warning WARNING: This is a development server... is a critical reminder not to use the server started by flask run for live applications. It lacks the necessary performance, security, and stability.

To deploy your Flask application correctly:

  1. Choose a production WSGI server: Waitress (cross-platform) or Gunicorn (Linux/macOS) are excellent choices.
  2. Install the chosen server into your project's virtual environment (pip install waitress or pip install gunicorn).
  3. Run your application using the command provided by the WSGI server (e.g., waitress-serve ... app:app or gunicorn ... app:app) instead of flask run.

This ensures your application is served by a robust server capable of handling production loads.

Navigation