<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: K.M Ahnaf Zamil</title>
    <description>The latest articles on Forem by K.M Ahnaf Zamil (@ahnafzamil).</description>
    <link>https://forem.com/ahnafzamil</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F609841%2F259ce4c9-9740-46f0-b546-4037c8cddda5.png</url>
      <title>Forem: K.M Ahnaf Zamil</title>
      <link>https://forem.com/ahnafzamil</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ahnafzamil"/>
    <language>en</language>
    <item>
      <title>Building a multi-tenant PaaS application: Part 1 (Architecture &amp; Initial Design)</title>
      <dc:creator>K.M Ahnaf Zamil</dc:creator>
      <pubDate>Sat, 04 Oct 2025 11:00:02 +0000</pubDate>
      <link>https://forem.com/ahnafzamil/building-a-multi-tenant-paas-application-part-1-architecture-initial-design-4d49</link>
      <guid>https://forem.com/ahnafzamil/building-a-multi-tenant-paas-application-part-1-architecture-initial-design-4d49</guid>
      <description>&lt;p&gt;&lt;strong&gt;TLDR:&lt;/strong&gt; I’m building Stratus, a multi-tenant PaaS, to understand how platforms like Heroku handle orchestration and scaling. Part 1 covers the architecture, node scheduling, agent design, and deployment flow. Follow along for lessons learned from building distributed infrastructure from scratch.&lt;/p&gt;

&lt;p&gt;There's a difference between using a tool and understanding how it works.&lt;/p&gt;

&lt;p&gt;I've been deploying applications to Heroku, Railway, and similar platforms for years. They abstract away the infrastructure complexity - which is great for shipping products, but terrible for learning how distributed systems actually work.&lt;/p&gt;

&lt;p&gt;I wanted to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How does a platform decide which server should run your code?&lt;/li&gt;
&lt;li&gt;How do multiple servers coordinate without stepping on each other?&lt;/li&gt;
&lt;li&gt;What happens when things fail? How does the system recover?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can read about these problems in books and blog posts. But for me, the only way to truly understand something is to build it.&lt;/p&gt;

&lt;p&gt;That's why I'm building &lt;a href="https://github.com/ahnaf-zamil/stratus" rel="noopener noreferrer"&gt;Stratus&lt;/a&gt; - a multi-tenant PaaS infrastructure that handles container orchestration across distributed nodes. It's not fully production-ready (yet), and that is not the real goal. The goal is to understand the foundational patterns that platforms like Heroku rely on.&lt;/p&gt;

&lt;p&gt;Turns out, building even a simplified version teaches you more than a dozen textbooks.&lt;/p&gt;

&lt;p&gt;This is Part 1 - covering the foundation of Stratus. I'll be writing more parts as the project progress.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is &lt;a href="https://github.com/ahnaf-zamil/stratus" rel="noopener noreferrer"&gt;Stratus&lt;/a&gt;?
&lt;/h2&gt;

&lt;p&gt;Its a multi-tenant Platform-as-a-Service infrastructure I built to understand how platforms like Heroku work under the hood. &lt;/p&gt;

&lt;p&gt;It handles code uploads and deployments, intelligently selects compute nodes based on resource availability, agent-based orchestration, fault-tolerant task distribution with health checks, etc.&lt;/p&gt;

&lt;p&gt;At its current state, the project is optimized for batch jobs and worker tasks. HTTP ingress and external traffic routing is planned next.&lt;/p&gt;

&lt;h2&gt;
  
  
  High-Level Architecture
&lt;/h2&gt;

&lt;p&gt;I tried to go for a K8s-like architecture for this project whilst keeping it as simple as possible. &lt;br&gt;
There are four main components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;API Server&lt;/code&gt; (user-facing, accepts deployments)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Management Plane&lt;/code&gt; (The puppet master i.e. orchestration brain, schedules tasks and keeps track of compute nodes along with health checks)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Deployment/Compute Nodes&lt;/code&gt; (Virtualized or bare metal servers that run containers, each are a part of the Stratus cluster, managed by the Management Plane)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Node Agent&lt;/code&gt; (An agent software that runs on each Deployment Node in order to respond to health check requests, deploy and manage containers)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1wziffwe3yyg82ipct2x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1wziffwe3yyg82ipct2x.png" alt="Stratus Architecture Diagram" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a nutshell, the architecture follows a control plane/data plane pattern. The Management Plane makes decisions about where to run workloads. Deployment Nodes execute those decisions. Agents on each node handle communication and container lifecycle management.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Deployment Flow (Step-by-Step)
&lt;/h2&gt;

&lt;p&gt;The entire deployment flow starts with the user uploading the code as an entire folder, which gets stored as a ZIP file on MinIO/S3.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: User uploads code&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API receives code upload&lt;/li&gt;
&lt;li&gt;Creates deployment record&lt;/li&gt;
&lt;li&gt;Sends gRPC deployment task to Management Plane&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Management Plane schedules the deployment&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Queries available compute nodes&lt;/li&gt;
&lt;li&gt;Evaluates resource availability (CPU, memory, existing containers)&lt;/li&gt;
&lt;li&gt;Selects the least-burdened node&lt;/li&gt;
&lt;li&gt;Sends task to that node's Agent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a snippet of how the Management Plane selects the optimal node&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_least_burdened_node&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Returns the node_id of the least burdened node based on CPU and memory.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;_nodes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

    &lt;span class="n"&gt;sorted_nodes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;_nodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cpu&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mem&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sorted_nodes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Agent executes the deployment&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Receives deployment task&lt;/li&gt;
&lt;li&gt;Pulls user code from S3 and mounts it onto Docker container&lt;/li&gt;
&lt;li&gt;Runs container with &lt;code&gt;stratus_init.sh&lt;/code&gt; as entrypoint&lt;/li&gt;
&lt;li&gt;Reports success/failure back to Management Plane&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Deployment is live&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Container is running&lt;/li&gt;
&lt;li&gt;Management Plane tracks it&lt;/li&gt;
&lt;li&gt;User sees deployment status&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Agent-Based Architecture
&lt;/h2&gt;

&lt;p&gt;In order to register a worker machine as a part of the Stratus cluster and to run containers on it, I created Agent applications to run on each Deployment Node.&lt;/p&gt;

&lt;p&gt;Initially, these are the problems I faced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Management Plane needs to communicate with many compute nodes&lt;/li&gt;
&lt;li&gt;Direct SSH or API calls don't scale well&lt;/li&gt;
&lt;li&gt;Need resilient, asynchronous communication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And after implementing Agents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each compute node runs a persistent Agent&lt;/li&gt;
&lt;li&gt;Agent registers with Management Plane on startup&lt;/li&gt;
&lt;li&gt;Receives tasks, executes them, reports status&lt;/li&gt;
&lt;li&gt;Like Kubernetes kubelet or Nomad agent&lt;/li&gt;
&lt;li&gt;Responds to health check requests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I chose Golang for the Agent because it has low overhead and it's very good for this purpose due to its concurrency model.&lt;/p&gt;

&lt;p&gt;A simplified example of how the Agent runs an application container&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;RunDeploymentContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;deploymentId&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;deploymentFilesPath&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;getAPIClient&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Generate a logical container ID for internal tracking&lt;/span&gt;
    &lt;span class="n"&gt;containerId&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;util&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GenerateCryptoID&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;hostConfig&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HostConfig&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Create container with deterministic name&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContainerCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hostConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"deploy-%s-%s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;deploymentId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;containerId&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Start container&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContainerStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartOptions&lt;/span&gt;&lt;span class="p"&gt;{});&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Fault Tolerance &amp;amp; Health Checks
&lt;/h2&gt;

&lt;p&gt;At the moment, I have not implemented a robust method to handle failures in the system. &lt;/p&gt;

&lt;p&gt;Currently, the Management Plane sends gRPC requests to every Deployment Node and the Agent must respond with the system resources available (CPU and RAM). &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Management Plane keeps an internal state of each node and later on, decides to offload deployment tasks based on it.&lt;/li&gt;
&lt;li&gt;In case a Node dies or becomes irresponsive, the failed health check will cause the Management Plane to not send any tasks to that Node.&lt;/li&gt;
&lt;li&gt;Rather, it will keep sending health check request until the Node is responsive again. Once that happens, it will start receiving tasks as usual.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple yet effective approach for now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Here's what I learned
&lt;/h2&gt;

&lt;p&gt;When I first thought of building Stratus, I was somewhat clueless on where to start, because there's so many moving pieces and every one of them is required for the entire thing to function properly.&lt;/p&gt;

&lt;p&gt;I'll have to admit, distributed state management isn't easy. Tracking which nodes have what containers requires careful design. &lt;/p&gt;

&lt;p&gt;There's so many edge cases which need to be taken into consideration when running something of this scale. After all, anything can go wrong (and it will). &lt;br&gt;
This has helped me to understand why Kubernetes is so complex - it handles every edge case I'm discovering.&lt;/p&gt;

&lt;p&gt;Things like container rescheduling, dynamic routing (since the internal network is completely isolated) will require lots of planning and careful considerations. &lt;/p&gt;

&lt;p&gt;And gVisor had made it a complete pain for me to access the containers through Docker's internal network, without tweaking the network isolation levels (or completely disabling it).&lt;/p&gt;

&lt;p&gt;If there's something I'd do differently for this, I'd add observability from day 1. Developing this would have been so much easier if I had logs and metrics from the get go. That was probably one of the mistakes I made with this.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;Part 2 will cover the routing layer - how to expose containerized apps to the internet when they're running on internal networks across multiple nodes. P.S. it involves Consul, OpenResty, and sidecar proxying.&lt;/p&gt;

&lt;p&gt;I'll also be working on implementing Horizontal scaling for this so it can run multiple containers application deployment. Stay tuned.&lt;/p&gt;




&lt;p&gt;If you're interested in the code: &lt;a href="https://github.com/ahnaf-zamil/stratus" rel="noopener noreferrer"&gt;Stratus GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have ideas, suggestions, or questions? Reply here or reach me at &lt;a href="mailto:ahnaf@ahnafzamil.com"&gt;ahnaf@ahnafzamil.com&lt;/a&gt; - I’d love to hear from you!&lt;/p&gt;

&lt;p&gt;Thank you for reading and have an amazing day!&lt;/p&gt;

</description>
      <category>distributedsystems</category>
      <category>architecture</category>
      <category>backend</category>
      <category>cloud</category>
    </item>
    <item>
      <title>OpenResty: The overpowered web server used by 40M websites (that people rarely talk about)</title>
      <dc:creator>K.M Ahnaf Zamil</dc:creator>
      <pubDate>Wed, 13 Jul 2022 07:42:17 +0000</pubDate>
      <link>https://forem.com/ahnafzamil/openresty-the-overpowered-web-server-used-by-40m-websites-that-people-rarely-talk-about-2fjg</link>
      <guid>https://forem.com/ahnafzamil/openresty-the-overpowered-web-server-used-by-40m-websites-that-people-rarely-talk-about-2fjg</guid>
      <description>&lt;p&gt;For the last three years, I have been working with server-side technologies, especially web servers to deploy my proxies and API gateways. I always thought Nginx was the best open-source web server you could get. Event-driven architecture, ability to load balance with upstreams, etc. They even claim to be a proxy server for email protocols such as POP3, and IMAP. But a lot of limitations and lack of modifiability had me looking for other options, and then I discovered the option I’ll never trade for another web server. I’m the type of person who yearns to spread the word about everything awesome.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations of Nginx - What it didn’t allow me to do
&lt;/h2&gt;

&lt;p&gt;Nginx had limitations that nobody usually complained about and that they used to solve in a lower layer of their infrastructure. Let’s say you want to check for authentication before sending the request to your app servers. &lt;strong&gt;With Nginx, there’s no way to run a middleware for this purpose.&lt;/strong&gt; Rather, people tend to have an API gateway that receives all the requests from Nginx, and they run the authentication check there; after that, they pass the request to the app servers. This is slow, complex, and can even cost you more if you are using serverless infrastructure. &lt;/p&gt;

&lt;p&gt;A few weeks ago, I was creating a web application where I needed to balance the traffic to Python Flask servers, which were registered on a Consul service mesh. Before even passing the traffic, I wanted my Nginx server to validate the authentication token so that my Python application wouldn’t have to do it. But that wasn’t possible with Nginx alone.&lt;/p&gt;

&lt;p&gt;Nginx Plus tried to solve it in a way I didn’t like. The biggest thing it DIDN'T solve is the ability to modify the behavior of Nginx. It did offer njs, which is JavaScript you can run on Nginx; however, it doesn’t allow you to turn Nginx into a web application. Again, Nginx Plus is 2500$ per year, which is pretty expensive for small companies or independent developers. Plus, I’m a BIG fan of open-source software. Because of all that, Nginx Plus was a big no-no for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Behold, the almighty OpenResty!!!
&lt;/h2&gt;

&lt;p&gt;First of all, let me get something straight. I am usually never fazed by technology. But OpenResty was probably one of the things that made me go “WHY DIDN’T I KNOW ABOUT THIS EARLIER?!?!?!?!” and there are many good reasons for that. When I first went to their website, I saw&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;OpenResty® is a dynamic web platform based on Nginx and &lt;br&gt;
LuaJIT. It integrates the standard Nginx core, LuaJIT, &lt;br&gt;
many carefully written Lua libraries, lots of high&lt;br&gt;
quality 3rd-party Nginx modules, and most of their external &amp;gt; dependencies. It is designed to help developers easily&lt;br&gt;
build scalable web applications, web services, &lt;br&gt;
and dynamic web gateways.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I thought they were capping (basically, a brand new word for lying). A dynamic web platform that runs on Nginx, and can be modified using Lua? I don’t know about others, but I was convinced after reading this single line. &lt;strong&gt;It’s like you are getting all the features of Nginx, but also the ability to dynamically program it and make it work like your own thing. This means you get the performance of C, but write code with the ease of Lua.&lt;/strong&gt; I was a bit concerned  at first since I thought they were doing the same thing as Nginx Plus, but I was wrong.&lt;/p&gt;

&lt;p&gt;You can use OpenResty for developing scalable web apps, web services, dynamic web gateways, APIs, and so much more! There’s no end to what you can do since you have been given the freedom to program its features.&lt;/p&gt;

&lt;h2&gt;
  
  
  OpenResty as a full-on web application? CAN YOU EVEN DO THAT?
&lt;/h2&gt;

&lt;p&gt;OpenResty gives you the power to execute your application logic inside it. It’s made in such a way that you don’t even need an application server running and proxy requests to that! In terms of performance, you are getting the speed of C while executing application logic. You can also interface with databases such as MySQL, PostgreSQL, Redis, etc., directly in OpenResty and the community has plenty of modules/libraries for it. &lt;/p&gt;

&lt;p&gt;Someone even made their blogging site only with OpenResty and Redis; they did not use any other backend application: &lt;a href="https://github.com/torhve/LuaWeb" rel="noopener noreferrer"&gt;https://github.com/torhve/LuaWeb&lt;/a&gt;. Unfortunately, they implied OpenResty to be a bunch of plugins; however, it’s a fully functional web platform on its own &lt;strong&gt;with its vast library of official and third-party modules.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  OpenResty as a proxy and API-Gateway? Is that a thing?
&lt;/h2&gt;

&lt;p&gt;Most people already have their application written in some other programming language such as Python, JavaScript, Java, etc., so they would want to use OpenResty as an API gateway instead of an application server. Using OpenResty, you can write code in Lua to make it work as an API gateway.&lt;/p&gt;

&lt;p&gt;Some API gateways such as Spring Cloud Gateway, run server-side code (for authentication, or input formatting) and then proxy the requests. But with the JVM, the execution is less performant. Since OpenResty runs your code in Lua (which runs on C), you get blazing fast performance; which might not be visible for a small amount of traffic but will play a big effect when it comes to huge traffic. &lt;/p&gt;

&lt;p&gt;Also, if you are talking about the Kong API Gateway, it’s built on top of OpenResty. &lt;/p&gt;

&lt;p&gt;I used OpenResty for load balancing my Flask applications registered on a Consul service mesh. I sent DNS requests to the Consul server using Lua to fetch the application instances, and then proxied the requests to the application. Without OpenResty, I would have to use another Python application as an API gateway, which would be slower, and more agonizing. With a single Lua file, I turned OpenResty into a dynamic load balancer that uses Consul as its service discovery. Here’s the repository for my project: &lt;a href="https://github.com/ahnaf-zamil/openresty-consul-proxy/" rel="noopener noreferrer"&gt;https://github.com/ahnaf-zamil/openresty-consul-proxy/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8zaprdp3plh2u9xvceta.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8zaprdp3plh2u9xvceta.png" alt="OpenResty Consul Upstream" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  But who uses OpenResty?
&lt;/h2&gt;

&lt;p&gt;I was a bit surprised when I first found out that Cloudflare had been supporting OpenResty since its early days and even uses it for a lot of their products. It is also worth mentioning that OpenResty was first sponsored by the Chinese e-commerce giant Taobao. According to NetCraft’s May 2022 web server survey, 40.7 million websites run on OpenResty. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fir9z6cpcnrqrq91gzdij.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fir9z6cpcnrqrq91gzdij.png" alt="NetCraft's September 2016 Survey" width="800" height="186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;NetCraft states this in its September 2016 survey,&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“&lt;/em&gt;&lt;em&gt;Switching from Nginx to OpenResty is not such a paradigm shift&lt;/em&gt;* as moving to, say, Apache or Microsoft IIS. The OpenResty web application platform is built around the standard Nginx core, which offers some familiarity, as well as allowing the use of third-party Nginx modules. One of the key additional features provided by OpenResty is the integration of the LuaJIT compiler and many Lua libraries – &lt;strong&gt;this gives scope for high performance web applications to be run completely within the bundled Nginx server, where developers can take advantage of non-blocking I/O.&lt;/strong&gt;”*&lt;/p&gt;

&lt;p&gt;Companies such as &lt;strong&gt;Kong&lt;/strong&gt;, &lt;strong&gt;Shopify&lt;/strong&gt;, &lt;strong&gt;GrubHub&lt;/strong&gt;, &lt;strong&gt;Strava&lt;/strong&gt;, &lt;strong&gt;AlgoExpert&lt;/strong&gt;, &lt;strong&gt;Tumblr&lt;/strong&gt;, etc, use OpenResty for powering their backends as well. The Kong API gateway itself is powered by OpenResty under the hood. It’s the 3rd most popular web server on the internet. &lt;/p&gt;

&lt;p&gt;Even a lot of people who claim to be using Nginx are actually using the Lua module which was made by and for OpenResty. The Kubernetes Nginx ingress controller uses OpenResty under the hood through its Lua module: &lt;a href="https://github.com/kubernetes/ingress-Nginx/blob/88e96decd95e7bd10e7de62b102284ff2bc82593/docs/how-it-works.md" rel="noopener noreferrer"&gt;https://github.com/kubernetes/ingress-Nginx/blob/88e96decd95e7bd10e7de62b102284ff2bc82593/docs/how-it-works.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the posts in Shopify’s Engineering blog states this,&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“One of Shopify's secret weapons is our edge tier, which uses a combination of Nginx and OpenResty's Lua module. This module integrates into Nginx's event model allowing us to write Lua scripts which operate on requests and responses.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://shopify.engineering/surviving-flashes-of-high-write-traffic-using-scriptable-load-balancers-part-i" rel="noopener noreferrer"&gt;https://shopify.engineering/surviving-flashes-of-high-write-traffic-using-scriptable-load-balancers-part-i&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  I’m excited, how do I get started?
&lt;/h2&gt;

&lt;p&gt;Firstly, you need to send $100 to a very fishy Bitcoin wallet to get a TOR link for the OpenResty binary on the dark web… just kidding. OpenResty is 100% open-source and FREE!!!!!! I mean, if it weren’t open-source, there wouldn’t be a point in having “Open” at the start of its name. I don’t know… I’m not the one who came up with the name :/&lt;/p&gt;

&lt;p&gt;Anyways, I recommend you check out OpenResty’s website (&lt;a href="https://openresty.org" rel="noopener noreferrer"&gt;https://openresty.org&lt;/a&gt;) first. OpenResty offers binary packages, but you can also compile from source code. I used the latter option (because I have an obsession with compiling stuff from scratch), and it didn’t take me long to do it, about 4-5 minutes.&lt;/p&gt;

&lt;p&gt;Next, you can get started with OpenResty by reading the “Getting Started”(&lt;a href="https://openresty.org/en/getting-started.html" rel="noopener noreferrer"&gt;https://openresty.org/en/getting-started.html&lt;/a&gt;) page on their website. It doesn’t even scratch the surface, but you will get the idea of how simple it is to use. &lt;/p&gt;

&lt;p&gt;If you want to know how you can make your own Lua module in OpenResty (that’s what you should do), then check out this video: &lt;a href="https://www.youtube.com/watch?v=vfYxOMl5LVY" rel="noopener noreferrer"&gt;Write Your Own Lua Modules in OpenResty/Nginx Applications&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here’s the API reference for OpenResty: &lt;a href="https://openresty-reference.readthedocs.io/en/latest/Lua_Nginx_API/" rel="noopener noreferrer"&gt;https://openresty-reference.readthedocs.io/en/latest/Lua_Nginx_API/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  OpenResty is HEAVILY underrated
&lt;/h2&gt;

&lt;p&gt;Compare the popularity of Nginx, Apache, or IIS with OpenResty. While OpenResty offers a lot more features and better performance in many cases, it’s not as popular as the servers that dominate the industry. I’m not sure why this is happening. &lt;/p&gt;

&lt;p&gt;Is it because we tend to keep the most powerful weapons secret to have an advantage over our competitors? Or is it because the OpenResty company/community has been too humble and low-key to show off their amazing features?&lt;/p&gt;

&lt;p&gt;I’m very curious about the psychology behind it, because if OpenResty was not popular, then people wouldn’t use it. Being used by 40.7 million sites and lots of big companies means that it is indeed popular. But I don’t understand why people barely talk about it. Whatever it may be, OpenResty is something I would look out for in the future as well. It has a LOT of potential, and I’ve just barely scratched the surface!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I made this post because I wanted OpenResty to gain more popularity, since it’s really an amazing piece of technology that is barely spoken of. It brings in a lot of things required in the current era of the web, where scalability and extensibility are key to having good and performant applications. I hope this post made you consider looking into OpenResty. Once you really get to understand the true power and beauty of this technology, I doubt you will move away from it. With that said, thank you for reading this long post and have a great day!&lt;/p&gt;

</description>
      <category>openresty</category>
      <category>nginx</category>
      <category>webdev</category>
      <category>webserver</category>
    </item>
    <item>
      <title>Service Registry: When should you use them and why?</title>
      <dc:creator>K.M Ahnaf Zamil</dc:creator>
      <pubDate>Tue, 15 Feb 2022 07:13:58 +0000</pubDate>
      <link>https://forem.com/ahnafzamil/service-registry-when-should-you-use-them-and-why-3o92</link>
      <guid>https://forem.com/ahnafzamil/service-registry-when-should-you-use-them-and-why-3o92</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Recently I've been digging deep into microservices and distributed systems in order to get a better understanding of how bigger companies make applications and products that can scale almost infinitely. I've taken Netflix as a great example of microservice implementation in a product used by millions of people. They use microservices for literally EVERYTHING, and it's fully cloud-based (AWS).&lt;/p&gt;

&lt;p&gt;But I see a lot of people (including me once) wondering how they keep track of their service instances when they autoscale. It's not like you have a set amount of service instances and you know their credentials (host and port). When you are autoscaling, you might have &lt;code&gt;n&lt;/code&gt; amount of instances for a single service and not know their credentials.&lt;/p&gt;

&lt;p&gt;For example, let's say you have 2 services: Service A and Service B. Service A depends on Service B for some kind of functionality. If you have one instance of Service B, you can just hardcode that instance's (Service B) credentials in Service A's configuration and use it. But what will you do when you have multiple instances of Service B and cant keep track of them?&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you solve it?
&lt;/h2&gt;

&lt;p&gt;That's where a Service Registry (also known as Service Discovery) comes into play. A Service Registry is basically a server itself, but it keeps track of all the other running service instances along with their credentials (host and port). The idea here is that whenever a new service instance starts, it will "register" itself on the registry by connecting to it and sending it's credentials as payload. Then it will just keep heartbeating (sending periodic packets) to let the registry know that it's "alive". If a service instance does not send a heartbeat for a long time, it will be considered as "dead" and removed from the registry.&lt;/p&gt;

&lt;p&gt;Just in case you are confused, let me specify the abstractions here. The registry will have multiple "services". Here, a service can be some kind of application or server that is required in your application's architecture. Each "service" can have multiple "instances" because you might have to scale.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuma682c6shwztkfajvgz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuma682c6shwztkfajvgz.png" alt="Service Registry Example" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  We got a registry, how do we access the instances?
&lt;/h2&gt;

&lt;p&gt;We now know how we can register services, but how do we get an instance's credentials so that we can actually use it? One might say that we can just randomly select an instance from the registry. But that is not optimal since it's not 100% "random" and might return the same instance's credentials multiple times. The best option here would be to use some sort of load balancing algorithm. Most service registry systems come with a "round-robin" load balancing implementation which works best if you have servers with same specs/configuration. And when you are autoscaling, that would usually be the case. I can write a whole article on load balancing algorithms so I won't babble about it here.&lt;/p&gt;

&lt;p&gt;Anyways, a load balancing algorithm will simply give you an instance's credentials by load-balancing all of the "alive" instances registered under that specific "service". Once you get the credentials of an instance, you can just use it in your application. BOOM!&lt;/p&gt;

&lt;h2&gt;
  
  
  I'm sold, but which service registry software should I use?
&lt;/h2&gt;

&lt;p&gt;There are MANY good service registry software available, including one that I made (which is fairly new, but you can give it a try). I will list a few good ones here that I recommend for starters and production.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.baeldung.com/spring-cloud-netflix-eureka" rel="noopener noreferrer"&gt;Spring Cloud Netflix Eureka&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.consul.io/" rel="noopener noreferrer"&gt;Hashicorp Consul&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://curator.apache.org/curator-x-discovery/index.html" rel="noopener noreferrer"&gt;Apache Curator Discovery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ahnaf-zamil/invenio" rel="noopener noreferrer"&gt;Invenio (the one I made)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Well that is it for this post, I hope you enjoyed learning about Service Registries. It's been a while since I've written an article, so it might not be the best thing I've written. Regardless, I hope this new knowledge about Service Registries help you in the long run and make your backend easier to scale.&lt;/p&gt;

&lt;p&gt;Happy Coding :D&lt;/p&gt;

</description>
      <category>devops</category>
      <category>distributedsystems</category>
      <category>backend</category>
      <category>microservices</category>
    </item>
    <item>
      <title>My favorite stack for web applications, and why I use it</title>
      <dc:creator>K.M Ahnaf Zamil</dc:creator>
      <pubDate>Wed, 18 Aug 2021 07:04:20 +0000</pubDate>
      <link>https://forem.com/ahnafzamil/my-favorite-stack-for-web-applications-and-why-i-use-it-128p</link>
      <guid>https://forem.com/ahnafzamil/my-favorite-stack-for-web-applications-and-why-i-use-it-128p</guid>
      <description>&lt;p&gt;If you are a full stack developer, or just a web developer in general; you might have heard the term "Tech Stack" or just "Stack" in general. Basically, it is a set of technologies that you use to make your web applications. Pretty simple right? &lt;/p&gt;

&lt;p&gt;There are many popular stacks which are used from small startups to big companies. These stacks include but not limited to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MERN: MongoDB, Express, React, Node&lt;/li&gt;
&lt;li&gt;MEAN: MongoDB, Express, Angular.js, Node&lt;/li&gt;
&lt;li&gt;LAMP: Linux, Apache, MySQL, PHP
etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When &lt;strong&gt;I&lt;/strong&gt; make a web application, I want a tech stack that is lightweight, and easy to use/manage. &lt;/p&gt;

&lt;p&gt;I call it the PERP stack (weird name)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;P: Python&lt;/li&gt;
&lt;li&gt;E: (E)nginx&lt;/li&gt;
&lt;li&gt;R: React&lt;/li&gt;
&lt;li&gt;P: PostgreSQL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since I use Python and TypeScript as my primary languages, I use these for making my applications. On the backend, I use Python Flask (specifically) as my web framework. I use &lt;a href="https://ariadnegraphql.org/" rel="noopener noreferrer"&gt;Ariadne&lt;/a&gt; with Flask as I like to use GraphQL instead of REST, whenever possible.&lt;/p&gt;

&lt;p&gt;Flask is an unopinionated and lightweight web framework. It comes with the bare essentials, and there are tons of extensions which you can integrate to make your application, which is why I use it instead of a complete web framework like Django.&lt;/p&gt;

&lt;p&gt;For the frontend, React is a must for me. I don't like any other frontend frameworks/libraries except React (just my own opinion). With React, I use URQL or Apollo client as the GraphQL client. Also, I forgot to mention that this will all be in TypeScript (because types are OP). UI-wise, I use &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt;, and &lt;a href="https://headlessui.dev/" rel="noopener noreferrer"&gt;Headless UI&lt;/a&gt; (Tailwind components for React, Vue, etc).&lt;/p&gt;

&lt;p&gt;As my database, I leverage SQL over any other type of "main" database, specifically PostgreSQL. Of course, I would use something like Redis for user session and caching. The reason I use SQL is because it provides you with structured tables, so that the data always follows the same format and pattern. Relational functionality is also another pro to it. Foreign keys, joins, etc, are very useful SQL functionalities.&lt;/p&gt;

&lt;p&gt;This is basically the set of technologies that I like to use for making my web application. Of course, there might be other better alternatives, but I just use it because I am more comfortable with using these. And it's not that bad. Let me know what tech stack you use for your web application, in the comments below. Hope you enjoyed this post :)&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>website</category>
      <category>webstack</category>
    </item>
    <item>
      <title>[Joke] Bad things about every programming language</title>
      <dc:creator>K.M Ahnaf Zamil</dc:creator>
      <pubDate>Wed, 18 Aug 2021 06:24:28 +0000</pubDate>
      <link>https://forem.com/ahnafzamil/joke-bad-things-about-every-programming-language-3246</link>
      <guid>https://forem.com/ahnafzamil/joke-bad-things-about-every-programming-language-3246</guid>
      <description>&lt;p&gt;This is just a sarcastic post where I rant about the bad sides of every programming language I have tried/used. Please don't be offended, as this just for entertainment purposes.&lt;/p&gt;

&lt;p&gt;Let's get started:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Python&lt;/strong&gt;: Slow as hell, no generics or types. I am not Harry Potter, Parseltongue is not for me. Spaces and tabs don't work together well. SNEK!!!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;: My life is &lt;code&gt;undefined&lt;/code&gt;, every single tutorial on the internet is on JS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TypeScript&lt;/strong&gt;: Error: Property &lt;code&gt;sanity&lt;/code&gt; of type &lt;code&gt;Mind&lt;/code&gt; is undefined.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Java&lt;/strong&gt;: I wish I had a widescreen monitor. JVM taking too much of my RAM. And the error tracebacks are bigger than my p- (rogramming skills)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C++/C&lt;/strong&gt;: I wish pointers didn't exist, and type conversion was easier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rust&lt;/strong&gt;: Lifetimes don't make sense. Car-go, car not fly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Golang&lt;/strong&gt;: No generics, error handling is disgusting. Why use zero values if nil exists? (nevermind, they got generics now.....)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;: Microsoft™ Java. Also, pointers are useless here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTML&lt;/strong&gt;: A very good &lt;strong&gt;programming&lt;/strong&gt; language.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CSS&lt;/strong&gt;: The only thing I can flex about in my life is a flexbox that I made when I was 12 years old.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed this post. Again, please don't take this offensively. A lot of the programming languages on this post are the ones I use, and they are pretty good. I just made the bad things sound funny :)&lt;/p&gt;

</description>
      <category>programming</category>
      <category>coding</category>
    </item>
    <item>
      <title>Web Application Scaling: For Dummies (like me)</title>
      <dc:creator>K.M Ahnaf Zamil</dc:creator>
      <pubDate>Wed, 18 Aug 2021 05:48:47 +0000</pubDate>
      <link>https://forem.com/ahnafzamil/web-application-scaling-for-dummies-like-me-1ilh</link>
      <guid>https://forem.com/ahnafzamil/web-application-scaling-for-dummies-like-me-1ilh</guid>
      <description>&lt;p&gt;Let's say you have created a blog website where you share your ideas and knowledge on coding. At the start, your website was small, and the traffic was low. A few weeks went by, and you see there is a lot of users now. They are requesting that you add forum system to the website (much like StackOverflow). You add that, and now everyone's happy. Seeing new features, there are more users now. Next week, a user contacts you via your email saying that they can't access your site. &lt;/p&gt;

&lt;p&gt;Because the web server crashed....&lt;/p&gt;

&lt;p&gt;When you log onto your VPS/server where your application is hosted, you see that the resource usages are peaking at 100%. Your single server/application instance cannot handle this insane amount of traffic coming to your website. So how do you ensure that your website is always up, and available?&lt;/p&gt;

&lt;p&gt;By scaling!!&lt;/p&gt;

&lt;h2&gt;
  
  
  Tell me, what in the bananas is scaling?!?!?!?
&lt;/h2&gt;

&lt;p&gt;Tldr, scaling is the process of making your application cope up with a huge amount of users. If one instance of your application cannot handle this much traffic, you spin up another server (cloud service providers like &lt;a href="//cloud.google.com"&gt;GCP&lt;/a&gt;, &lt;a href="//aws.amazon.com"&gt;AWS&lt;/a&gt;, &lt;a href="//digitalocean.com"&gt;DigitalOcean&lt;/a&gt;, &lt;a href="//azure.microsoft.com"&gt;Azure&lt;/a&gt;, etc, make it easy and cheap) and host your application there.&lt;/p&gt;

&lt;p&gt;That way, if one of your application server crashes, the other one can handle the traffic. Or, the huge traffic can be distributed to both of the servers, depending on which one is the least busy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But here's a catch!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Since your application is hosted on two different servers (for the sake of scaling), each of the servers have a different IP address. But you have a single domain, so how will the user know which server to connect to?&lt;/p&gt;

&lt;p&gt;We need to call upon the mighty Load Balancer!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Load Balancer?!?!?!?
&lt;/h2&gt;

&lt;p&gt;Well, since you have multiple servers for the web application, we need a server in the middle which will receive all the client requests, and distribute them to the application servers. So instead of assigning the domain to the web application servers, you assign the domain to the Load Balancer server, and all the users/clients will send the request to the Load Balancer. The Load Balancer will simply receive all the traffic, and send them to one of your application servers depending on which one is the least busy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi0.wp.com%2Fgbhackers.com%2Fwp-content%2Fuploads%2F2018%2F12%2FLoad-Balancer.jpg%3Ffit%3D759%252C387%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi0.wp.com%2Fgbhackers.com%2Fwp-content%2Fuploads%2F2018%2F12%2FLoad-Balancer.jpg%3Ffit%3D759%252C387%26ssl%3D1" alt="How Load Balancing works" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most cloud service providers have their own Load Balancers which work very well. But if you are like me, and want to set up a Load Balancer form scratch, then you can use &lt;a href="//nginx.com"&gt;Nginx&lt;/a&gt; as your Load Balancer. Now don't get me started on Nginx, I can write a whole post about how great and useful Nginx is. Simply, it's not just a web server, you can use it as a reverse proxy, Load Balancer, TCP proxy, etc.&lt;/p&gt;

&lt;p&gt;So now we have a simple but efficient Load Balancer which will distribute all of our traffic to the application servers. End of problem, right? Well, I wish I could tell you that. But there are still some things that need to be fixed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First, the database.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you scale a freaking database?!?!?!?!?
&lt;/h2&gt;

&lt;p&gt;Right now, a database instance is being hosted on each of your application servers. That would have been fine if you only had a single instance of the application, and the database is hosted on the same server as the application. But since we have multiple instances of the application now, it will be a problem. As the Load Balancer is sending the traffic to different servers at a time, each application server that receives the request will write to the database that is hosted on it's own server. So the data will be different for each server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So how do we solve this?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well, the best way to do it would be to have a centralized database. Now if your application is &lt;strong&gt;VERY&lt;/strong&gt; big and works at a high scale, you might need to partition your database, or use some other database scaling pattern. But for now, just having a good old centralized database would work just fine. You need to spin up another VPS/server, and host your database software there. Or, you can use a managed database service like DynamoDB (AWS), RDS (AWS), SQL Database (Azure), etc, which you don't need to worry about scaling as the cloud provider will scale it for you. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9v8j9zpb0t4s6ev01rtk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9v8j9zpb0t4s6ev01rtk.png" alt="Centralized Database" width="416" height="299"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, just make the application servers connect to that database. This way, the application state/data would be the same across every single instance since they are all using the same database server. &lt;/p&gt;

&lt;p&gt;So we have a centralized database now, and all users are happily using your application. But suddenly, your blog started to pop off. People liked the content you were making, and they are so many users visiting your page that your database started to crash, and your &lt;code&gt;reads per second&lt;/code&gt; rates are &lt;strong&gt;VERY&lt;/strong&gt; high.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do we solve this??&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let us implement a caching mechanism!&lt;/p&gt;

&lt;h2&gt;
  
  
  Bro, what is caching now?!?!?
&lt;/h2&gt;

&lt;p&gt;Caching is a very simple concept, yet it is very useful. Whenever someone visits your website/blog, it is making a request to the database for the post. So if many users visit your blog, the number of database &lt;code&gt;read&lt;/code&gt; requests is high. So instead of making a database request for every time someone visits a page, we can use a caching mechanism (or caching layer) that will simply cache your posts in memory, for some time. That way, instead of making a request to the database every time someone visits your blog, the request can be made to the cache, and that cache will return the data that is stored in the memory. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqpavicpqx3yqb5d5qge7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqpavicpqx3yqb5d5qge7.jpg" alt="How caching works" width="770" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The caching layer (or simply, the "cache") can update itself every few minutes so that the data is not stale. Since it is a blog website, you won't be writing posts every 5 minutes, jeez. So the cache can just fetch the updated data from the database every 15 or so minutes, and store it in memory. That way, whenever a user visits your blog, it will fetch the data from the cache instead of the database; reducing the number of database &lt;code&gt;read&lt;/code&gt; requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;So now we know how we can scale a basic web application. This are just very simple scaling patterns, and bigger applications might need more advanced procedures to ensure maximum performance and uptime. Also, this is my first ever tech blog post, so please ignore any grammatical/spelling mistakes. That's all for this post, hope you found it helpful :)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;The best type of application is the application that scales well&lt;/em&gt;&lt;/strong&gt; - Dev Tzu, Art of Code&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>deployment</category>
      <category>devops</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
