The Limitations of The Server

When I looked at starting a blog for hosting my first thought was hopefully, I could get the Oracle arm based servers which are under the free plan. Despite the recent reduction from four arm CPU's to two and from 24GB ram to 16GB, I was unable to get one provisioned sadly.

So if I wanted free hosting the resource the server would have is very limited with only 1/8th of a CPU and 1GB of memory. Having used these in the past for hosting services I knew every bit of ram and CPU matters, if I don't want Policy & Packets to randomly stop working.

The first big challenge was picking the server OS, well more the Linux distribution. Because if I went with Windows Server the OS itself would use all the CPU and the full 1GB of Ram.1 Ubuntu minimal is what I picked, due to it having a low memory and CPU usage and because it's well used making it easy to solve issues I encounter. My second option which I would have preferred to use is alpine Linux, but the big issue with this option it's not supported by oracle so the setup would have been difficult.

The Architecture

Now that we know what the limitations of the server we need to pick how I deploy it. There is a few options my first would be Hugo while it's fast and would be great, I was worried about the performance and memory usage. As a Python dev I also thought about using FastAPI or base Python. While Python has come a long way with performance it's still not the most efficient. With such a constrained server every drop of performance matters, Python is not the best options in this situation.

In the end I decided to make a Go program even though I had never programmed in Go. I thought it would be a good option and reading this article about how Python and Go manages their memory differently, I thought it would be a great option.2

In another article I will talk about the process of how I write these. Starting in Markdown and then convert them to HTML like what Hugo does but built from the ground up.

Memory Footprint

Base minimal Ubuntu while being connected via SSH gave a memory usage of 179Mi and 2Mi used of swap. Once I setup the app using a simple bash script, my memory usage was somehow less at 155Mi of memory and 28Mi of swap. The only conclusion is Ubuntu was doing something in the background when I took the first memory measurement and the website was so efficient that it's negligible while not being hit with requests.

Load Testing

In order to see how the site would handle loads, I performed a load test suite. The test generator simulated traffic at various rates from 1 RPS up to 1000 RPS for 60 seconds each, with at least 4% of the requests consisting of search queries.

1. Request Latency vs RPS

Below is the latency response curve. Up to 150 RPS, response times are extremely stable at around 53ms. At 300 RPS, latency rises slightly but remains very healthy. Beyond 300 RPS, the server saturates, causing queue delays and timeouts (5,000ms threshold).

xychart-beta
    title "Request Latency vs RPS (Capped at 1000ms+)"
    x-axis ["1", "3", "5", "10", "20", "50", "100", "150", "300", "500", "750", "1000"]
    y-axis "Latency (ms)"
    bar [53.81, 53.65, 53.77, 53.04, 52.98, 51.96, 52.12, 52.99, 106.12, 1000.00, 1000.00, 1000.00]
    line [58.67, 307.73, 62.74, 66.86, 61.92, 303.80, 66.28, 172.81, 426.35, 1000.00, 1000.00, 1000.00]

(Bars: Median P50 latency; Line: P95 latency. Latencies exceeding 1000ms are capped at 1000ms to preserve scale).

2. Server CPU Usage vs RPS

The VM has 2 CPU cores (max 200% capacity). The blog engine is highly efficient, using less than 20% of a single core up to 150 RPS. Saturation happens between 300 and 500 RPS as CPU consumption hits the core limit.

xychart-beta
    title "Average and Max Server CPU % (2 Cores Max 200%)"
    x-axis ["1", "3", "5", "10", "20", "50", "100", "150", "300", "500", "750", "1000"]
    y-axis "CPU %"
    bar [0.18, 0.48, 0.79, 1.66, 2.98, 6.78, 13.10, 19.95, 77.71, 182.44, 185.97, 185.13]
    line [1.00, 1.00, 2.00, 4.99, 4.00, 10.00, 17.98, 62.15, 134.83, 198.75, 198.75, 203.94]

(Bars: Average CPU %; Line: Max CPU %)

3. Server Memory Usage vs RPS

Memory footprint remains incredibly stable around 18–19 MB under low-to-medium loads, and only increases to ~34 MB (peaking at ~50–60 MB) under full saturation (1000 RPS).

xychart-beta
    title "Average and Max Server Memory Usage"
    x-axis ["1", "3", "5", "10", "20", "50", "100", "150", "300", "500", "750", "1000"]
    y-axis "Memory (MB)"
    bar [19.25, 18.85, 18.81, 18.86, 18.91, 18.96, 18.86, 18.65, 21.05, 39.05, 30.98, 34.25]
    line [22.93, 19.10, 19.10, 19.19, 19.24, 19.29, 19.23, 19.29, 22.76, 66.37, 37.98, 50.99]

(Bars: Average Memory MB; Line: Max Memory MB)

Is it a Success?

Well I would say so if you're reading this without any issues, I'm surprised by how much I can get out of the tiny Oracle VPS because lets say we want a comfortable margin increase I get tons of site traffic saying 50 RPS is a comfortable level and lets say that each user send 10 Requests per Visit to the site with all my users come over an hour time frame. We take 50 Request per Second Times it by 60 two times and get 180,000 then divide that by 10 where I get 18K Visitors a day.

Obviously if I post images and have more content on each page the amount of requests I can handle will drop. I will come back in a month or two and do a follow up when I have more page and see how it does then I have images on some pages.


  1. Xelu86. (2024, October 23). Hardware requirements for Windows Server. Microsoft.Com. https://learn.microsoft.com/en-us/windows-server/get-started/hardware-requirements?tabs=ram&pivots=windows-server-2019 ↩︎

  2. amir. (2026, May 25). Memory Under the Hood: Why Go Often Feels Faster Than Python. DEV Community. https://dev.to/amirsefati/memory-under-the-hood-why-go-often-feels-faster-than-python-3pb3 ↩︎