Python/Mongo website on a small 1GB RAM VPS
Tags: vps, python, mongodb, linode
Published: 2023-02-01 14:30:58

---
title: Python/Mongo website on a small 1GB RAM VPS    
published: true
description: Load stats on a small 1GB, 1CPU VPS
tags: vps, python, mongo, linode  
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2022-11-01 14:07 +0000
---

I just released a small website which will most probably be taken down in 1-2 years because of lack of users. This was an idea which bugged me for a long time, so I had to do it (a little bit of OCD).

The website is pretty simple and does the following:
- scrape some data once per day;
- clear old data once per day;
- serve that scraped data with Python/FastAPI from MongoDB;
- added some extra features on that scraped data so users can do something with it;
- SSR html pages served with Jinja2 with some custom logic; 

Docker services running on that small 1GB RAM, 1CPU, VPS (Linode/Nanode):
- Python/FastAPI web application (serves data to users);
- Python Worker (which scrapes/cleans the data in the background);
- MongoDB (holds all data);
- Caddy2 as a reverse proxy;

The amount of RAM free with the website idle **93MB** RAM.
```
Tasks: 118 total,   1 running, 117 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.7 us,  1.0 sy,  0.0 ni, 98.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.3 st
MiB Mem :    969.4 total,    93.2 free,    315.9 used,    519.3 buff/cache
MiB Swap:    512.0 total,    438.7 free,     73.3 used.    506.2 avail Mem 
```

I tried a bit of load testing using baton (a golang cli load testing tool). 

Here are some load testing stats on that VPS with 100 concurent users making 1000 requests:
```
====================== Results ======================
Total requests:                                  1000
Time taken to complete requests:        14.646065944s
Requests per second:                               68
===================== Breakdown =====================
Number of connection errors:                        0
Number of 1xx responses:                            0
Number of 2xx responses:                         1000
Number of 3xx responses:                            0
Number of 4xx responses:                            0
Number of 5xx responses:                            0
=====================================================
```

It took around 15 seconds to complete...but no errors which is good!


Now here is the same on my laptop (16GB RAM, 7 CPU's):
```
====================== Results ======================
Total requests:                                  1000
Time taken to complete requests:         128.916784ms
Requests per second:                             7757
===================== Breakdown =====================
Number of connection errors:                        0
Number of 1xx responses:                            0
Number of 2xx responses:                            0
Number of 3xx responses:                         1000
Number of 4xx responses:                            0
Number of 5xx responses:                            0
=====================================================
```  

It took around 130 miliseconds to complete! 

Some stats with 20 requests made by 1 user on the VPS:
```
====================== Results ======================
Total requests:                                    20
Time taken to complete requests:         1.271508214s
Requests per second:                               16
===================== Breakdown =====================
Number of connection errors:                        0
Number of 1xx responses:                            0
Number of 2xx responses:                           20
Number of 3xx responses:                            0
Number of 4xx responses:                            0
Number of 5xx responses:                            0
=====================================================
```

The request used for load testing does the following:
- makes a query to MongoDB for 10 random posts;
- renders those posts with Jinja2 on the server + some template logic (if else);

Results may differ for your use case and tech used, but I think this is a good average for a Python/MongoDB website.