I’ve undertaken a hobby project over the last several months to build a Django web application. I have in mind to build a budgeting or enveloping tool similar to a spreadsheet we’ve been using in our household for the last several years. It’s getting pretty close to being in a state that I can publish to the public and see if others find value in it. I started exploring some hosting options for the app. These are some highlights from exploring different hosting options.
Application Hosting Options
Platform as a Service
Not the least expensive option at the “Hobby” tier, but fairly easy to setup and get your application going. It also includes a “Let’s Encrypt” SSL certificate for your app at no extra cost.
I work with a lot of Azure services at work and wanted to try their Azure App Service to host the Django app. I signed up for an account to get the free $200 credit to use for a month. I wasn’t very impressed with this service. It was the most expensive option I looked at, and the performance was terrible.
I didn’t explore these with anything more than a superficial look.
The pricing and features aren’t what I was looking with Python Anywhere , at least at first glance.
I’ve had my AWS account for more than a year, so I don’t think I qualify for the EB / EC2 free tier of usage any longer. I assume the pricing in AWS would be in the same ball park as Azure App Services.
Virtual Private Servers
Provision the full hosting stack on a VM
I’m looking as just the entry level options for $5 / month until the load demands more. I’ve used both services, and they’re both excellent. Linode sponsors a podcast I enjoy, so I’ve been using them recently.
On a $5 / month “nanode” plan I setup PostgreSQL, Nginx, and the Python stack with gunicorn. I used this Ansible playbook I put together to help with the implementation.
When you verify your custom domain with Heroku your provisioned with a free “Let’s Encrypt” SSL certificate for your app. I had purchased a wildcard certificate with my domain registration because it was sharply discounted. It seems that you need a load balancer add-on with Heroku to use your own custom certificate. I don’t want to pay for that add-on at this stage in the project, so I switched it back to the “Let’s Encrypt” certificate. I’m using the custom certificate with CloudFront to deliver the static content from an S3 bucket, so it doesn’t go to waste.
The metrics and visibility tools at the “Hobby” tiers are pretty good. It costs $7 / month for the dyno and I’m expecting I’ll need to move to a $9 / month “Hobby” Postgresql database sooner than later. At $16 / month, it’s not the least expensive option, but I don’t have to manage the platform like I would with Linode or Digital Ocean, I think the metrics and dashboards for the application are better, and the price is reasonable to me for a “Hobby”.
The performance on the page with the most complicated template and SQL is typically like in the screenshot above, between 180 to 450ms to process and download.
The performance on the $5 / month Linode droplet with the application and database all on the same VM is pretty similar to this.
Heroku is what I’ve settled on hosting my app with for now.
- Azure App Services
This is the interesting part of this exercise.
I wonder if I’m missing something in the configuration because the performance for the cost with this service is awful compared to the other deployment options I’ve tried.
This screenshot shows the best response time I can get from the Azure App Service deployment with the same code base. It’s never better than 2 seconds to process the request, and is often between 3 to 5 seconds.
This isn’t on the least expensive plan either. I moved it from the “Dev / test” B1 plan to the B2 plan, and it improved the response time about 50%. This plan has 7 x the memory of the Heroku Hobby plan and costs 5 x as much.
The database isn’t on the lowest performance tier either.
Between the database cost, the App Service cost, and the static files hosting with blob storage, this would cost over $75 / month.
My impression is that Azure’s target market is enterprise customers much more so than lowly hobbyist like me, but this makes me think I’m doing something wrong. Maybe the performance delivered doesn’t start to converge until the load gets much higher? Maybe there are optimization settings in the platform or in the code I’m not aware of or finding?
However, in terms of performance from the first user making the first request, there’s a stark difference.