Welcome to your first lesson on FastAPI! I'm excited to guide you on your journey from Django to mastering this modern, high-performance framework.
Given your background in building full-stack applications with Django, you're already familiar with the core components of a web framework. Our goal in this course is to build on that knowledge, drawing direct comparisons to help you understand not just how FastAPI works, but why it's designed the way it is.
In this introductory lesson, we'll start at the very foundation. We will address the following learning outcome:
Compare the server gateway interfaces: ASGI used by FastAPI vs. WSGI used by Django.
This might sound a bit abstract, but understanding this single difference is the key to grasping FastAPI's main advantages: its speed and its support for modern asynchronous features. We'll explore what these interfaces are, how they differ, and why FastAPI's choice of ASGI is so significant.
Let's begin.
What is a Server Gateway Interface?
When you run a Django application in production, you don't just use python manage.py runserver. As you know, that's a simple development server. For production, you use a more robust web server like Gunicorn. But how does Gunicorn, a general-purpose server, know how to talk to your specific Django application?
This is where a Server Gateway Interface comes in. It's a standard, a specification, that defines a common language between web servers and Python web applications.
Think of it as a universal adapter. Your Django or FastAPI application is a device with a specific plug, and the web server (like Gunicorn or Uvicorn) is the wall socket. The gateway interface (WSGI or ASGI) is the adapter that ensures they can connect and communicate seamlessly.

For years, the standard adapter for Python has been WSGI.
WSGI: The Synchronous Standard
WSGI (Web Server Gateway Interface) is the long-standing standard that your Django applications use. It was designed for a synchronous world.
What does "synchronous" mean in this context? It means that when a request comes in, the server assigns it to a worker process/thread, which handles that single request from start to finish. The worker is "blocked" — it cannot do anything else until it has produced a complete response for that request.
To understand this better, let's watch a short segment from a video that uses a great analogy.
The following clip from 'WSGI & ASGI Simplified' by Jerin Jose uses a simple breakfast-making analogy to explain how WSGI handles requests.
Watch the two segments from 00:46 to 03:30. The first part explains the sequential nature of WSGI. The second part explains how WSGI servers like Gunicorn use 'workers' to handle multiple requests at once.
As the video explains, if you want to handle more than one request at a time with WSGI, you need more "cooks" in the kitchen. In a production Django setup, this means configuring your WSGI server (like Gunicorn) to run multiple worker processes. Each worker can handle one request at a time. This is a form of concurrency based on multiprocessing.

The key takeaway for WSGI is: one request per worker thread at a time. If that request involves waiting for a database query or a call to another API (I/O-bound operations), the worker thread is stuck waiting.
ASGI: The Asynchronous Successor
FastAPI is built on a newer standard: ASGI (Asynchronous Server Gateway Interface). It was created specifically to address the limitations of WSGI and to bring the power of Python's asyncio library to web development.
ASGI enables true asynchronous request handling. Instead of a worker being blocked while waiting for an I/O operation, it can hand off the waiting task and pick up a new request. When the waiting task is complete, the event loop will return to it to finish the job.
Let's return to the breakfast analogy to see how this changes things.
Now, let's watch the next part of the same video, which explains the ASGI approach using the same analogy.
Watch the segment from 03:30 to 05:04. Pay close attention to how the 'cook' switches between tasks instead of waiting idly.
This ability to juggle tasks is the core of asynchronous programming. Instead of needing many workers to handle many concurrent users, a single ASGI worker can handle many I/O-bound requests concurrently.
- Django (WSGI): Handles 10 concurrent users by using 10 separate workers/threads.
- FastAPI (ASGI): Can handle those same 10 users within a single worker process by switching between their requests during I/O wait times.
This is why FastAPI, running on an ASGI server like Uvicorn, can achieve such high performance with fewer resources, especially for applications with lots of database calls, file operations, or external API requests. The right side of the diagram we saw earlier illustrates this perfectly: Process A sends a request and continues working on other things.
The ASGI Application Interface
The difference between WSGI and ASGI goes down to the code level. The "contract" they define for an application is different.
- A WSGI application is a callable that accepts
environ(a dictionary of request data) andstart_response(a function to send headers). - An ASGI application is an
asynccallable that acceptsscope(connection info),receive(an async function to get messages), andsend(an async function to send messages).
You don't need to memorize these details, as FastAPI handles them for you. But understanding that ASGI is fundamentally designed around an async event-driven message system is important.
To see what this looks like under the hood, the following video gives a clear, low-level explanation of the ASGI specification.
Asynchronous Web Apps in Python
This clip from 'Asynchronous Web Apps in Python' by mCoding dives into the ASGI specification itself. It's a bit more technical, but it clearly shows why ASGI is a more powerful and flexible interface than WSGI.
Watch from 01:08 to 05:07. Focus on understanding the three arguments of an ASGI application (scope, receive, send) and how they represent a more flexible, event-based way of communicating compared to WSGI's simple request-response model.
This event-based structure is also what allows ASGI to support more than just HTTP. It can handle long-lived connections for protocols like WebSockets natively, something WSGI was never designed for.
WSGI vs. ASGI: A Direct Comparison
Your experience with Django has been with a framework that was born in the WSGI era but has been adapted to support ASGI. In contrast, FastAPI was built from the ground up as an ASGI-native framework.
Let's summarize the key differences.
| Feature | WSGI (used by Django) | ASGI (used by FastAPI) |
|---|---|---|
| Model | Synchronous | Asynchronous |
| Concurrency | Multi-processing / Multi-threading (many "cooks") | Asynchronous event loop within a process (one "cook" who juggles) |
| I/O Handling | Blocking (a worker waits for I/O to complete) | Non-blocking (a worker handles other tasks during I/O) |
| Primary Use-Case | Traditional request-response web applications | High-concurrency, I/O-bound APIs, real-time apps |
| Protocols | HTTP only | HTTP, WebSockets, and more |
| Primary Server | Gunicorn, uWSGI | Uvicorn, Hypercorn, Daphne |
This article provides a good textual summary of these points if you'd like to read more.
For a detailed breakdown and further examples, I recommend reading the article 'WSGI vs ASGI: Complete Guide' from DEV Community.
Read the sections 'Key Differences Comparison' and 'When to Use Each'. This will reinforce the concepts we've discussed and provide context on the trade-offs.
Key Takeaways
- WSGI is the synchronous gateway interface that you've used with Django and Gunicorn. It handles concurrency by running multiple processes or threads, with each one handling a single request from start to finish.
- ASGI is the asynchronous successor to WSGI, and it is the foundation of FastAPI and its server, Uvicorn.
- The primary advantage of ASGI is its non-blocking nature. It allows a single worker to handle many concurrent connections by switching between tasks during I/O-bound waiting periods (like database queries).
- This makes ASGI (and thus FastAPI) extremely efficient for building high-performance APIs that spend a lot of time waiting on network or disk operations.
You've now learned about the single most important architectural difference between the Django world you're coming from and the FastAPI world you're entering. This isn't just a technical detail; it influences everything from how you write your code to how your application performs under load.
In our next lesson, we will build on this foundation. We'll explore FastAPI's async-first programming model, see how to write async functions, and understand when to use them versus regular def functions. This will be our first step into writing actual FastAPI code.