Akash Chatterjee

November 15, 2024

An overview of Flask's architecture and configurations for production - a kitchen analogy

As someone who works with Flask in production environments, I've found that the best way to understand web architecture is through real-world analogies. Let's talk about web servers, workers, and threads using something we all understand - a restaurant kitchen.

The Restaurant (aka Your Web Server): Okay, picture this, your web server is basically a restaurant. Users are hungry customers walking in with their orders (requests), and they all want to be served ASAP.

In Flask's world, we typically use Gunicorn as our production server. Think of it as the restaurant's management system.
Quick side note: please, please don't ever use Flask's built-in development server in production. That's like trying to run a professional kitchen with your home microwave. Trust me, I learned this one the hard way...

Two Ways to Serve:
WSGI vs ASGI

Let's talk about waiters, because that's essentially what we're dealing with here.

WSGI (The Old-School Waiter):
Picture that one waiter who insists on doing everything sequentially. They take your order, wait for the kitchen, serve your food, and only then move to the next table. That's WSGI for you - reliable but kind of... stuck in their ways. Flask typically uses this approach, and honestly, it works pretty well for most cases. It stands for "Web Server Gateway Interface" btw.

ASGI (The Multitasking New-Gen Waiter)
Now imagine one of those super-efficient waiters who's somehow everywhere at once. While your food's cooking, they're already taking another order, refilling someone's water, and probably planning tomorrow's menu too. That's ASGI (Asynchronous Server Gateway Interface). Frameworks like FastAPI use this.

The Kitchen Crew (Where the Magic Happens): This is where it gets interesting.

Workers (Your Chefs)
Think of workers as individual chefs. Each one needs their own workspace, equipment, and they work independently. More workers means more orders handled at once, but each one needs their own resources. It's like hiring more chefs but realising that you need more stoves, prep stations, and kitchen space for each one.

Threads (The Chef's Multitasking Abilities)
Now, here's where Python throws us a curveball with its GIL (Global Interpreter Lock). I won't bore you with the technical details, but here's the deal, threads are like a chef's ability to juggle tasks. They can have multiple things planned, but they can only actively cook one thing at a time. When something's in the oven, though, They can prep something else.

The "Magic" Formula (That's Not Really Magic):
workers = (2 × number of CPU cores) + 1
Why this works:
  • Two workers per CPU core (like having two chefs per stove)
  • That extra +1 worker? Think of it as your head chef keeping everything running smoothly
  • And no, more isn't better. I've tried. It's like having too many cooks in the kitchen - pure chaos!

When you're setting up Flask in production:
  • Use workers for the heavy lifting (CPU stuff)
  • Let threads handle the waiting game (I/O operations)
  • Match workers to your CPU cores (don't get greedy!)
  • Keep threads reasonable (2-4 per worker usually does the trick)
  • And always keep monitoring, monitoring, monitoring!

Look, at the end of the day, it's not about maxing out your server with workers and threads. It's about finding that sweet spot where everything runs smoothly. Kind of like finding the perfect balance in a kitchen,you don't need 20 chefs to make great food, you just need the right setup.

About Akash Chatterjee

When not coding or solving technical challenges, I'm contemplating the deeper questions that lie at the intersection of innovation and human existence.