Where to Host a Python Web App

Jeff Morhous headshot

Jeff Morhous

@JeffMorhous

Building a production-ready Python web app is kind of pointless if you don’t ship it. Still, many developers struggle to choose where to host their Python applications. There’s a rich ecosystem of hosting options for Python apps, from classic platforms like Heroku to modern container-based services like Fly.io and AWS ECS. Whether you’re using Django, Flask, FastAPI, or some other Python framework, you have options.

In this guide, I’ll walk you through the most popular options, comparing developer experience, scalability, performance, and cost. Let’s jump in!

Using Docker makes a difference

One of the first considerations for your Python deployment is usually whether you want to deploy using Docker containers or rely on platform-provided build tools (like Heroku’s buildpacks).

Platforms like Heroku (and similarly Render and Railway) can take your code and build it using buildpacks, which detect your app’s language and install needed dependencies. This means you don’t need to create a Docker image (and manage the build process) or manage the OS-level setup yourself. For example, Heroku’s buildpacks run on a maintained stack image that Heroku’s engineers keep patched and secure. This is a huge boost to developer experience, since security updates to the OS and runtime are handled for you automatically.

Hosting a Python app on Heroku

Using Docker abstracts away a lot of problems, but you’ll still have to maintain and update your image.

Services like AWS ECS or Fly.io require you to containerize your app (i.e., provide a Docker image). If you already develop with Docker, this might be fine or even preferred. Containers give you more control over the environment. You get to (and have to) define exactly what OS, dependencies, and configuration your app runs with. The trade-off is that you become responsible for maintaining that environment (applying security patches to the base image, etc.).

Hosting a Python app on ECS

Meanwhile, Amazon’s Elastic Container Service (ECS) is fundamentally a container platform. It lets you deploy Docker images onto AWS infrastructure. Similarly, Fly.io deployments are via Docker images or their flyctl builder. So, if your development workflow already includes building Docker images, platforms like ECS or Fly.io will fit naturally. But if you’ve never touched Docker, using a buildpack-based platform like Heroku or Render will spare you a lot of up-front and continuing infrastructure work.

I don’t really have a strong opinion about whether you should use Docker. I’ve shipped plenty of projects with and without it. But your choice of whether to containerize your app affects your hosting options, so it’s one you should make pretty early.

If you’re not using Docker, consider Heroku

One category of option for hosting Python apps is the Platform as a Service (PaaS) option. These platforms offer solutions to give you a ready-to-go hosting environment with minimal setup. You push your code, the platform builds and runs it, and handles scaling (sort of), maintenance, and more.

Heroku is the tried and true player in this space and often pointed to as the gold standard for developer experience. Developers love Heroku because it’s “stupid easy” to use. The “everything just works” philosophy is why Heroku is praised for developer productivity.

From a developer experience standpoint, Heroku is hard to beat. The platform abstracts away servers and infrastructure so much that you might forget they exist (but you should still think about autoscaling, which we’ll talk about later). However, all these benefits come at a bit of a price premium. Hobby projects start at $7/month for a basic dyno, and for larger apps, costs can ramp up pretty fast. Autoscaling is a good lever to reduce your costs, but it’s not platform-specific, so we’ll cover it later in the article.

I’ll go over some other PaaS options next, but we have an ever deeper dive into Heroku alternatives on the blog as well!

Render is a cheaper Heroku alternative

Render is a newer, cheaper PaaS that has gained popularity in the last couple of years. It provides a similar “git push to deploy” experience and runs on top of AWS as well. Many Heroku users started looking at Render when Heroku’s free tier ended, since Render initially offered free plans for small services. Render is often cheaper than Heroku, but has a bit more cumbersome of a developer experience.

Render for Python apps

Ultimately, Render is a great option in the PaaS space, especially if cost is a primary concern. It’s a solid platform that handles your infrastructure for you, even if it’s missing some Heroku magic.

Fly is usually the cheapest choice

Fly.io is a newer and growing option for hosting, especially for those who have a need for globally distributed compute. It runs your app in Docker containers, on Fly’s own hardware network distributed across dozens of regions. They advertise Python support, especially for Django.

Running a Python app on Fly

The developer experience with Fly.io is a bit different from Heroku. You typically write a config file to define how your app should run (regions, instance size, etc.), and you deploy via the CLI.

Fly expects a lot more from the developer to configure and maintain compared to a fully managed platform like Heroku. Despite requiring a bit more tinkering, Fly is might be a good choice if you are cost-conscious and not afraid to tinker. For example, if Heroku’s costs are too high for you and you don’t mind getting your hands dirty with config files, Fly can be a great choice. That being said, if you’re willing to get into the details of your infrastructure, you may as well consider using a cloud platform like ECS yourself.

Amazon ECS is AWS’s managed container orchestration option. Instead of giving you a full platform, ECS sits a bit lower-level: you define a task, and ECS will run it on either EC2 instances or AWS’s serverless Fargate capacity. You aren’t running on your own bare-metal servers, but you’re operating much closer to the infrastructure. On ECS, you’ll have to configure things like networking, a load balancer (if you want one for a web app), auto-scaling groups or Fargate scaling policies, and son on. You can do this with IaC like Terraform, but it’s a far cry from the simplicity of Heroku.

The advantage of ECS is deep AWS integration and seemingly unlimited scalability. You can fine-tune every aspect of your deployment. But the flip side of that is that you have to fine-tune every aspect of your deployment.

Hosting Python on AWS

From a developer experience perspective, though, ECS is very involved. Expect to be writing Terraform or CloudFormation templates, or using the AWS console to wire things together.

For small apps, AWS often looks cheaper on paper, especially as you scale (you pay only for raw resources, no PaaS markup). Still, you should only go with this option if you’re using Docker and willing to spend a tremendous amount of time on your infrastructure. I personally don’t use AWS for any projects, and only find it the best choice for enterprise teams.

Self-hosting is attractive for only a small subset of Python apps

Beyond PaaS and container platforms, there’s always the most basic option. You can rent a server (more often a VM) and run the app yourself. This could mean a droplet on DigitalOcean, a server on Hetzner, a Linode VM, or even a physical server in your own data center. This route offers maximum control and potentially massive cost savings, but at the expense of your time and effort.

If you go this route, you’ll be responsible for everything: installing the runtime (Python, Gunicorn/Uvicorn, etc.), setting up a web server (NGINX or Caddy for reverse proxy), configuring everything to keep your app running, handling logs, monitoring, scaling, and security updates.

In the Rails community, DHH of 37Signals has loudly claimed victory after their big move from AWS to self-hosted infrastructure, citing massive cost savings. This is compelling to an extent, but his business is predictable in volume and has a dedicated ops team capable of supporting the complexity of all this infrastructure.

DHH at the Rails 8 keynote

Chances are, you don’t have a dedicated ops team at your disposal. More likely, you are the ops team, and that’s just one part of your job.

I don’t think I can recommend self-hosting with a straight face. It’s not even that it’s “too hard”. It just comes at an incredible opportunity cost. Still, it’s popular in the Python community. If you’re going to self-host, understand that you’re saving money but spending time. Expect a big up-front time investment and ongoing work to support this choice.

Autoscaling whatever you choose

For almost all of these options, autoscaling is a critical part of your hosting. While vertical scaling is important, scaling horizontally is an incredibly useful lever to pull. You need to be able to scale up to meet demand and scale down to keep costs under control.

Heroku also has an autoscaling feature, but it’s limited to Performance-tier dynos and based on request response time thresholds. Many have found Heroku’s native autoscaler to be a bit slow-reacting. Render supports autoscaling on its paid plans, but it’s limited to hardware metrics like CPU usage, which might not catch every scenario where your number of servers should change. ECS is a whole different story. Its autoscaler requires some serious configuration and can still be unreliable.

Given these challenges, you may wish to go with a third-party autoscaler like Judoscale. Judoscale provides autoscaling as an add-on for platforms like Heroku, Render, Fly, and even ECS. There are plenty of Python apps using Judoscale to keep their apps quick and costs low.

The key difference between native autoscalers and Judoscale is that Judoscale focuses on request queue time rather than CPU. This is a direct measure of how long incoming requests wait to be served, which is the most direct indicator that you need more capacity to handle your current load. And when you add background tasks using Celery or RQ, Judoscale will autoscale your worker services as well, including the option to turn them off completely when your task queues are empty.

My recommendation for hosting a Python web app

If raw developer experience and reliability are your top priorities, Heroku is still a fantastic choice. You’ll get easy deployment, a robust ecosystem, and the confidence that comes with a platform that’s been supported huge portions of the internet for many years.

When I’m working on a project and I’m excited about getting it in front of users, I use Heroku. I have used the other platforms with similar success, but I only use ECS or a VPS if I’m intentionally tinkering. If you’re considering a self-hosted option because of costs, check out the pricing calculator to compare the costs of platforms first!