<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Blog - Tonmoy Deb]]></title><description><![CDATA[Welcome to my Thoughts Book – a space where ideas, insights, and creativity come alive. Explore posts on coding, engineering, web development, and more. Dive into a journey of learning and innovation!]]></description><link>https://blog.tonmoydeb.com</link><generator>RSS for Node</generator><lastBuildDate>Thu, 16 Apr 2026 11:52:55 GMT</lastBuildDate><atom:link href="https://blog.tonmoydeb.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How We Scaled Our Email System From 10K to 700K Emails Without Crashing the Backend]]></title><description><![CDATA[Hey folks, so last week me & my team scaled an application from 10K emails to 700K emails. Sounds cool, right? Today I’m going to share the story & learning from this experience.
The Story
So one of my company's clients had built an email marketing p...]]></description><link>https://blog.tonmoydeb.com/how-we-scaled-our-email-system-from-10k-to-700k-emails-without-crashing-the-backend</link><guid isPermaLink="true">https://blog.tonmoydeb.com/how-we-scaled-our-email-system-from-10k-to-700k-emails-without-crashing-the-backend</guid><category><![CDATA[scaling]]></category><category><![CDATA[email marketing]]></category><dc:creator><![CDATA[Tonmoy Deb]]></dc:creator><pubDate>Sun, 20 Jul 2025 19:29:34 GMT</pubDate><content:encoded><![CDATA[<p>Hey folks, so last week me &amp; my team scaled an application from 10K emails to 700K emails. Sounds cool, right? Today I’m going to share the story &amp; learning from this experience.</p>
<h2 id="heading-the-story">The Story</h2>
<p>So one of my company's clients had built an email marketing platform recently. Initially, he wants to send an email to max 10K customers. So we just built &amp; optimized that application for 10k customers. Everything is working fine until last week, suddenly last week client asked us that “Is it possible to send 700k mails?” Our minds have just blown out. Because this is a huge number, and we can’t just do this in a single click. So we started researching &amp; testing it. We found that currently the whole operation is operating from the main backend server &amp; there is no way we can continue this for the next huge number of emails, so we choose to use Amazon services. At the end, we prepared a high-level implementation diagram and scheduled this feature for next week.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753032608059/de786c16-fd0a-4ac6-9359-f74d55cb7886.png" alt class="image--center mx-auto" /></p>
<p>There is one issue remaining that currently if we do this huge operation in the backend, then the backend server will crash as expected. Although this is not an issue but we take this challenge to scale our backend to at least handle this huge load because eventually we need to do this same thing once we move stuff into AWS. And surprisingly, we did this in 1 working day. We scaled our backend to handle 700k email sending operations.</p>
<h2 id="heading-how-did-we-scale">How did we scale?</h2>
<p>So now starts the main thing. How did we do this? Here are the things we do to achieve this.</p>
<h3 id="heading-1-batching-is-important">1. Batching is important</h3>
<p>First, we started from the basics. We all know that while handling a huge load, batching is important. Doing work by batching stuff helps us reduce the memory overload. But there is a flaw in batching stuff. batch operation takes more time than normal operation, and if the size of the data is that huge, then it’s really hard to rely on batching only. So to reduce the initial operation time, we did batching twice.</p>
<p><strong>1.1 Grouping Operations</strong></p>
<p>Since we need to reduce memory load so we group our operations by indexes. So, from 0-1000 index it will be a group, from 1001-2000 will be a separate group, and that’s how it goes on. Now, each group will perform operations independently.</p>
<p><strong>1.2 Batch Operations</strong></p>
<p>Besides memory load, we need to reduce the process time also. So we put our 2nd batch operations in the background queue jobs. In this step, we do our actual operations. We validate data, prepare payload for emails &amp; lots of stuff. But since it’s done from the background, it doesn’t affect our initial process time.</p>
<h3 id="heading-2-queue-matters">2. Queue matters</h3>
<p>I already talked about the queue first, but actually, queue jobs matter. When an operation is huge, time-consuming &amp; you really don’t need that result instantly, then a queue makes much more sense than doing that job on the go.</p>
<p>As an example, before using the queue in the 2nd batch operation, it was good when it is handling a small dataset, but when the dataset grew to 700k, we never saw a success response from the API. We only saw a timeout error.</p>
<p>Also, we have used a queue for sending emails (we didn’t create it newly it’s already there). Since the 2nd batch operations are only responsible for preparing data for emails so we implemented a separate email queue which is only responsible for sending emails. Also, this is very helpful to rate limit operations per second because when we use third-party services, we need to take care of API calling limits as well.</p>
<h3 id="heading-3-caching-helps">3. Caching helps</h3>
<p>While sending the same mail to all users, the most common thing is an email template. There is also a lot of other common stuff, but since we sliced our full email sending operations into slices so there is a problem of accessing the common data. The easiest way is to pass data from one slice to another, but this may create huge memory usage. So what we did is cache the common data into Redis and access it whenever we needed. It may sound very simple, but it really helped us a lot because after implementing Batching &amp; Queue, we solved half of the problem, but the issue comes of huge memory usage. And it was solved quickly after we implemented the caching. Also, since this is cached in Redis so we don’t lose anything on performance.</p>
<h3 id="heading-4-keep-only-stuff-that-is-needed">4. Keep only stuff that is needed</h3>
<p>After all of this is done, we are about to be stable, but found that our Redis memory is going through a very bad time. Whenever the mailing service starts, the Redis memory usage goes up to 7GB, which is really bad. So we started removing unnecessary data. After removing all the unnecessary data, we managed to run the same mailing service under 200MB of Redis usage. which is a great achievement.</p>
<h2 id="heading-what-is-the-impact-of-this-scaling">What is the impact of this scaling?</h2>
<p>Our main goal was to stop the server from crashing, that’s it. And we achieved that. But it’s not worth it right now because if you’re using any third-party services, then your scaling also depends on the third-party services. In our case, it’s Amazon SES (Simple Email Service). Because the limitation of SES is 14 mail per second. So even if we scale 100x but we still need to cap it to 14 mail per second. But we can increase the limit, of course, and next week we are going to do this.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>During this process, I got stuck a lot &amp; then I researched a lot. But eventually I learned a lot also. Also, I realized you don’t need to scale your applications into millions on the first day. You start small, then when you need, you scale. This makes the business more profitable &amp; reduces pressure from developers.</p>
<p>Regarding the app with the current setup, we can go on with just increasing the limit from SES, but it will be good to move this into a separate thing.</p>
<p>This is it for today. I hope you find this article helpful. Do not forget to share your thoughts in the comments.</p>
]]></content:encoded></item><item><title><![CDATA[Design Sense for Developers]]></title><description><![CDATA[Introduction
For most developers, design is a nightmare. In my experience, developers are terrible at design. Not all of them, but many of them. And that’s okay because traditionally, it hasn't been a developer’s job. In today’s article, I will take ...]]></description><link>https://blog.tonmoydeb.com/design-sense-for-developers</link><guid isPermaLink="true">https://blog.tonmoydeb.com/design-sense-for-developers</guid><category><![CDATA[developer-journey]]></category><dc:creator><![CDATA[Tonmoy Deb]]></dc:creator><pubDate>Sun, 06 Apr 2025 16:13:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1743955692984/0a8aea37-8dd9-41aa-8ff6-b1944ef7e919.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction"><strong>Introduction</strong></h2>
<p>For most developers, design is a nightmare. In my experience, developers are terrible at design. Not all of them, but many of them. And that’s okay because traditionally, it hasn't been a developer’s job. In today’s article, I will take a look at this subject.</p>
<h2 id="heading-what-is-design-sense"><strong>What is design sense?</strong></h2>
<p>In other words, <strong>"Design sense means knowing what looks good and works well, almost like a natural feeling."</strong> So it doesn’t mean that you need to know everything about designing and such. You just need to know what looks good and where. Also, it’s not a curriculum thing; you need to train your mind to adopt this by exploring other good designs.</p>
<h2 id="heading-do-you-need-it"><strong>Do you need it?</strong></h2>
<p>This question depends on various factors, such as:</p>
<h3 id="heading-preference">Preference</h3>
<p>First of all, it’s purely based on your preference. If you don’t like it, you can just skip. If you love to design stuff or are excited about learning new stuff, then you can at least give it a try.</p>
<h3 id="heading-job-role"><strong>Job Role</strong></h3>
<p>If you want to be a front-end developer, then mark my words—you will need this for sure. Nowadays, companies expect that you will have at least a good design sense.</p>
<h3 id="heading-job-place"><strong>Job Place</strong></h3>
<p>If you plan to join a big established company, then if you don’t want to, you can skip this. You can just focus on your work.</p>
<p>If you plan to join a startup, then you will need it for sure. Because, as startup culture goes, most startups want developers to be a one-man army. And on top of that, if you also have good design sense, then it’s just a lucky jackpot for them.</p>
<p>If you want to work as a freelancer, then most of the time, you may not need it, but if you do, it can help you impress your clients.</p>
<h2 id="heading-where-to-start"><strong>Where to start?</strong></h2>
<p>Everything has its fundamentals. So, here are the top 5 fundamental topics I would suggest you study.</p>
<h3 id="heading-1-typography">1. <strong>Typography</strong></h3>
<p>Typography is an essential thing in design. There are different types of fonts, and each of them has a purpose. Also, there are some standards for font size, spacing, and line height.</p>
<h3 id="heading-2-colors">2. <strong>Colors</strong></h3>
<p>There are some standards for colors as well. It plays a great role in user accessibility. You need to know at least about:</p>
<ul>
<li><p>Different shades of color.</p>
</li>
<li><p>What are the most common colors for designing user interfaces?</p>
</li>
<li><p>What should we consider while building a color palette for any product?</p>
</li>
<li><p>What do different colors mean?</p>
</li>
</ul>
<h3 id="heading-3-spacing">3. <strong>Spacing</strong></h3>
<p>White space is a very important thing that we don’t notice often. People don’t like things that look cluttered or messy. To prevent that, the design should have enough white space.</p>
<h3 id="heading-4-alignment">4. <strong>Alignment</strong></h3>
<p>There should be a proper alignment that guides user flow. You shouldn’t just place elements randomly. This creates a negative impact on user flow.</p>
<h3 id="heading-5-consistency">5. <strong>Consistency</strong></h3>
<p>Everything should be consistent across the whole design. Even if changes are needed, the transition should be smooth.</p>
<p>You don’t need to master these concepts right away, but understanding them will help you make better decisions in the future. Along with these, start exploring designs on Behance, Dribble, or Figma Community. This is the main thing. You need to train your eyes to recognize good design. You also need to keep up with design trends, which will help you stay relevant to industry changes.</p>
<p>After completing the basics, you can start making some designs on your own. To make it easier, just open Behance, choose a design, and start copying it in Figma. This will help you gain hands-on knowledge and build your Figma skills as well. And that’s it! In your free time, just copy some designs, and after a few days, you will notice the improvements.</p>
<h2 id="heading-how-i-improved-my-design-sense-as-a-developer">How I Improved My Design Sense as a Developer</h2>
<p>As a self-taught developer, I didn’t have formal guidance on design. I’ve never been great at it, but I started noticing that many senior developers were saying that having a good design sense increases the chances of getting hired. So, I decided to learn the fundamentals and explore Figma. I copied several websites, and over time, my design skills started improving. I’m not claiming to be great at design yet, but I now know what kind of design suits each section of a website. I can take elements from multiple designs and combine them into a cohesive one. As a result, my clients have come to appreciate my design sense.</p>
<p>For reference, you can visit my <a target="_blank" href="https://www.behance.net/tonmoydeb">Behance profile</a>. I uploaded some of my works at that time. While learning these things, I got this <a target="_blank" href="https://youtube.com/playlist?list=PLlHtucAD9KT3wgeeVqILeW-0rYoQgR1Rh&amp;si=7YaRoQcmUrojXdZg">YouTube playlist</a> from Ansh Mehra, which helped me a lot to clear the basics.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>If you’ve reached this point in the article, then I must say that you’re interested in learning about design sense. I’ve been working in this industry for the last 2 years, and based on that, I know that having a design sense will help you in a lot of places. It will also help you make a good impression at your company. There’s a line called <strong>"Appearance comes before qualities."</strong> This may sound harsh, but it’s the reality. So, having a good design sense is a plus point.</p>
<p>Now, if you’re not the type of person who likes design and such, don’t worry at all. Just focus on what you love and be good at that—that’s what matters most. As I said, having a good design sense is just a bonus, nothing else. With that, I’ll wrap up today’s blog. I’ll see you in the next article.</p>
]]></content:encoded></item><item><title><![CDATA[Managing Multiple Git & GitHub Account]]></title><description><![CDATA[Introduction
As a developer, for work purposes, we always need to work with multiple github accounts at once. If you have multiple systems then there is no problem with it but If you want to manage multiple github in one system then today's article i...]]></description><link>https://blog.tonmoydeb.com/managing-multiple-git-and-github-account</link><guid isPermaLink="true">https://blog.tonmoydeb.com/managing-multiple-git-and-github-account</guid><dc:creator><![CDATA[Tonmoy Deb]]></dc:creator><pubDate>Wed, 05 Mar 2025 17:34:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1741195941672/2007b299-8b3b-437f-b69b-78b2f00c5c79.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>As a developer, for work purposes, we always need to work with multiple github accounts at once. If you have multiple systems then there is no problem with it but If you want to manage multiple github in one system then today's article is for you.</p>
<h2 id="heading-what-is-the-problem">What is the problem?</h2>
<p>The first problem comes when you need to access different repositories from different github accounts. Whenever you need to clone a repository or push any changes, you need to authenticate each account on your terminal, again and again.</p>
<p>The second problem is you need to commit codes with different accounts also. So the same thing again, you need to switch between different accounts again &amp; again.</p>
<p>Now as you can see switching stuff again &amp; again is a hassle.</p>
<h2 id="heading-what-is-the-solution">What is the solution?</h2>
<p>To solve the first problem we need to use SSH key-based authentication other than the regular traditional <strong>Personal access tokens</strong> way. While cloning a private repository we need to use the <strong>SSH</strong> method instead of the <strong>HTTPS URL</strong> method.</p>
<p>To solve the second problem we need to use folder-based git config. Where a git config will apply to a specific folder only.</p>
<h2 id="heading-multiple-github-account-using-ssh">Multiple Github account using SSH</h2>
<p>Before getting started with some commands you need to make sure <code>ssh-keygen</code> is installed in your system. In most of the Linux operating systems, it’s already installed by default, and for Windows, you need to enable <strong>Open SSH Client</strong> from optional features.</p>
<p>If everything is set correctly then let’s get started</p>
<p>For example, I’ve two emails <code>user1@email.com</code> and <code>user2@email.com</code>. Both accounts have separate github accounts also. Now I would like to authenticate both accounts on my machine.</p>
<h3 id="heading-step-1-generate-ssh-key"><strong>Step 1: Generate SSH Key</strong></h3>
<p>Execute this command in your terminal to generate an SSH key for <a target="_blank" href="mailto:user1@email.com"><code>user1@email.com</code></a> but make sure you have a <code>.ssh</code> folder in your home directory. If not then create one.</p>
<pre><code class="lang-bash">ssh-keygen -t rsa -C <span class="hljs-string">"user1@email.com"</span> -f ~/.ssh/user1
</code></pre>
<p><strong>Explanation</strong></p>
<ul>
<li><p><code>ssh-keygen</code> is The command to generate an SSH key.</p>
</li>
<li><p><code>t rsa</code> Specifies the key type as <strong>RSA</strong> (Rivest-Shamir-Adleman), a widely used public-key cryptosystem.</p>
</li>
<li><p><code>C "user1@email.com"</code> Adds a <strong>comment</strong> (usually an email) to help identify the key.</p>
</li>
<li><p><code>f ~/.ssh/user1</code> Specifies the <strong>file name and location</strong> for storing the key:</p>
<ul>
<li><p><code>~/.ssh/</code> is the default SSH directory inside the user's home folder.</p>
</li>
<li><p><code>user1</code> is the <strong>custom filename</strong> for the private key (instead of the default <code>id_rsa</code>).</p>
</li>
</ul>
</li>
</ul>
<p><strong>What happens after running this command?</strong></p>
<ol>
<li><p>You might be prompted to set a <strong>passphrase</strong> and to <strong>confirm the passphrase</strong> for added security. You can just press enter and skip them.</p>
</li>
<li><p>If everything goes correctly then it will generate <strong>two</strong> files:</p>
<ul>
<li><p><code>~/.ssh/user1</code> → The <strong>private key</strong> (keep this secret).</p>
</li>
<li><p><code>~/.ssh/user1.pub</code> → The <strong>public key</strong> (sharable with github).</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-step-2-registering-ssh-key"><strong>Step 2: Registering SSH Key</strong></h3>
<p>In this step, we will register our generated SSH public key to github. To do that first we need to get the public key.</p>
<pre><code class="lang-bash">cat ~/.ssh/user1.pub
</code></pre>
<p><strong>Explanation:</strong></p>
<ul>
<li><p><code>cat</code> Reads and displays the contents of a file.</p>
</li>
<li><p><code>~/.ssh/user1.pub</code> This is the <strong>public key</strong> file generated earlier with <code>ssh-keygen</code>.</p>
</li>
</ul>
<p><strong>What happens after running this command?</strong></p>
<p>After executing this command you will get something like this in the terminal.</p>
<pre><code class="lang-bash">ssh-rsa AAAAB3NzaC1yc2EDDDDDAQABAAABgQDRaOTJKD8oa7ZKdCYoiE9fXjR9XFWL8mejeBLRt7KKLhVBshl5IZPu4cwkzpe+ALbjDP2QLOKeNP13jfTqH+mDqTXQUOswtOOgdyQiTWn6w4dyW4C0W4HN5gwkSsqqWpF9jBp9fkkL15gB9yas8VHFI9uyhAHgSYzi4RwOtSYN/duK5ZtiT4qSSivxLfMbRt8LHBHKs+IdkmT5EdtDDEVsSWR4RutjOvAdQbdakMQT+z/5C/JijS9p8XdqWi2J55owDHP2DLHWpYxL5CqZW/ulf/LFMeQmF35L7HqNBODY/x5zWCiIAtzngltppL5yoecxAWTER8nzU0OnwdNTj+QCLemKcPgpAif/kZd0MO9/1lYdOt6AS/hXb8f7IRRqLzS9js2TFvUXGIYGQtrbYKq0jIWowauQryt6caPkvRLZBUWVIfpgU4Xii1Hmh7crwospOvKUJZjXtXaygHa+U/abV+yUWitBk7+cA6BSHgdkuZCE0YBZ4eYOeYPpdluCKrk= user1@email.com
</code></pre>
<p>Copy that key and go to this <a target="_blank" href="https://github.com/settings/keys">**SSH &amp; GPG keys</a>** github **<strong>page using</strong> <code>user1@email.com</code> and click on the <a target="_blank" href="https://github.com/settings/ssh/new">**New SSH Key</a> button. Now give this key a title (maybe your device name), the key type will be <strong>Authentication Key,</strong> and paste the earlier copied public key content into the key field. After that click on <strong>Add SHH Key</strong> button and save the key.</p>
<h3 id="heading-step-3-ssh-config"><strong>Step 3: SSH Config</strong></h3>
<p>We have successfully authenticated our device with Github. Now, the last thing we need is a config file where we will write all the rules to ensure that the correct SSH key is used for authentication. So create a file called <code>config</code> in the <code>~/.ssh</code> folder and put these lines in the file.</p>
<pre><code class="lang-bash">Host    github.com-user1
    HostName github.com
    User git
    IdentityFile ~/.ssh/user1
</code></pre>
<p><strong>Explanation:</strong></p>
<ul>
<li><p><code>Host github.com-user1</code> This defines a shortcut (<code>github.com-user1</code>) for connecting to GitHub using <code>user1</code>'s SSH key.</p>
</li>
<li><p><code>HostName github.com</code> Specifies the actual hostname, which is <code>github.com</code>.</p>
</li>
<li><p><code>User git</code> The user for SSH authentication is <code>git</code>. This is required when using SSH for GitHub.</p>
</li>
<li><p><code>IdentityFile ~/.ssh/user1</code> Specifies the SSH key to use (<code>~/.ssh/user1</code>) when connecting with this alias.</p>
</li>
</ul>
<p><strong>What does it do?</strong></p>
<p>So basically when we clone a repository or push some changes to a repository using SSH URL, It looks like this.</p>
<pre><code class="lang-bash">git@github.com:user1/latebro.git
</code></pre>
<p>Here <a target="_blank" href="http://github.com"><code>github.com</code></a> is the remote host. Now this config file created a shortcut hostname called <code>github.com-user1</code>. Now if we use this then it will still connect to the <code>github.com</code> remote host but for authentication, it will use the <code>user1</code> public key. So the URL will look like this.</p>
<pre><code class="lang-bash">git@github.com-user1:user1/latebro.git
</code></pre>
<p>And as I said you can now access any private repository of <code>user1</code> . You just need to use this format in the SSH URL.</p>
<p>Now you can do the same steps for your all other accounts and you are done with setting up multiple github accounts on one device. In my case, I’ve two accounts so my SSH config file looks like this.</p>
<pre><code class="lang-bash">Host    github.com-user1
    HostName github.com
    User git
    IdentityFile ~/.ssh/user1

Host    github.com-user2
    HostName github.com
    User git
    IdentityFile ~/.ssh/user2
</code></pre>
<p>I think you already guessed that for <code>user2</code> repositories I’m going to use an SSH URL like this.</p>
<pre><code class="lang-bash">git@github.com-user2:user2/webcamio.git
</code></pre>
<h2 id="heading-folder-based-git-profile">Folder-Based Git Profile</h2>
<p>Now our authentication problem is solved &amp; we can clone, and push changes using a specific formatted URL. But still, we have a problem that we can clone from different accounts but our commit is going from one profile.</p>
<p>To solve that we will use the Folder-Based Git profile technique. Here we will define a Git profile for a specific folder only. Let’s say I’ve two working folders called <code>user1-projects</code> and <code>user2-projects</code> . Now I want to have the <code>user1</code> git profile in the <code>user1-projects</code> folder &amp; <code>user2</code> git profile in the <code>user2-projects</code> folder. So whenever I work on the <code>user1-projects</code> folder, My commit history will contain the <code>user1</code> git profile &amp; If I work on the <code>user2-projects</code> folder, then My commit history will contain the <code>user2</code> git profile.</p>
<p>First of all, we need to create separate gitconfig files for each profile. In my case <code>user1</code> &amp; <code>user2</code>. To organize stuff better I’m creating them inside a folder called <code>gitconfigs</code> in the home directory.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># user1</span>
[user]
    name = User One
    email = user1@example.com
</code></pre>
<pre><code class="lang-bash"><span class="hljs-comment"># user2</span>
[user]
    name = User Two
    email = user2@example.com
</code></pre>
<p>Now to set up everything &amp; define the rules to use which config file when? We need to create an index config file in our home folder called <code>.gitconfig</code>. If you already worked with git then you most probably already have it. So just put these lines in your git config file.</p>
<pre><code class="lang-bash">[includeIf <span class="hljs-string">"gitdir:~/user1-projects/"</span>]
    path = ~/gitconfigs/user1

[includeIf <span class="hljs-string">"gitdir:~/user2-projects/"</span>]
    path = ~/gitconfigs/user2
</code></pre>
<p><strong>What It Does?</strong></p>
<p>This tells Git:</p>
<ul>
<li><p>If I’m working on <code>~/user1-projects</code> directory then use git config from <code>~/gitconfigs/user1</code></p>
</li>
<li><p>If I’m working on <code>~/user2-projects</code> directory then use git config from <code>~/gitconfigs/user2</code></p>
</li>
</ul>
<p>That’s it we are done with setting up the <strong>Folder-Based Git Profile</strong>. Now all you need to do is modify stuff as per your need and you're good to go for building projects.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Dealing with multiple GitHub accounts on one machine can be tiring, but with SSH-based authentication and folder-specific Git profiles, you can simplify the process significantly. The need for repetitive authentications when switching accounts is mitigated by configuring the custom SSH micro for each account. Moreover, it's possible to set up folder-based Git profiles so that commits are made to the appropriate GitHub accounts.</p>
<p>With this enabled, you are free to work on as many repositories as you desire without needing to authenticate, masticate, or switch between accounts to cloud this environment to blend or make the invites. This tactic helps keep the development environment untangled while optimizing time for other matters. Happy coding! 🚀</p>
]]></content:encoded></item><item><title><![CDATA[Understanding Adaptive Bitrate Streaming]]></title><description><![CDATA[YouTube is one platform that most of us use in our day-to-day activities. One thing we tend to take for granted is how smoothly these videos stream. Users can pick up video quality on YouTube, and if mine is slow, it automatically adjusts itself to d...]]></description><link>https://blog.tonmoydeb.com/understanding-adaptive-bitrate-streaming</link><guid isPermaLink="true">https://blog.tonmoydeb.com/understanding-adaptive-bitrate-streaming</guid><category><![CDATA[Web Development]]></category><category><![CDATA[video streaming]]></category><dc:creator><![CDATA[Tonmoy Deb]]></dc:creator><pubDate>Thu, 27 Feb 2025 04:36:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1740630612531/8c771427-4216-4ad7-a7ac-b68ed201ea48.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>YouTube is one platform that most of us use in our day-to-day activities. One thing we tend to take for granted is how smoothly these videos stream. Users can pick up video quality on YouTube, and if mine is slow, it automatically adjusts itself to deliver the content in lower quality so that it can be watched without interruptions. This technology is called Adaptive Bitrate Streaming, with which I would like to discuss both its working and importance.</p>
<h2 id="heading-problem-1-video-being-slow-to-load">Problem 1: Video Being Slow to Load</h2>
<p>When you attempt to play a video file in an HTML video player, your browser buffers the whole video file before beginning playback. Whatever the size file and whatever your network condition were, you'd wait for a good while. The bigger the file size, the longer you'd be waiting for—definitely a user experience killer.</p>
<h2 id="heading-problem-2-quality-switching-is-inefficient">Problem 2: Quality Switching Is Inefficient</h2>
<p>For this purpose, possible solutions to the above problems seem to involve the conversion of video files into various quality formats, where users can finally select the best based on their network speed or preference. It sure is a good idea but fails miserably in execution. Why?</p>
<p>Here's a user waiting for the video to be loaded in full. After watching half the video, if they change their mind and switch quality, then from the beginning of the video, the player reloads and starts playing, thus stalling itself for a bit longer. Frustration, inefficiency. Very much so.</p>
<p>Now, let us delve further into how Adaptive Bitrate Streaming successfully addresses these issues by allowing for streamlined viewing.</p>
<h2 id="heading-solution-adaptive-bitrate-streaming">Solution: Adaptive <strong>Bitrate</strong> Streaming</h2>
<p>This is a method where video streaming dynamically switches qualities depending on client network speed and instead of loading the whole video file at once, it loads a small portion of the video chunk by chunk. After all of this users can experience smooth video streaming. let’s deep dive into this.</p>
<h3 id="heading-segmented-video-streaming">Segmented Video Streaming</h3>
<p>The whole video is divided into smaller segments (2-10 seconds each). and to track all the segments there is one playlist file that takes care of the serialization of the segments. So at the end, we pass this playlist file to the user and the user loads the video segment by segment. There is no need to wait for the whole file to fetch</p>
<h3 id="heading-multiple-quality">Multiple Quality</h3>
<p>The video file is stored in multiple-quality with smaller segments. To track all the qualities there will be a master playlist file that lists all the quality options to the user and the user can select from the options. All the quality video is stored in smaller segments so the user can switch quality whenever he wants. only the current chunk will be loaded again.</p>
<h3 id="heading-realtime-quality-adjustments">Realtime Quality Adjustments</h3>
<p>on the master playlist file, there is a property called BANDWIDTH. Using that system will automatically switch video quality based on user network speed.</p>
<h2 id="heading-how-to-implement-abr">How to implement ABR?</h2>
<p>There are primarily two ways to implement adaptive streaming</p>
<h3 id="heading-http-live-streaming-hls">HTTP Live Streaming (HLS)</h3>
<p>Developed by Apple, HLS uses <code>.m3u8</code> playlists and is widely supported on iOS/macOS. It originally used <strong>MPEG-TS</strong> but now supports <strong>fMP4</strong> and has a low-latency variant (LL-HLS).</p>
<h3 id="heading-dynamic-adaptive-streaming-over-http-dash">Dynamic Adaptive Streaming Over HTTP (DASH)</h3>
<p>An open-standard streaming protocol that uses <code>.mpd</code> files and supports <strong>fMP4</strong>. It offers broader codec support (H.265, VP9, AV1) and is widely used on Android, Windows, and web platforms.</p>
<p>For today's article, I’ll continue with the HLS method. So enough talking dive into some examples.</p>
<h2 id="heading-implementing-hls-avr">Implementing HLS AVR</h2>
<h3 id="heading-tools">Tools</h3>
<p>Before diving into examples let me just quickly introduce our main tool.</p>
<p><strong>FFmpeg:</strong> As we are talking about encoding &amp; decoding stuff. We will need ffmpeg for this media file encoding. so make sure you’ve installed it on your device. for reference, you can follow this <a target="_blank" href="https://ffmpeg.org/">documentation</a>.</p>
<p>Now we are ready to dive into examples.</p>
<h3 id="heading-step-1-convert-media-files-into-hls-format">Step 1: Convert Media Files Into HLS Format</h3>
<p>In this step, we will convert media files to small segments in HLS format. To achieve this we need to run this command.</p>
<pre><code class="lang-bash">ffmpeg -i input.mp4 -codec: copy -start_number 0 -hls_time 5 -hls_list_size 0 -f hls output.m3u8
</code></pre>
<p><strong>Explanations:</strong></p>
<ul>
<li><p><code>-i input.mp4</code> specifies our input file for this command</p>
</li>
<li><p><code>-codec: copy</code> this specifies to copy the input file codec instead of re-encoding for the output file</p>
</li>
<li><p><code>-start_number 0</code> specifies the starting number for the segments</p>
</li>
<li><p><code>-hls_time 5</code> specifies each segment duration in seconds. in our case, it’s 5 seconds.</p>
</li>
<li><p><code>-hls_list_size 0</code> This specifies how many segments should be stored in the output playlist file. to store all the segments we need to use <code>0</code> value.</p>
</li>
<li><p><code>-f hls output.m3</code> This specifies output format as <code>hls</code> format and file name as <code>output.m3u8</code></p>
</li>
</ul>
<p>After executing this command you will see multiple <code>.ts</code> file was generated based on your input file size and one <code>output.m3u8</code> file is generated. This file is our playlist file that tracks all the segments &amp; this file is served to the client.</p>
<h3 id="heading-step-2-playing-hls-format-file">Step 2: Playing HLS Format File</h3>
<p>In general, we just pass the file URL to the HTML video element &amp; that’s it, we can play the video file. However, we don’t have any native support for the HLS format file. we need to use a third-party package called <a target="_blank" href="https://www.npmjs.com/package/hls.js">hls.js</a>. Here is a simple example of that</p>
<pre><code class="lang-bash">&lt;!DOCTYPE html&gt;
&lt;html lang=<span class="hljs-string">"en"</span>&gt;
&lt;head&gt;
    &lt;meta charset=<span class="hljs-string">"UTF-8"</span>&gt;
    &lt;meta name=<span class="hljs-string">"viewport"</span> content=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;
    &lt;title&gt;HLS Video Preview&lt;/title&gt;
    &lt;script src=<span class="hljs-string">"&lt;https://cdn.jsdelivr.net/npm/hls.js@1.4.12/dist/hls.min.js&gt;"</span>&gt;&lt;/script&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            text-align: center;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

    &lt;h2&gt;HLS Video Preview&lt;/h2&gt;

    &lt;video id=<span class="hljs-string">"hls-video"</span> controls width=<span class="hljs-string">"640"</span> height=<span class="hljs-string">"360"</span>&gt;&lt;/video&gt;

    &lt;script&gt;
        const video = document.getElementById(<span class="hljs-string">'hls-video'</span>);
        const hlsUrl = <span class="hljs-string">"./output.m3u8"</span>; // Replace with your HLS URL

        <span class="hljs-keyword">if</span> (Hls.isSupported()) {
            const hls = new Hls();
            hls.loadSource(hlsUrl);
            hls.attachMedia(video);
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (video.canPlayType(<span class="hljs-string">'application/vnd.apple.mpegurl'</span>)) {
            // Fallback <span class="hljs-keyword">for</span> Safari (<span class="hljs-built_in">which</span> supports native HLS)
            video.src = hlsUrl;
        } <span class="hljs-keyword">else</span> {
            alert(<span class="hljs-string">"Your browser does not support HLS playback."</span>);
        }
    &lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>If we try to preview (use vs code <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer">live server</a> extension) this file on the browser we will see the video is playing as it is. If your video size is large, you will notice the difference between normal video file streaming &amp; hls encoded video file streaming. If you want to explore more you can open the Network Tab from browser developer tools. We will see that the video segments are loaded one by one.</p>
<h3 id="heading-step-3-converting-into-multiple-qualities">Step 3: Converting Into Multiple Qualities</h3>
<p>Currently, we’re providing video chunk by chunk which is already lot optimized but we need to give a quality switching feature to users also. to achieve that we need to customize our command a little bit.</p>
<pre><code class="lang-bash">ffmpeg -y -i <span class="hljs-string">"input.mp4"</span> \\
  -vf scale=w=-2:h=720:force_original_aspect_ratio=decrease:force_divisible_by=2 -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 26 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 3000k -maxrate 3600k -bufsize 6000k -b:a 128k -hls_segment_filename <span class="hljs-string">"720p_%03d.ts"</span> -f hls <span class="hljs-string">"720p.m3u8"</span> \\
  -vf scale=w=-2:h=480:force_original_aspect_ratio=decrease:force_divisible_by=2 -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 28 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 1500k -maxrate 1800k -bufsize 3000k -b:a 128k -hls_segment_filename <span class="hljs-string">"480p_%03d.ts"</span> -f hls <span class="hljs-string">"480p.m3u8"</span> \\
  -vf scale=w=-2:h=360:force_original_aspect_ratio=decrease:force_divisible_by=2 -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 30 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 800k -maxrate 960k -bufsize 1600k -b:a 96k -hls_segment_filename <span class="hljs-string">"360p_%03d.ts"</span> -f hls <span class="hljs-string">"360p.m3u8"</span> \\
  -vf scale=w=-2:h=240:force_original_aspect_ratio=decrease:force_divisible_by=2 -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 32 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 400k -maxrate 480k -bufsize 800k -b:a 64k -hls_segment_filename <span class="hljs-string">"240p_%03d.ts"</span> -f hls <span class="hljs-string">"240p.m3u8"</span>
</code></pre>
<p><strong>Explanations:</strong></p>
<ul>
<li><p><code>-y</code> This is to allow automatically all operations. in some cases, <code>ffmpeg</code> might ask you for your confirmation (like overwriting a file)</p>
</li>
<li><p><code>-i "input.mp4"</code> This specifies the input file</p>
</li>
<li><p><code>-vf scale=w=-2:h=720</code> This resize video into 720p while maintaining the aspect ratio (using <code>w=-2</code> it automatically calculates the width)</p>
</li>
<li><p><code>force_original_aspect_ratio=decrease</code> This prevents the video from stretching while resizing</p>
</li>
<li><p><code>force_divisible_by=2</code> Ensures video dimension is always even number, to prevent runtime encoding error.</p>
</li>
<li><p><code>-c:a aac -ar 48000</code> Encode audio format in ACC format with 48 kHz sampling rate.</p>
</li>
<li><p><code>-c:v h264 -profile:v main</code> Encoding video in H.264 format main profile</p>
</li>
<li><p><code>-crf 26</code> Constant Rate Factor (CRF) controls video quality</p>
<ul>
<li><p>Higher Value = low quality, small file size</p>
</li>
<li><p>Lower Value = better quality, large file size</p>
</li>
</ul>
</li>
<li><p><code>-sc_threshold 0</code> Ensures uniform keyframe spacing</p>
</li>
<li><p><code>-g 48</code> Sets Group of Pictures to 48</p>
</li>
<li><p><code>-keyint_min 48</code> Ensure minimum keyframe interval 48</p>
</li>
<li><p><code>-hls_time 4</code> Each segment duration is set to 4 seconds</p>
</li>
<li><p><code>-hls_playlist_type vod</code> Generates a fixed playlist with all segments</p>
</li>
<li><p><code>-b:v 3000k</code> Sets video bitrate to 3Mbps</p>
</li>
<li><p><code>-maxrate 3600k -bufsize 6000k</code> Controls bitrate fluctuations for better stability</p>
</li>
<li><p><code>-b:a 128k</code> Sets auto bitrate to 128kbps</p>
</li>
<li><p><code>-hls_segment_filename "720p_%03d.ts"</code> Defines segment file name. We will generate segments for different qualities so to differentiate them we need to use a specific file name format.</p>
</li>
<li><p><code>-f hls "720p.m3u8"</code> Specifying playlist output file path</p>
</li>
</ul>
<p>The same command options are applied for other qualities also with different values for sure. Now we need to create a master playlist file to track different quality playlists. here is an example of the master playlist.</p>
<pre><code class="lang-bash"><span class="hljs-comment">#EXTM3U</span>
<span class="hljs-comment">#EXT-X-VERSION:3</span>

<span class="hljs-comment"># 720p Stream</span>
<span class="hljs-comment">#EXT-X-STREAM-INF:BANDWIDTH=3600000,RESOLUTION=1280x720</span>
720p.m3u8

<span class="hljs-comment"># 480p Stream</span>
<span class="hljs-comment">#EXT-X-STREAM-INF:BANDWIDTH=1800000,RESOLUTION=854x480</span>
480p.m3u8

<span class="hljs-comment"># 360p Stream</span>
<span class="hljs-comment">#EXT-X-STREAM-INF:BANDWIDTH=960000,RESOLUTION=640x360</span>
360p.m3u8

<span class="hljs-comment"># 240p Streamjust </span>
<span class="hljs-comment">#EXT-X-STREAM-INF:BANDWIDTH=480000,RESOLUTION=426x240</span>
240p.m3u8
</code></pre>
<p><strong>Explanations:</strong></p>
<ul>
<li><p><code>#EXTM3U</code> Marks this as an HLS playlist.</p>
</li>
<li><p><code>#EXT-X-VERSION:3</code> HLS version <strong>3</strong>, widely supported.</p>
</li>
<li><p>****<code>#EXT-X-STREAM-INF</code> ****Each section defines a video quality option:</p>
<ul>
<li><p><code>BANDWIDTH=3600000</code> Maximum bitrate for this stream (in bits per second). this helps with auto video quality switching based on the user network connection speed</p>
</li>
<li><p><code>RESOLUTION=1280x720</code> Video resolution.</p>
</li>
<li><p><code>720p.m3u8</code> Points to the playlist file for that resolution.</p>
</li>
</ul>
</li>
</ul>
<p>Now to preview this video provide this <code>master.m3u8</code> file path in the preview example and open in a browser. Now to test whether the auto quality switching is working or not you can use the <strong>Network Throttle</strong> option from the Browser Network Tab. If you choose <strong>Slow 4G</strong> from there then you will notice the video player automatically reduces the video quality. if you disable the throttle option then video quality will be switched back to high quality automatically.</p>
<h3 id="heading-step-4-manual-quality-switching">Step 4: Manual Quality Switching</h3>
<p>Now if you want to give a feature to your users to switch video quality manually then you can just update our preview example with the following code.</p>
<pre><code class="lang-bash">&lt;!DOCTYPE html&gt;
&lt;html lang=<span class="hljs-string">"en"</span>&gt;

&lt;head&gt;
    &lt;meta charset=<span class="hljs-string">"UTF-8"</span>&gt;
    &lt;meta name=<span class="hljs-string">"viewport"</span> content=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;
    &lt;title&gt;HLS Video Preview with Quality Selector&lt;/title&gt;
    &lt;script src=<span class="hljs-string">"&lt;https://cdn.jsdelivr.net/npm/hls.js@1.4.12/dist/hls.min.js&gt;"</span>&gt;&lt;/script&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            text-align: center;
        }

        <span class="hljs-comment">#quality-selector {</span>
            margin-top: 10px;
            padding: 5px;
        }
    &lt;/style&gt;
&lt;/head&gt;

&lt;body&gt;

    &lt;h2&gt;HLS Video Preview&lt;/h2&gt;

    &lt;video id=<span class="hljs-string">"hls-video"</span> controls width=<span class="hljs-string">"640"</span> height=<span class="hljs-string">"360"</span>&gt;&lt;/video&gt;
    &lt;br&gt;
    &lt;label <span class="hljs-keyword">for</span>=<span class="hljs-string">"quality-selector"</span>&gt;Select Quality:&lt;/label&gt;
    &lt;select id=<span class="hljs-string">"quality-selector"</span> disabled&gt;
        &lt;option&gt;Auto&lt;/option&gt;
    &lt;/select&gt;

    &lt;script&gt;
        const video = document.getElementById(<span class="hljs-string">'hls-video'</span>);
        const qualitySelector = document.getElementById(<span class="hljs-string">'quality-selector'</span>);
        const hlsUrl = <span class="hljs-string">"./master.m3u8"</span>; // Replace with your .m3u8 URL

        <span class="hljs-keyword">if</span> (Hls.isSupported()) {
            const hls = new Hls();
            hls.loadSource(hlsUrl);
            hls.attachMedia(video);

            hls.on(Hls.Events.MANIFEST_PARSED, () =&gt; {
                const levels = hls.levels.map((level, index) =&gt; ({
                    index,
                    label: level.height ? `<span class="hljs-variable">${level.height}</span>p` : `<span class="hljs-variable">${level.bitrate / 1000}</span> kbps`
                }));

                qualitySelector.innerHTML = `&lt;option value=<span class="hljs-string">"-1"</span>&gt;Auto&lt;/option&gt;`;
                levels.forEach(level =&gt; {
                    qualitySelector.innerHTML += `&lt;option value=<span class="hljs-string">"<span class="hljs-variable">${level.index}</span>"</span>&gt;<span class="hljs-variable">${level.label}</span>&lt;/option&gt;`;
                });

                qualitySelector.disabled = <span class="hljs-literal">false</span>;
            });

            qualitySelector.addEventListener(<span class="hljs-string">'change'</span>, (event) =&gt; {
                const selectedLevel = parseInt(event.target.value);
                hls.currentLevel = selectedLevel;
            });
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (video.canPlayType(<span class="hljs-string">'application/vnd.apple.mpegurl'</span>)) {
            // Fallback <span class="hljs-keyword">for</span> Safari (<span class="hljs-built_in">which</span> supports native HLS)
            video.src = hlsUrl;
        } <span class="hljs-keyword">else</span> {
            alert(<span class="hljs-string">"Your browser does not support HLS playback."</span>);
        }
    &lt;/script&gt;

&lt;/body&gt;

    &lt;/html&gt;
</code></pre>
<p>Here first we list all the available quality options and then let the user select his desired video quality and enjoy.</p>
<h3 id="heading-explanation">Explanation</h3>
<p>After loading the master playlist file it provides available quality options in <code>hls.levels</code> and for changing quality we can set the level index in <code>hls.currentLevel</code>. By default, it’s <code>-1</code> means automatic switching based on network bandwidth</p>
<h2 id="heading-real-world-implementation">Real-world Implementation</h2>
<p>This article covers only required commands but in Real-world applications, you might need to implement various technologies. to demonstrate that I made a project using Nest JS &amp; React JS. You will find the <a target="_blank" href="https://github.com/tonmoydeb404/adaptive-bitrate-streaming">source code here</a>. again it’s not production-grade code or something, it’s just an example of using the commands in your project.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>If you've followed this guide, congratulations! 🎉 You now understand <strong>Adaptive Bitrate Streaming (ABR)</strong> and how to implement <strong>HLS with FFmpeg</strong>. While this article covers the basics, real-world applications require additional considerations like backend integration and optimization strategies. Once you're comfortable with these fundamentals, you can explore l<strong>ow-latency HLS (LL-HLS)</strong> for even better performance.</p>
<p>Stay tuned for more advanced topics!</p>
]]></content:encoded></item><item><title><![CDATA[Escape Learning Hell: How to Learn Effectively and Purposefully]]></title><description><![CDATA[Introduction
It’s another day, and we are still here. As software developers, we always find ourselves being asked to learn, be it a new tool, framework, or programming language. But today, let's step away from that for a moment. I want to talk about...]]></description><link>https://blog.tonmoydeb.com/escape-learning-hell-how-to-learn-effectively-and-purposefully</link><guid isPermaLink="true">https://blog.tonmoydeb.com/escape-learning-hell-how-to-learn-effectively-and-purposefully</guid><category><![CDATA[developer-journey]]></category><dc:creator><![CDATA[Tonmoy Deb]]></dc:creator><pubDate>Sun, 02 Feb 2025 17:36:20 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1738517393412/f9957da7-48fd-4aa4-aaf8-19850a57472d.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>It’s another day, and we are still here. As software developers, we always find ourselves being asked to learn, be it a new tool, framework, or programming language. But today, let's step away from that for a moment. I want to talk about something different: things we learn to stay abreast of the industry trends or enhance our careers even though we might not have a legitimized need for these right now.</p>
<p>You may be just starting out, laying down a foundation for some good job opportunities. Or you may be in the game for quite a while, but still seeking for the next skill to stay fresh. But I would pose a more critical question to you: Are we, in fact, learning effectively? Is all this knowledge of real value; or are we just filling our heads with information that serves no purpose? Let us go check that.</p>
<h2 id="heading-my-experience">My Experience</h2>
<p>Speaking from personal experience, I'm a self-taught developer who has primarily worked with JavaScript. Lots of time, I learned other languages like Python and Rust. But that did not really help me.</p>
<p>Why? That is because I had no real purpose for learning them.</p>
<p>It's just that I got caught up in the hype of learning them and after a week I lost the fervor to continue.</p>
<p>The same goes for other technologies. While I was learning React.js, someone suggested I use React-Query since it was something that would impress a recruiter in an interview. I tried it and I learned pretty much all the basics, but if you asked me to write some code with it right now I would not be able to do it.</p>
<p>Why? Because there was never a real case to use it. I learned it, but not using it in practice allowed that information to slip away. That's the whole wasted learning.</p>
<h2 id="heading-learning-hell">Learning Hell</h2>
<p>Many developers find it hard to get out of <strong>Tutorial Hell</strong>-a death spiral where videos are found constantly playing on a side of the screen while the student never executes their knowledge on the opposite side. Learning Hell is another variant of this trap.</p>
<p>In this stage, you’re running on a treadmill of perpetual learning. You will never feel ready to apply your thing, so instead, you keep stacking up the knowledge. It feels like progress, but, in truth, you're merely overwhelming your brain with information that you will never use.</p>
<p>If you can't really use what you've learned, what is the point of it all? In real-life problem-solving, you don’t need not know everything. The best way to learn is still through working on a project, and thereby solve whatever problem may arise, rather than benching yourself for life with a hundred tutorial courses on theory alone.</p>
<h2 id="heading-the-consequences">The Consequences</h2>
<p>Perhaps you are wondering: "If learning is such a good thing, then why are you discouraging it?" No, I'm not discouraging it. Learning must be done every day. However, I have seen many aspiring developers lose themselves in Learning Hell and, as a result, abandon their development careers. The entire experience leaves them so disillusioned that they can hardly continue.</p>
<p>Despite their good education, many programmers can't hold down a job because they're always questioning themselves. So they just keep learning instead of putting their knowledge to use. A few manage to get jobs but change careers for the mere reason of being utterly frustrated with the perpetual openness of learning.</p>
<h2 id="heading-solution">Solution</h2>
<p>So, what should you do instead?</p>
<ol>
<li><p><strong>Start Building:</strong> Instead of learning everything at once, try to apply your knowledge by building real projects. Try to find some problems that you face regularly &amp; solve them using your existing knowledge.</p>
</li>
<li><p><strong>Learn as you go:</strong> When you’re building stuff, you might realize that your existing knowledge is not enough. You might need additional knowledge to complete a feature in your project. then go and learn it. at first, no need to dig deep. try to solve your problem first.</p>
</li>
<li><p><strong>Find Purpose:</strong> Focus on the technologies that align with your work or goals. Ignore the unnecessary hype. If you find something that you don’t need today but is useful in the future then you can invest time and try to apply that with your regular life. so your investment won’t go wrong.</p>
</li>
</ol>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Learning is important, but purposeful learning pays off your effort. So don’t just learn—try to apply what you learn and find a purpose for why you're learning. Is it really important to you?</p>
<p>I’m also a victim of this, but I tried to overcome it, and I hope this article will help you overcome the problem as well. If you found this helpful, don’t forget to share it with other developers who might be struggling with the same issue.</p>
]]></content:encoded></item><item><title><![CDATA[The Art of Adaptation in a Developer’s Life]]></title><description><![CDATA[Introduction
As developers, we live in a world of constant evolution. Every day, new tools, frameworks, and technologies emerge, reshaping the way we work. To stay relevant, it's essential to embrace change and adapt to these innovations. In this blo...]]></description><link>https://blog.tonmoydeb.com/the-art-of-adaptation-in-a-developers-life</link><guid isPermaLink="true">https://blog.tonmoydeb.com/the-art-of-adaptation-in-a-developers-life</guid><category><![CDATA[developer-journey]]></category><dc:creator><![CDATA[Tonmoy Deb]]></dc:creator><pubDate>Sun, 26 Jan 2025 14:55:23 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1737906448215/20864f37-2892-40c8-8dec-649357106b4c.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction"><strong>Introduction</strong></h2>
<p>As developers, we live in a world of constant evolution. Every day, new tools, frameworks, and technologies emerge, reshaping the way we work. To stay relevant, it's essential to embrace change and adapt to these innovations. In this blog, I want to share my journey of adapting to new technologies and reflect on why mastery goes beyond just using a tool—it’s about integrating it into our daily workflow.</p>
<h2 id="heading-my-journey-with-javascript-and-react"><strong>My Journey with JavaScript and React</strong></h2>
<p>I still remember when I started learning React JS. At the time, I was deeply attached to raw JavaScript. It was familiar, efficient, and something I had spent years mastering. I could solve almost any problem in minutes because of how comfortable I was with it. React, on the other hand, felt new and challenging. Every time I built something with it, I encountered countless errors and roadblocks.</p>
<p>Despite the initial struggle, I stuck with React. Over time, as I worked on more projects, the challenges turned into opportunities to learn. Eventually, React became my go-to framework, and now, whether it’s a simple app or a complex system, I’m confident in building it with React.</p>
<p>This journey taught me an important lesson: mastery comes from consistent practice. Until you integrate a technology into your regular workflow, it remains unfamiliar and intimidating. Adapting to new tools is never easy, but it’s the only way to truly grow as a developer.</p>
<h2 id="heading-the-role-of-ai-in-development"><strong>The Role of AI in Development</strong></h2>
<p>In today’s AI-driven world, tools like ChatGPT have revolutionized development. They allow us to write code, debug issues, and research solutions faster than ever before. But there’s an important distinction between using AI and mastering a technology.</p>
<p>AI can help you build prototypes, automate repetitive tasks, and provide quick answers. However, creating production-level applications requires more than just writing code. Real-world scenarios are filled with unique challenges, and solving them demands experience, creativity, and problem-solving skills.</p>
<p>For example, you may have seen YouTube videos claiming, “I built a million-dollar app using AI.” While impressive, these developers often have years of experience and use AI as a tool to accelerate their workflow—not as a crutch. Mastery comes from understanding the nuances of your tools, and that level of understanding only comes with practice and adaptation.</p>
<h2 id="heading-why-adapting-matters"><strong>Why Adapting Matters</strong></h2>
<p>Adapting to new technologies isn’t just about learning the basics; it’s about incorporating them into your workflow. For instance, when I first started with React, I struggled to let go of my JavaScript habits. But over time, I realized that by adapting React into my daily projects, I could unlock its true potential.</p>
<p>The same applies to AI tools. While they’re excellent for speeding up tasks, they can’t replace the depth of knowledge you gain through hands-on experience. Building expertise requires consistent effort—reading documentation, solving problems, and experimenting with real-world projects. You don’t need to master every tool, but for the ones you want to excel at, make them part of your routine.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>AI is a powerful ally for developers, but it’s not a replacement for expertise. To truly master a technology, you need to adapt it into your daily life and face the challenges it brings. Mastery is not just about knowing how to use a tool—it’s about understanding its intricacies, solving unique problems, and growing with it. The art of adaptation is what keeps us evolving in this ever-changing field of development.</p>
]]></content:encoded></item></channel></rss>