<?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" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[IT Untold]]></title><description><![CDATA[Stories and Insights from the Real World of IT and Technology]]></description><link>https://ituntold.rixlabs.dev</link><image><url>https://substackcdn.com/image/fetch/$s_!vR--!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F741adb9b-20f4-47ba-8aa6-3f06ebe39b25_1024x1024.png</url><title>IT Untold</title><link>https://ituntold.rixlabs.dev</link></image><generator>Substack</generator><lastBuildDate>Sat, 04 Apr 2026 08:49:34 GMT</lastBuildDate><atom:link href="https://ituntold.rixlabs.dev/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Riccardo]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[rixlabs@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[rixlabs@substack.com]]></itunes:email><itunes:name><![CDATA[Riccardo Causo]]></itunes:name></itunes:owner><itunes:author><![CDATA[Riccardo Causo]]></itunes:author><googleplay:owner><![CDATA[rixlabs@substack.com]]></googleplay:owner><googleplay:email><![CDATA[rixlabs@substack.com]]></googleplay:email><googleplay:author><![CDATA[Riccardo Causo]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[The hard part I skipped: Passkeys Cryptography]]></title><description><![CDATA[Understanding elliptic curves, signatures, and challenges (with visual help)]]></description><link>https://ituntold.rixlabs.dev/p/the-hard-part-i-skipped-passkeys</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/the-hard-part-i-skipped-passkeys</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Fri, 24 Oct 2025 14:02:48 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!U2be!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b7ea449-191f-4ae3-8d17-e9b85b852ccf_330x440.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A short follow-up to my <a href="https://ituntold.rixlabs.dev/p/passkeys-moving-beyond-passwords">previous article</a> on passkeys. I initially skipped the cryptographic part, like everyone, I didn&#8217;t feel like doing the hard part. But since you can&#8217;t really understand passkeys without going under the hood, this is the moment to do it.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!U2be!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b7ea449-191f-4ae3-8d17-e9b85b852ccf_330x440.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!U2be!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b7ea449-191f-4ae3-8d17-e9b85b852ccf_330x440.gif 424w, https://substackcdn.com/image/fetch/$s_!U2be!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b7ea449-191f-4ae3-8d17-e9b85b852ccf_330x440.gif 848w, https://substackcdn.com/image/fetch/$s_!U2be!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b7ea449-191f-4ae3-8d17-e9b85b852ccf_330x440.gif 1272w, https://substackcdn.com/image/fetch/$s_!U2be!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b7ea449-191f-4ae3-8d17-e9b85b852ccf_330x440.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!U2be!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b7ea449-191f-4ae3-8d17-e9b85b852ccf_330x440.gif" width="330" height="440" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2b7ea449-191f-4ae3-8d17-e9b85b852ccf_330x440.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:440,&quot;width&quot;:330,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:17164,&quot;alt&quot;:&quot;Elliptic arithmetic&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/176907572?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b7ea449-191f-4ae3-8d17-e9b85b852ccf_330x440.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Elliptic arithmetic" title="Elliptic arithmetic" srcset="https://substackcdn.com/image/fetch/$s_!U2be!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b7ea449-191f-4ae3-8d17-e9b85b852ccf_330x440.gif 424w, https://substackcdn.com/image/fetch/$s_!U2be!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b7ea449-191f-4ae3-8d17-e9b85b852ccf_330x440.gif 848w, https://substackcdn.com/image/fetch/$s_!U2be!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b7ea449-191f-4ae3-8d17-e9b85b852ccf_330x440.gif 1272w, https://substackcdn.com/image/fetch/$s_!U2be!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b7ea449-191f-4ae3-8d17-e9b85b852ccf_330x440.gif 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h2>How Passkeys Work at the Cryptographic Level</h2><p>When you register a passkey with a service (the relying party), your device generates a <strong>key pair</strong>, a public key and a private key. The public key is shared with the server, while the private key is securely stored in your device&#8217;s enclave or secure element (for example, the Trusted Platform Module or Secure Enclave).</p><p>When you later authenticate, the server sends a <strong>challenge</strong>, a random piece of data, to your device. Your device signs this challenge using the private key, producing a <strong>digital signature</strong>. The server then uses the public key it stored earlier to verify the signature. If the verification passes, the server knows two things:</p><p>- The signature could only have been created by the matching private key.</p><p>- The challenge is fresh, meaning the authentication attempt is not a replay of a previous one.</p><p>This process provides <strong>proof of possession</strong> of the private key, without ever transmitting it over the network.</p><p>At a <strong>high level</strong>, the math works like this:</p><p>- The device generates a signature using the private key.</p><p>- The server verifies the signature with the public key.</p><p>- If verification passes, the server knows the user is authentic.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>The Math Behind the Verification</h2><p>WebAuthn supports multiple cryptographic algorithms, with <strong>ECDSA (Elliptic Curve Digital Signature Algorithm)</strong> and <strong>EdDSA (Ed25519)</strong> being the most common. RSA-based algorithms like <strong>RSASSA-PKCS1-v1_5</strong> and <strong>RSASSA-PSS</strong> are also supported for compatibility.</p><p>The principle behind all these algorithms is that the <strong>public key is mathematically linked to the private key</strong>, allowing verification without ever exposing the private key. The algorithms differ in curves, key sizes, and signing methods, but all implement <strong>challenge-response authentication</strong>.</p><h3>ECDSA Example: A Step-by-Step Walkthrough</h3><p>Let&#8217;s be honest: the math behind ECDSA is not easy to follow. Even with a clear explanation, keeping track of all the variables (d, k, r, s, Q, R, G, H...) and understanding how they relate to each other can feel overwhelming. You&#8217;re dealing with elliptic curve operations, modular arithmetic, and multiple interdependent steps, all happening simultaneously.</p><p>That&#8217;s why I&#8217;ve created an <strong>interactive visual guide</strong> that walks you through each step with animations and highlights. Instead of just reading about the process, you can see it unfold:</p><p>&#127919; <a href="https://rixlabs.github.io/passkeys-visual-guide">Launch Interactive Visual Guide</a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!M7jN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989ffec9-d975-4b7b-8919-f447595cfa84_1946x748.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!M7jN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989ffec9-d975-4b7b-8919-f447595cfa84_1946x748.png 424w, https://substackcdn.com/image/fetch/$s_!M7jN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989ffec9-d975-4b7b-8919-f447595cfa84_1946x748.png 848w, https://substackcdn.com/image/fetch/$s_!M7jN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989ffec9-d975-4b7b-8919-f447595cfa84_1946x748.png 1272w, https://substackcdn.com/image/fetch/$s_!M7jN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989ffec9-d975-4b7b-8919-f447595cfa84_1946x748.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!M7jN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989ffec9-d975-4b7b-8919-f447595cfa84_1946x748.png" width="1456" height="560" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/989ffec9-d975-4b7b-8919-f447595cfa84_1946x748.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:560,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:115369,&quot;alt&quot;:&quot;Passkey visual guide&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/176907572?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989ffec9-d975-4b7b-8919-f447595cfa84_1946x748.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Passkey visual guide" title="Passkey visual guide" srcset="https://substackcdn.com/image/fetch/$s_!M7jN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989ffec9-d975-4b7b-8919-f447595cfa84_1946x748.png 424w, https://substackcdn.com/image/fetch/$s_!M7jN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989ffec9-d975-4b7b-8919-f447595cfa84_1946x748.png 848w, https://substackcdn.com/image/fetch/$s_!M7jN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989ffec9-d975-4b7b-8919-f447595cfa84_1946x748.png 1272w, https://substackcdn.com/image/fetch/$s_!M7jN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F989ffec9-d975-4b7b-8919-f447595cfa84_1946x748.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>The guide breaks down the entire process into digestible steps, showing you exactly when each variable is created, how they combine, and where they end up. I highly recommend opening it in a new tab and following along as you read the explanation below.</p><p>Now, let&#8217;s walk through ECDSA from setup to verification.</p><p><strong>Initial Setup: Creating the Key Pair</strong></p><p>When you first register a passkey, your device creates a key pair on an elliptic curve. Think of an elliptic curve as a mathematical space where certain operations are easy in one direction but nearly impossible to reverse.</p><p>The setup starts with a fixed point called the <strong>generator `G`</strong>, which is a standard point that everyone using this curve agrees upon. Your device then:</p><p>1. Generates a <strong>private key `d`</strong>, which is simply a large random number. This is your secret, stored securely in your device&#8217;s enclave, and never shared with anyone.</p><p>2. Computes the <strong>public key `Q`</strong> using the formula <strong>`Q = d * G`</strong>. This operation means &#8220;multiply the generator point <strong>`G`</strong> by the scalar <strong>`d`</strong>&#8221; in elliptic curve arithmetic.</p><p>Here&#8217;s the crucial property: computing <strong>`Q`</strong> from <strong>`d`</strong> and <strong>`G`</strong> is easy, but computing <strong>`d`</strong> from <strong>`Q`</strong> and <strong>`G`</strong> is computationally infeasible. This one-way property is what makes the cryptography secure. Your device sends <strong>`Q`</strong> to the server during registration, but <strong>`d`</strong> stays locked away forever.</p><p><strong>Authentication: Creating a Signature</strong></p><p>Now, when you return to authenticate, the server sends you a <strong>challenge `H`</strong> (typically a hash of random data plus contextual information). Your device needs to prove it still possesses the private key <strong>`d`</strong> without revealing it. Here&#8217;s how the signature is created:</p><p>1. <strong>Generate a fresh nonce `k`</strong>: For each signature, your device creates a new random number called <strong>`k`</strong>. This nonce is temporary and unique to this specific authentication attempt. Using a new <strong>`k`</strong> every time ensures that even signing the same challenge twice produces different signatures, preventing replay attacks.</p><p>2. <strong>Create a curve point `R`</strong>: Using the same generator <strong>`G`</strong> from setup, compute <strong>`R = k * G`</strong>. This point <strong>`R`</strong> has two coordinates, an <strong>x-coordinate</strong> and a <strong>y-coordinate</strong>.</p><p>3. <strong>Extract `r`</strong>: Take the <strong>x-coordinate</strong> of point <strong>`R`</strong> and call it <strong>`r`</strong>. This becomes the first part of your signature.</p><p>4. <strong>Compute `s`</strong>: Now comes the part that actually involves your private key. Calculate <strong>`s = k^(-1) * (H + r*d) mod n`</strong>, where:</p><p>   - <strong>`k^(-1)`</strong> is the modular inverse of your nonce <strong>`k`</strong></p><p>   - <strong>`H`</strong> is the <strong>hash of the challenge</strong> from the server</p><p>   - <strong>`r`</strong> is the <strong>x-coordinate</strong> we just extracted</p><p>   - <strong>`d`</strong> is your <strong>private key</strong></p><p>   - <strong>`n`</strong> is the order of the elliptic curve (a fixed parameter)</p><p>5. <strong>Send the signature</strong>: Your device sends the pair <strong>`(r, s)`</strong> back to the server. Notice that neither <strong>`d`</strong> (your private key) nor <strong>`k`</strong> (your temporary nonce) are included, only the values <strong>`r`</strong> and <strong>`s`</strong> derived from them.</p><p><strong>Verification: The Server&#8217;s Role</strong></p><p>The server now has:</p><p>- The challenge <strong>`H`</strong> it originally sent</p><p>- Your signature <strong>`(r, s)`</strong></p><p>- Your public key <strong>`Q`</strong> from registration</p><p>Using elliptic curve mathematics, the server can verify that this signature could only have been created by someone who knows the private key <strong>`d`</strong> corresponding to public key <strong>`Q`</strong>. The verification algorithm checks the mathematical relationship between all these values. If the relationship holds, the server has proof that you possess the private key without you ever transmitting it.</p><p>The beauty of this system is in its asymmetry: creating the signature requires the private key <strong>`d`</strong>, but verifying it only requires the public key <strong>`Q`</strong>. The server can be confident of your identity without ever knowing your secret.</p><p><strong>If you found this explanation dense</strong> <strong>(and honestly, who wouldn&#8217;t?), go back to the</strong> <a href="https://rixlabs.github.io/passkeys-visual-guide">interactive visual guide</a>. Click through each step and watch how the variables flow from one operation to the next. It makes the whole process much clearer than words alone can convey.</p><h3>Other Algorithms</h3><p>- <strong>EdDSA (Ed25519)</strong>: A faster, modern elliptic curve algorithm with deterministic signatures (no random <strong>`k`</strong> needed, which eliminates certain implementation risks).</p><p>- <strong>RSASSA-PKCS1-v1_5 and RSASSA-PSS</strong>: RSA-based algorithms that use different mathematical operations (prime factorization instead of elliptic curves) but follow the same principle of public key verification.</p><p>All these algorithms implement the same core concept: only the private key holder can produce a signature that the public key can verify, ensuring authenticity without exposing secrets.</p><h2>Why the Challenge Matters</h2><p>The challenge prevents <strong>replay attacks</strong>. Each authentication request generates a new random challenge, so an old signature is useless. Including contextual data, like the domain name, prevents <strong>phishing</strong> or <strong>cross-origin attacks</strong>, ensuring the signature is valid only for the legitimate site.</p><h2>Security Properties</h2><p>The cryptographic mechanism provides three main guarantees:</p><p>- <strong>Authenticity</strong> &#8211; Only the legitimate private key holder can produce a valid signature.</p><p>- <strong>Integrity</strong> &#8211; Any modification to the challenge or signed data invalidates the signature.</p><p>- <strong>Non-repudiation</strong> &#8211; Once the challenge is signed, the signer cannot plausibly deny having authenticated (depending on implementation).</p><p>These properties make passkeys robust against phishing, credential stuffing, and password leaks. The private key never leaves your device, and even the server breach won&#8217;t compromise your credentials.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><p>If you enjoyed this deeper dive and want to keep exploring the technical side of authentication, subscribe to the newsletter or follow me on <strong><a href="https://x.com/rixlabs">X</a></strong> for future updates.</p><p>If you find this content useful, feel free to support me with a <strong><a href="https://ko-fi.com/rixlabs">coffee</a></strong></p><div><hr></div><h2>More articles I enjoyed this week</h2><ul><li><p><a href="https://www.byhand.ai/p/linear-regression-new-free-series">Linear Regression (New Free Series)</a> by <a href="https://www.byhand.ai/">AI by Hand &#9997;&#65039;</a></p></li><li><p><a href="https://newsletter.francofernando.com/p/chain-replication">Chain Replication</a> by <a href="https://newsletter.francofernando.com/">The Polymathic Engineer</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Passkeys Explained: The Future of Passwordless Authentication]]></title><description><![CDATA[Discover how passkeys replace passwords with secure, phishing-resistant authentication using WebAuthn and FIDO2. Learn practical implementation tips and integration with password managers.]]></description><link>https://ituntold.rixlabs.dev/p/passkeys-moving-beyond-passwords</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/passkeys-moving-beyond-passwords</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Wed, 22 Oct 2025 09:13:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!oUbg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2eea096-12a2-4ff7-ae72-22d60b10976d_826x1211.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A short update from me on a topic I had to explore recently. Not an exhaustive guide but an introduction to a topic that is becoming ubiquitous. Passkeys aim to close the chapter on passwords, replacing them with a cryptographic system that is simpler for users and safer for everyone.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oUbg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2eea096-12a2-4ff7-ae72-22d60b10976d_826x1211.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oUbg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2eea096-12a2-4ff7-ae72-22d60b10976d_826x1211.png 424w, https://substackcdn.com/image/fetch/$s_!oUbg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2eea096-12a2-4ff7-ae72-22d60b10976d_826x1211.png 848w, https://substackcdn.com/image/fetch/$s_!oUbg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2eea096-12a2-4ff7-ae72-22d60b10976d_826x1211.png 1272w, https://substackcdn.com/image/fetch/$s_!oUbg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2eea096-12a2-4ff7-ae72-22d60b10976d_826x1211.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oUbg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2eea096-12a2-4ff7-ae72-22d60b10976d_826x1211.png" width="826" height="1211" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d2eea096-12a2-4ff7-ae72-22d60b10976d_826x1211.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1211,&quot;width&quot;:826,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:891607,&quot;alt&quot;:&quot;Passkey: The Next Step in Authentication&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/176812715?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2eea096-12a2-4ff7-ae72-22d60b10976d_826x1211.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Passkey: The Next Step in Authentication" title="Passkey: The Next Step in Authentication" srcset="https://substackcdn.com/image/fetch/$s_!oUbg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2eea096-12a2-4ff7-ae72-22d60b10976d_826x1211.png 424w, https://substackcdn.com/image/fetch/$s_!oUbg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2eea096-12a2-4ff7-ae72-22d60b10976d_826x1211.png 848w, https://substackcdn.com/image/fetch/$s_!oUbg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2eea096-12a2-4ff7-ae72-22d60b10976d_826x1211.png 1272w, https://substackcdn.com/image/fetch/$s_!oUbg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2eea096-12a2-4ff7-ae72-22d60b10976d_826x1211.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h2>What Is a Passkey</h2><p>A passkey is a cryptographic key pair that replaces a password. The private key stays securely on your device, while the public key is stored by the service you register with. When you log in, the service sends a random challenge that your device signs using the private key.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><p>The signature is verified using the public key, and access is granted only if the signature is valid. The private key never leaves your device and cannot be shared across sites. This removes the two classic risks of credential theft and phishing.</p><p>Passkeys are part of the FIDO2 and WebAuthn standards, and are supported across all major ecosystems including Apple, Google, and Microsoft.</p><h2>The WebAuthn Foundation</h2><p>At the core of passkeys is WebAuthn, the Web Authentication API. It defines how browsers, authenticators, and servers communicate to register and use credentials.</p><p>A WebAuthn flow consists of two main parts:</p><h3>Registration</h3><ul><li><p>The authenticator (your phone, laptop, or hardware key) generates a new key pair.</p></li><li><p>The public key is returned to the service and stored.</p></li><li><p>The private key remains secured on the authenticator.</p></li></ul><h3>Authentication</h3><ul><li><p>The service sends a unique challenge to the client.</p></li><li><p>The authenticator signs the challenge with the private key.</p></li><li><p>The server verifies the signature using the stored public key.</p></li></ul><p>Each credential is scoped to a specific origin, meaning that a key created for example.com cannot be used on fake-example.com. This property makes phishing nearly impossible.</p><p>WebAuthn supports two types of authenticators:</p><p><strong>Platform authenticators</strong>, built into a device (like Touch ID or Windows Hello).</p><p><strong>Roaming authenticators</strong>, external devices like YubiKeys that can be used across machines.</p><p>The browser acts as the interface between your application and these authenticators. In JavaScript, the process is straightforward:</p><pre><code>// Registration
const credential = await navigator.credentials.create({
  publicKey: publicKeyCreationOptions
});


// Authentication
const assertion = await navigator.credentials.get({
  publicKey: publicKeyRequestOptions
});</code></pre><p>The browser and operating system handle the cryptography and user verification. Your backend only needs to store public keys and verify signatures, which can be done through existing libraries for Java, Node.js, Go, and others.</p><h2>Implementation in Practice</h2><p><strong>To integrate passkeys in your app:</strong></p><ul><li><p>Use WebAuthn on the client side for registration and authentication.</p></li><li><p>Generate and store challenges securely server-side.</p></li><li><p>Validate signatures using a WebAuthn or FIDO2 library.</p></li><li><p>Update your login flow to support both passwords and passkeys during the transition.</p></li></ul><p>Mobile and desktop platforms provide equivalent APIs through AuthenticationServices (iOS) and Credential Manager (Android).</p><p><strong>Why It Matters</strong></p><ul><li><p>Phishing resistance: Credentials are domain-bound and cannot be replayed.</p></li><li><p>No password reuse: Each service has its own key pair.</p></li><li><p>Hardware-backed security: Private keys live inside secure enclaves or TPMs.</p></li><li><p>Faster user experience: Logins are completed with biometrics or device unlock.</p></li></ul><h2>Integration with Password Managers</h2><p>Modern password managers such as 1Password, Bitwarden, iCloud Keychain, and Google Password Manager now support passkeys. They act as roaming authenticators, synchronizing passkeys across devices while keeping private keys encrypted.</p><p>This approach combines strong cryptography with usability. Users can log in from new devices without manually exporting keys, while developers avoid dealing with device-specific storage concerns.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><p>Passkeys are not an experimental idea. They are live across browsers and platforms today. For developers, supporting them is mostly a matter of implementing WebAuthn and preparing authentication flows that work without passwords.</p><p>We have spent decades patching around passwords with multi-factor authentication, password complexity rules, and breach monitoring. Passkeys move the conversation forward by removing the weakest component altogether. They are not just a security upgrade &#8212; they are the logical endpoint of password evolution.</p><div><hr></div><h2>Articles I enjoyed this week</h2><ul><li><p><a href="https://newsletter.eng-leadership.com/p/engineering-leaders-guide-how-to">Engineering Leader&#8217;s Guide: How to Become a Great Coach and Mentor</a> by <a href="https://newsletter.eng-leadership.com/">Engineering Leadership</a></p></li><li><p><a href="https://lorenzhw.substack.com/p/4-resources-you-should-read-to-get">4 Resources You Should Read to Get Better at Agentic Coding</a> by <a href="https://lorenzhw.substack.com/">The Growing Engineer</a></p></li></ul><div><hr></div><p>If you want to explore the underbelly of IT and follow the journey of a senior engineer and architect, subscribe to this newsletter and follow me on <a href="https://x.com/rixlabs">X</a>. </p><p>If you find this content useful, feel free to support me with a <a href="https://ko-fi.com/rixlabs">coffee</a></p>]]></content:encoded></item><item><title><![CDATA[Can we look into MCP for real?]]></title><description><![CDATA[A deep dive under the hood of MCP, the most discussed protocol of 2025]]></description><link>https://ituntold.rixlabs.dev/p/can-we-look-into-mcp-for-real</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/can-we-look-into-mcp-for-real</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Tue, 30 Sep 2025 08:27:56 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!U3wV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d17f3b-c357-4404-a84c-c36737cd4474_1876x1100.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>What is Model Context Protocol (MCP)?</h2><p>MCP is the hottest thing this year in the AI sphere. I keep seeing badly written articles so I decided to try to put together some meaningful informations.</p><p>I did what every sensible person would at this point and I started asking question to Claude. From the questions I created this article to try bringing some clarity into the matter.</p><p>Model Context Protocol (MCP) is an open standard protocol introduced by Anthropic in November 2024 that standardizes how AI assistants communicate with external tools and data sources. Think of it as a universal adapter, like USB-C for hardware, that allows any AI application to connect with any tool or data source without custom integration code.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!U3wV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d17f3b-c357-4404-a84c-c36737cd4474_1876x1100.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!U3wV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d17f3b-c357-4404-a84c-c36737cd4474_1876x1100.png 424w, https://substackcdn.com/image/fetch/$s_!U3wV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d17f3b-c357-4404-a84c-c36737cd4474_1876x1100.png 848w, https://substackcdn.com/image/fetch/$s_!U3wV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d17f3b-c357-4404-a84c-c36737cd4474_1876x1100.png 1272w, https://substackcdn.com/image/fetch/$s_!U3wV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d17f3b-c357-4404-a84c-c36737cd4474_1876x1100.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!U3wV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d17f3b-c357-4404-a84c-c36737cd4474_1876x1100.png" width="1456" height="854" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/64d17f3b-c357-4404-a84c-c36737cd4474_1876x1100.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:854,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2450500,&quot;alt&quot;:&quot;MCP, the puppet master strings protocol&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/174905055?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d17f3b-c357-4404-a84c-c36737cd4474_1876x1100.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="MCP, the puppet master strings protocol" title="MCP, the puppet master strings protocol" srcset="https://substackcdn.com/image/fetch/$s_!U3wV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d17f3b-c357-4404-a84c-c36737cd4474_1876x1100.png 424w, https://substackcdn.com/image/fetch/$s_!U3wV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d17f3b-c357-4404-a84c-c36737cd4474_1876x1100.png 848w, https://substackcdn.com/image/fetch/$s_!U3wV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d17f3b-c357-4404-a84c-c36737cd4474_1876x1100.png 1272w, https://substackcdn.com/image/fetch/$s_!U3wV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d17f3b-c357-4404-a84c-c36737cd4474_1876x1100.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Before MCP, connecting an AI to 10 different tools (GitHub, Slack, databases, APIs) meant writing 10 different integrations. And if you wanted 5 different AI applications to use those same 10 tools, you&#8217;d need 50 separate integrations. MCP solves this N&#215;M problem by providing one standardized way for AIs to talk to tools.</p><h2>What Problem Does MCP Solve?</h2><p>The AI integration landscape before MCP looked like this:</p><p><strong>The Fragmentation Problem:</strong></p><ul><li><p>Every AI application needed custom code to integrate with each tool</p></li><li><p>Developers wrote the same integration logic repeatedly for different AI platforms</p></li><li><p>Tools had to provide separate SDKs and APIs for each AI application</p></li><li><p>No standard way to describe what a tool could do or how to use it</p></li><li><p>Switching tools or AI providers meant rewriting everything</p></li></ul><p><strong>Real World Impact:</strong></p><ul><li><p>A company using Claude, ChatGPT, and a custom AI agent would need three separate integrations for each tool (like GitHub, Slack, or their database)</p></li><li><p>Adding a new data source required updating every AI application individually</p></li><li><p>Tool developers couldn&#8217;t build once and support all AI platforms</p></li><li><p>Security, permissions, and error handling were inconsistent across integrations</p></li></ul><p>MCP eliminates this by creating a single protocol that both AI applications and tools can implement once and use everywhere.</p><h2>How MCP Solves the Problem</h2><p>Think of the system like a puppet master controlling multiple puppets. Here&#8217;s how the strings connect:</p><p><strong>The Puppets (Third-Party Tools):</strong></p><ul><li><p>Each puppet is a tool like GitHub, Slack, PostgreSQL, or Google Drive</p></li><li><p>The puppet needs attachment points where strings can connect</p></li><li><p>These attachment points are the MCP Server implementation</p></li></ul><p><strong>The Puppet Master (AI + MCP):</strong></p><ul><li><p>The puppet master is the combination of the AI model and its MCP Client</p></li><li><p>The strings are the JSON-RPC messages flowing over a transport layer</p></li><li><p>The puppet master needs to know what strings connect to which parts of each puppet</p></li></ul><p><strong>The Strings (The Protocol):</strong> This is where we get into the HOW. The strings aren&#8217;t magical, they&#8217;re made of three distinct layers:</p><ol><li><p><strong>Transport Layer</strong> (The Physical String)</p><ul><li><p>How the messages physically travel</p></li><li><p>Local puppets: STDIO (standard input/output streams)</p></li><li><p>Remote puppets: HTTP with Server-Sent Events (SSE)</p></li></ul></li><li><p><strong>Message Format Layer</strong> (What&#8217;s Written on the String)</p><ul><li><p>All messages use JSON-RPC 2.0 format</p></li><li><p>Provides structure for requests, responses, and notifications</p></li><li><p>Ensures every message can be understood by both sides</p></li></ul></li><li><p><strong>Protocol Layer</strong> (The Commands on the String)</p><ul><li><p>Defines specific MCP methods like <code>tools/list</code>, <code>tools/call</code>, <code>resources/read</code></p></li><li><p>Describes capabilities, permissions, and data formats</p></li><li><p>Handles initialization, discovery, and execution</p></li></ul></li></ol><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>The Technical Deep Dive: How the Strings Actually Work</h2><p>Now let&#8217;s explain exactly how the puppet master pulls the strings.</p><h3>Phase 1: Attaching the Strings (Initialization)</h3><p>When you want to use an MCP server, the AI application (MCP Client) first needs to establish a connection. Here&#8217;s the exact sequence:</p><p><strong>Step 1: Transport Connection</strong></p><p>For a local tool using STDIO:</p><pre><code><code>AI Application spawns the MCP server as a child process
Server process: node github_mcp_server.js
Communication channels: stdin/stdout pipes connect AI &#8596; Server
</code></code></pre><p>For a remote tool using HTTP:</p><pre><code><code>AI Application connects to: https://api.example.com/mcp
Opens persistent connection for Server-Sent Events
Communication channels: HTTP POST for requests, SSE stream for responses
</code></code></pre><p><strong>Step 2: The Handshake (Initialize Request)</strong></p><p>The AI sends the first message over the connected transport:</p><pre><code><code>{
  &#8220;jsonrpc&#8221;: &#8220;2.0&#8221;,
  &#8220;id&#8221;: 1,
  &#8220;method&#8221;: &#8220;initialize&#8221;,
  &#8220;params&#8221;: {
    &#8220;protocolVersion&#8221;: &#8220;2024-11-05&#8221;,
    &#8220;capabilities&#8221;: {
      &#8220;roots&#8221;: { &#8220;listChanged&#8221;: true },
      &#8220;sampling&#8221;: {}
    },
    &#8220;clientInfo&#8221;: {
      &#8220;name&#8221;: &#8220;Claude Desktop&#8221;,
      &#8220;version&#8221;: &#8220;1.0.0&#8221;
    }
  }
}
</code></code></pre><p>This message says: &#8220;Hello, I&#8217;m Claude Desktop version 1.0.0, I speak MCP protocol version 2024-11-05, and here&#8217;s what I can do (my capabilities).&#8221;</p><p><strong>Step 3: The Response (Initialize Response)</strong></p><p>The MCP Server responds:</p><pre><code><code>{
  &#8220;jsonrpc&#8221;: &#8220;2.0&#8221;,
  &#8220;id&#8221;: 1,
  &#8220;result&#8221;: {
    &#8220;protocolVersion&#8221;: &#8220;2024-11-05&#8221;,
    &#8220;capabilities&#8221;: {
      &#8220;tools&#8221;: {},
      &#8220;resources&#8221;: {},
      &#8220;prompts&#8221;: {}
    },
    &#8220;serverInfo&#8221;: {
      &#8220;name&#8221;: &#8220;GitHub MCP Server&#8221;,
      &#8220;version&#8221;: &#8220;1.2.0&#8221;
    }
  }
}
</code></code></pre><p>This says: &#8220;Hello, I&#8217;m the GitHub MCP Server version 1.2.0, I also speak protocol version 2024-11-05, and I can provide tools, resources, and prompts.&#8221;</p><p><strong>Step 4: Initialization Complete</strong></p><p>The AI sends a notification (no response needed):</p><pre><code><code>{
  &#8220;jsonrpc&#8221;: &#8220;2.0&#8221;,
  &#8220;method&#8221;: &#8220;notifications/initialized&#8221;
}
</code></code></pre><p>The strings are now attached. The connection is live.</p><h3>Phase 2: Discovering the Puppet&#8217;s Joints (Capability Discovery)</h3><p><strong>This is one of the most powerful aspects of MCP.</strong> Instead of hardcoding what each tool can do, the AI dynamically discovers capabilities at runtime. This means new tools can be added without changing the AI&#8217;s code, and tools can update their capabilities without breaking existing integrations.</p><p>Now the puppet master needs to learn what this puppet can do. This is where the magic starts to become clear.</p><p><strong>Step 1: Asking &#8220;What Tools Do You Have?&#8221;</strong></p><p>The AI sends:</p><pre><code><code>{
  &#8220;jsonrpc&#8221;: &#8220;2.0&#8221;,
  &#8220;id&#8221;: 2,
  &#8220;method&#8221;: &#8220;tools/list&#8221;
}
</code></code></pre><p><strong>Step 2: The Server Lists Its Tools</strong></p><p>The GitHub MCP Server responds:</p><pre><code><code>{
  &#8220;jsonrpc&#8221;: &#8220;2.0&#8221;,
  &#8220;id&#8221;: 2,
  &#8220;result&#8221;: {
    &#8220;tools&#8221;: [
      {
        &#8220;name&#8221;: &#8220;create_issue&#8221;,
        &#8220;description&#8221;: &#8220;Creates a new GitHub issue in a repository&#8221;,
        &#8220;inputSchema&#8221;: {
          &#8220;type&#8221;: &#8220;object&#8221;,
          &#8220;properties&#8221;: {
            &#8220;repository&#8221;: {
              &#8220;type&#8221;: &#8220;string&#8221;,
              &#8220;description&#8221;: &#8220;Repository name in format &#8216;owner/repo&#8217;&#8221;
            },
            &#8220;title&#8221;: {
              &#8220;type&#8221;: &#8220;string&#8221;,
              &#8220;description&#8221;: &#8220;Issue title&#8221;
            },
            &#8220;body&#8221;: {
              &#8220;type&#8221;: &#8220;string&#8221;,
              &#8220;description&#8221;: &#8220;Issue description&#8221;
            }
          },
          &#8220;required&#8221;: [&#8221;repository&#8221;, &#8220;title&#8221;]
        }
      },
      {
        &#8220;name&#8221;: &#8220;list_issues&#8221;,
        &#8220;description&#8221;: &#8220;Lists issues from a GitHub repository&#8221;,
        &#8220;inputSchema&#8221;: {
          &#8220;type&#8221;: &#8220;object&#8221;,
          &#8220;properties&#8221;: {
            &#8220;repository&#8221;: {&#8221;type&#8221;: &#8220;string&#8221;},
            &#8220;state&#8221;: {
              &#8220;type&#8221;: &#8220;string&#8221;,
              &#8220;enum&#8221;: [&#8221;open&#8221;, &#8220;closed&#8221;, &#8220;all&#8221;]
            }
          },
          &#8220;required&#8221;: [&#8221;repository&#8221;]
        }
      }
    ]
  }
}
</code></code></pre><p>This response tells the AI: &#8220;I have two tools. The first one is called <code>create_issue</code> and it needs a repository name and title (and optionally a body). The second one is <code>list_issues</code> and it needs a repository and optional state.&#8221;</p><p>The AI now knows exactly what strings it can pull and what information each string pull requires.</p><p><strong>Step 3: Discovering Resources</strong></p><p>Similarly, the AI can ask about available data:</p><pre><code><code>{
  &#8220;jsonrpc&#8221;: &#8220;2.0&#8221;,
  &#8220;id&#8221;: 3,
  &#8220;method&#8221;: &#8220;resources/list&#8221;
}
</code></code></pre><p>Response:</p><pre><code><code>{
  &#8220;jsonrpc&#8221;: &#8220;2.0&#8221;,
  &#8220;id&#8221;: 3,
  &#8220;result&#8221;: {
    &#8220;resources&#8221;: [
      {
        &#8220;uri&#8221;: &#8220;github://repo/user/myproject&#8221;,
        &#8220;name&#8221;: &#8220;My Project Repository&#8221;,
        &#8220;description&#8221;: &#8220;Main project repository information&#8221;,
        &#8220;mimeType&#8221;: &#8220;application/json&#8221;
      }
    ]
  }
}
</code></code></pre><h3>Phase 3: Pulling the Strings (Executing Actions)</h3><p>This is where the puppet master actually makes the puppet move. Let&#8217;s trace a complete action from user request to execution.</p><p><strong>User Says:</strong> &#8220;Create a GitHub issue titled &#8216;Fix login bug&#8217; in the auth-service repository&#8221;</p><p><strong>Step 1: AI Decides to Use a Tool</strong></p><p>The AI model (Claude) processes the request and determines it needs to use the <code>create_issue</code> tool. It constructs the appropriate parameters and sends:</p><pre><code><code>{
  &#8220;jsonrpc&#8221;: &#8220;2.0&#8221;,
  &#8220;id&#8221;: 4,
  &#8220;method&#8221;: &#8220;tools/call&#8221;,
  &#8220;params&#8221;: {
    &#8220;name&#8221;: &#8220;create_issue&#8221;,
    &#8220;arguments&#8221;: {
      &#8220;repository&#8221;: &#8220;mycompany/auth-service&#8221;,
      &#8220;title&#8221;: &#8220;Fix login bug&#8221;,
      &#8220;body&#8221;: &#8220;Users are experiencing login failures. Need to investigate authentication flow.&#8221;
    }
  }
}
</code></code></pre><p>This message travels over the transport (STDIO or HTTP) as a JSON string.</p><p><strong>Step 2: MCP Server Receives and Routes</strong></p><p>The GitHub MCP Server:</p><ol><li><p>Receives the JSON-RPC message on its transport layer</p></li><li><p>Parses the JSON and validates the structure</p></li><li><p>Checks that the requested tool (<code>create_issue</code>) exists</p></li><li><p>Validates the arguments against the tool&#8217;s input schema</p></li><li><p>Routes to the actual tool implementation code</p></li></ol><p><strong>Step 3: MCP Server Translates to Third-Party API</strong></p><p>Here&#8217;s the crucial part that&#8217;s often glossed over. The MCP Server now translates this standardized MCP request into the specific API call the third-party service expects:</p><pre><code><code>// Inside the GitHub MCP Server implementation
async function handleCreateIssue(args) {
  // Translate MCP request to GitHub API format
  const githubApiRequest = {
    title: args.title,
    body: args.body,
    labels: []
  };
  
  // Make actual HTTP call to GitHub&#8217;s REST API
  const response = await fetch(
    `https://api.github.com/repos/${args.repository}/issues`,
    {
      method: &#8216;POST&#8217;,
      headers: {
        &#8216;Authorization&#8217;: `Bearer ${process.env.GITHUB_TOKEN}`,
        &#8216;Content-Type&#8217;: &#8216;application/json&#8217;,
        &#8216;Accept&#8217;: &#8216;application/vnd.github.v3+json&#8217;
      },
      body: JSON.stringify(githubApiRequest)
    }
  );
  
  const issue = await response.json();
  
  // Translate GitHub response back to MCP format
  return {
    issueNumber: issue.number,
    url: issue.html_url,
    state: issue.state
  };
}
</code></code></pre><p>This is THE critical translation layer. The MCP Server is a wrapper that:</p><ul><li><p>Takes standardized MCP requests</p></li><li><p>Translates them to service-specific API calls</p></li><li><p>Handles authentication (using stored tokens/credentials)</p></li><li><p>Makes the actual API call to GitHub</p></li><li><p>Translates the response back to MCP format</p></li></ul><p><strong>Step 4: MCP Server Responds</strong></p><p>After GitHub&#8217;s API returns success, the MCP Server sends back:</p><pre><code><code>{
  &#8220;jsonrpc&#8221;: &#8220;2.0&#8221;,
  &#8220;id&#8221;: 4,
  &#8220;result&#8221;: {
    &#8220;content&#8221;: [
      {
        &#8220;type&#8221;: &#8220;text&#8221;,
        &#8220;text&#8221;: &#8220;Successfully created issue #127 in mycompany/auth-service&#8221;
      }
    ],
    &#8220;isError&#8221;: false
  }
}
</code></code></pre><p><strong>Step 5: AI Incorporates Result</strong></p><p>The AI receives this response and uses it to formulate the final answer to the user:</p><p>&#8220;I&#8217;ve created issue #127 in the auth-service repository with the title &#8216;Fix login bug&#8217;. You can view it at: https://github.com/mycompany/auth-service/issues/127&#8221;</p><h3>The Complete Data Flow Diagram</h3><pre><code><code>User Request
    &#8595;
[AI Model - Claude]
    &#8595; (decides which tool to call)
[MCP Client in Host App]
    &#8595; (formats JSON-RPC message)
[Transport Layer - STDIO or HTTP]
    &#8595; (sends JSON string)
[MCP Server - GitHub Wrapper]
    &#8595; (receives &amp; parses JSON-RPC)
    &#8595; (validates request)
    &#8595; (translates to GitHub API format)
[GitHub REST API]
    &#8595; (processes request)
    &#8595; (returns GitHub response)
[MCP Server]
    &#8595; (translates response to MCP format)
    &#8595; (formats JSON-RPC response)
[Transport Layer]
    &#8595; (sends JSON string back)
[MCP Client]
    &#8595; (parses response)
[AI Model]
    &#8595; (incorporates result into context)
User Response
</code></code></pre><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>A Complete Working Example: Weather Tool with Claude</h2><p>Let&#8217;s build a simple but complete MCP server and show exactly how Claude interfaces with it.</p><h3>Building the MCP Server</h3><p><strong>1. Server Implementation (weather_server.js)</strong></p><pre><code><code>import { Server } from &#8220;@modelcontextprotocol/sdk/server/index.js&#8221;;
import { StdioServerTransport } from &#8220;@modelcontextprotocol/sdk/server/stdio.js&#8221;;

// Create the MCP server instance
const server = new Server(
  {
    name: &#8220;weather-server&#8221;,
    version: &#8220;1.0.0&#8221;,
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

// Define the weather tool
server.setRequestHandler(&#8221;tools/list&#8221;, async () =&gt; {
  return {
    tools: [
      {
        name: &#8220;get_weather&#8221;,
        description: &#8220;Gets current weather for a city&#8221;,
        inputSchema: {
          type: &#8220;object&#8221;,
          properties: {
            city: {
              type: &#8220;string&#8221;,
              description: &#8220;City name&#8221;,
            },
            units: {
              type: &#8220;string&#8221;,
              enum: [&#8221;celsius&#8221;, &#8220;fahrenheit&#8221;],
              description: &#8220;Temperature units&#8221;,
            },
          },
          required: [&#8221;city&#8221;],
        },
      },
    ],
  };
});

// Handle tool execution
server.setRequestHandler(&#8221;tools/call&#8221;, async (request) =&gt; {
  if (request.params.name === &#8220;get_weather&#8221;) {
    const { city, units = &#8220;celsius&#8221; } = request.params.arguments;
    
    // Simulate weather API call
    // In real implementation, this would call OpenWeatherMap, etc.
    const weatherData = await fetchWeatherFromAPI(city);
    
    const temp = units === &#8220;celsius&#8221; 
      ? weatherData.temp_c 
      : weatherData.temp_f;
    
    return {
      content: [
        {
          type: &#8220;text&#8221;,
          text: `Weather in ${city}: ${temp}&#176;${units === &#8220;celsius&#8221; ? &#8220;C&#8221; : &#8220;F&#8221;}, ${weatherData.condition}`,
        },
      ],
    };
  }
  
  throw new Error(`Unknown tool: ${request.params.name}`);
});

// Simulated API call
async function fetchWeatherFromAPI(city) {
  // In real implementation, this makes HTTP request to weather service
  // For demo, we return mock data
  return {
    temp_c: 22,
    temp_f: 72,
    condition: &#8220;Partly cloudy&#8221;,
  };
}

// Start the server with STDIO transport
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error(&#8221;Weather MCP server running on stdio&#8221;);
}

main().catch(console.error);
</code></code></pre><p><strong>2. Connecting to Claude Desktop</strong></p><p>Edit Claude Desktop configuration file:</p><p><strong>On macOS:</strong> <code>~/Library/Application Support/Claude/claude_desktop_config.json</code> <strong>On Windows:</strong> <code>%APPDATA%\Claude\claude_desktop_config.json</code></p><pre><code><code>{
  &#8220;mcpServers&#8221;: {
    &#8220;weather&#8221;: {
      &#8220;command&#8221;: &#8220;node&#8221;,
      &#8220;args&#8221;: [&#8221;/path/to/weather_server.js&#8221;]
    }
  }
}
</code></code></pre><h3>How Claude Interfaces with the MCP Server</h3><p><strong>Step-by-Step Execution:</strong></p><p><strong>1. Claude Desktop Startup</strong></p><p>When Claude Desktop launches:</p><pre><code><code>// Inside Claude Desktop&#8217;s MCP Client code
const weatherClient = new MCPClient();
const transport = new StdioClientTransport({
  command: &#8220;node&#8221;,
  args: [&#8221;/path/to/weather_server.js&#8221;]
});

// Spawns: node /path/to/weather_server.js
// Creates stdin/stdout pipes for communication
await weatherClient.connect(transport);
</code></code></pre><p><strong>2. Initialization Handshake</strong></p><p>Claude sends over stdin:</p><pre><code><code>{&#8221;jsonrpc&#8221;:&#8221;2.0&#8221;,&#8221;id&#8221;:1,&#8221;method&#8221;:&#8221;initialize&#8221;,&#8221;params&#8221;:{&#8221;protocolVersion&#8221;:&#8221;2024-11-05&#8221;,&#8221;capabilities&#8221;:{},&#8221;clientInfo&#8221;:{&#8221;name&#8221;:&#8221;Claude Desktop&#8221;,&#8221;version&#8221;:&#8221;1.0.0&#8221;}}}
</code></code></pre><p>Server responds over stdout:</p><pre><code><code>{&#8221;jsonrpc&#8221;:&#8221;2.0&#8221;,&#8221;id&#8221;:1,&#8221;result&#8221;:{&#8221;protocolVersion&#8221;:&#8221;2024-11-05&#8221;,&#8221;capabilities&#8221;:{&#8221;tools&#8221;:{}},&#8221;serverInfo&#8221;:{&#8221;name&#8221;:&#8221;weather-server&#8221;,&#8221;version&#8221;:&#8221;1.0.0&#8221;}}}
</code></code></pre><p><strong>3. Tool Discovery</strong></p><p>Claude sends:</p><pre><code><code>{&#8221;jsonrpc&#8221;:&#8221;2.0&#8221;,&#8221;id&#8221;:2,&#8221;method&#8221;:&#8221;tools/list&#8221;}
</code></code></pre><p>Server responds:</p><pre><code><code>{&#8221;jsonrpc&#8221;:&#8221;2.0&#8221;,&#8221;id&#8221;:2,&#8221;result&#8221;:{&#8221;tools&#8221;:[{&#8221;name&#8221;:&#8221;get_weather&#8221;,&#8221;description&#8221;:&#8221;Gets current weather for a city&#8221;,&#8221;inputSchema&#8221;:{&#8221;type&#8221;:&#8221;object&#8221;,&#8221;properties&#8221;:{&#8221;city&#8221;:{&#8221;type&#8221;:&#8221;string&#8221;,&#8221;description&#8221;:&#8221;City name&#8221;},&#8221;units&#8221;:{&#8221;type&#8221;:&#8221;string&#8221;,&#8221;enum&#8221;:[&#8221;celsius&#8221;,&#8221;fahrenheit&#8221;],&#8221;description&#8221;:&#8221;Temperature units&#8221;}},&#8221;required&#8221;:[&#8221;city&#8221;]}}]}}
</code></code></pre><p>Claude now knows: &#8220;I have access to a tool called <code>get_weather</code> that needs a city and optional units.&#8221;</p><p><strong>4. User Interaction</strong></p><p>User types: &#8220;What&#8217;s the weather in Paris?&#8221;</p><p>Claude&#8217;s internal processing:</p><ol><li><p>Analyzes the user query</p></li><li><p>Recognizes this requires weather information</p></li><li><p>Checks available tools</p></li><li><p>Finds <code>get_weather</code> tool matches the need</p></li><li><p>Extracts parameters: city = &#8220;Paris&#8221;</p></li><li><p>Decides to call the tool</p></li></ol><p><strong>5. Tool Execution</strong></p><p>Claude sends over stdin:</p><pre><code><code>{&#8221;jsonrpc&#8221;:&#8221;2.0&#8221;,&#8221;id&#8221;:3,&#8221;method&#8221;:&#8221;tools/call&#8221;,&#8221;params&#8221;:{&#8221;name&#8221;:&#8221;get_weather&#8221;,&#8221;arguments&#8221;:{&#8221;city&#8221;:&#8221;Paris&#8221;,&#8221;units&#8221;:&#8221;celsius&#8221;}}}
</code></code></pre><p>This JSON string travels through the stdin pipe to the server process.</p><p><strong>6. Server Processing</strong></p><p>The weather_server.js:</p><ol><li><p>Receives the JSON string from stdin</p></li><li><p>Parses it: <code>JSON.parse(message)</code></p></li><li><p>Recognizes <code>method: &#8220;tools/call&#8221;</code></p></li><li><p>Routes to the tools/call handler</p></li><li><p>Extracts tool name: <code>get_weather</code></p></li><li><p>Validates arguments against schema</p></li><li><p>Executes the tool function</p></li><li><p>Calls <code>fetchWeatherFromAPI(&#8221;Paris&#8221;)</code></p></li><li><p>Formats the response</p></li></ol><p><strong>7. Server Response</strong></p><p>Server sends over stdout:</p><pre><code><code>{&#8221;jsonrpc&#8221;:&#8221;2.0&#8221;,&#8221;id&#8221;:3,&#8221;result&#8221;:{&#8221;content&#8221;:[{&#8221;type&#8221;:&#8221;text&#8221;,&#8221;text&#8221;:&#8221;Weather in Paris: 22&#176;C, Partly cloudy&#8221;}]}}
</code></code></pre><p><strong>8. Claude&#8217;s Final Response</strong></p><p>Claude receives the response, incorporates it into its context, and responds to the user:</p><p>&#8220;The weather in Paris is currently 22&#176;C and partly cloudy.&#8221;</p><h3>How MCP Communicates with Third-Party Services</h3><p>The critical piece that makes MCP work is that the <strong>MCP Server acts as a translation layer</strong>. Here&#8217;s the exact flow:</p><pre><code><code>Claude (MCP Client)
    &#8595;
Sends standardized MCP request:
{method: &#8220;tools/call&#8221;, params: {name: &#8220;get_weather&#8221;, arguments: {city: &#8220;Paris&#8221;}}}
    &#8595;
MCP Server receives this
    &#8595;
MCP Server translates to third-party API format:
fetch(&#8217;https://api.openweathermap.org/data/2.5/weather?q=Paris&amp;appid=KEY&#8217;)
    &#8595;
Third-party API (OpenWeatherMap) returns:
{temp: 295.15, weather: [{description: &#8220;partly cloudy&#8221;}]}
    &#8595;
MCP Server translates response back to MCP format:
{content: [{type: &#8220;text&#8221;, text: &#8220;Weather in Paris: 22&#176;C, Partly cloudy&#8221;}]}
    &#8595;
Claude receives standardized MCP response
</code></code></pre><p><strong>The Power of This Design:</strong></p><ol><li><p><strong>Claude never needs to know about OpenWeatherMap&#8217;s API</strong></p><ul><li><p>Doesn&#8217;t need their API key format</p></li><li><p>Doesn&#8217;t need to know their endpoints</p></li><li><p>Doesn&#8217;t need to parse their response format</p></li></ul></li><li><p><strong>The MCP Server handles all service-specific details</strong></p><ul><li><p>Stores the API key securely</p></li><li><p>Knows the exact endpoint URLs</p></li><li><p>Handles authentication headers</p></li><li><p>Translates data formats both ways</p></li><li><p>Manages rate limiting</p></li><li><p>Handles errors gracefully</p></li></ul></li><li><p><strong>Switching weather providers is easy</strong></p><ul><li><p>Update only the MCP Server code</p></li><li><p>Claude&#8217;s interface stays identical</p></li><li><p>Change from OpenWeatherMap to WeatherAPI</p></li><li><p>Claude still calls <code>get_weather</code> the same way</p></li></ul></li></ol><h2>The Transport Layer: How the Strings Actually Connect</h2><h3>STDIO (Local Integrations)</h3><p>For tools running on the same machine as the AI:</p><p><strong>How it works:</strong></p><pre><code><code>// Claude spawns a child process
const serverProcess = spawn(&#8217;node&#8217;, [&#8217;weather_server.js&#8217;]);

// Sets up communication pipes
serverProcess.stdin.write(jsonRpcRequest);  // Send request
serverProcess.stdout.on(&#8217;data&#8217;, (data) =&gt; {  // Receive response
  const response = JSON.parse(data);
  handleResponse(response);
});
</code></code></pre><p><strong>Why STDIO?</strong></p><ul><li><p>Simple: uses standard input/output streams</p></li><li><p>Fast: no network overhead</p></li><li><p>Secure: no network exposure</p></li><li><p>Works perfectly for local tools</p></li></ul><p><strong>Data Flow:</strong></p><pre><code><code>[Claude Process]                [Weather Server Process]
     stdin &#8592;&#8594; stdout                  stdin &#8592;&#8594; stdout
        &#8595;                                  &#8593;
    Writes JSON to server&#8217;s stdin          |
        &#8595;                                  |
    Server reads from its stdin            |
        &#8595;                                  |
    Server processes request               |
        &#8595;                                  |
    Server writes JSON to its stdout -------
        &#8595;
    Claude reads from server&#8217;s stdout
</code></code></pre><h3>HTTP with Server-Sent Events (Remote Integrations)</h3><p>For tools running on remote servers:</p><p><strong>How it works:</strong></p><p><strong>Request Phase (HTTP POST):</strong></p><pre><code><code>// Claude makes HTTP POST request
const response = await fetch(&#8217;https://api.example.com/mcp&#8217;, {
  method: &#8216;POST&#8217;,
  headers: {
    &#8216;Content-Type&#8217;: &#8216;application/json&#8217;,
    &#8216;Mcp-Session-Id&#8217;: sessionId
  },
  body: JSON.stringify({
    jsonrpc: &#8220;2.0&#8221;,
    id: 3,
    method: &#8220;tools/call&#8221;,
    params: {name: &#8220;get_weather&#8221;, arguments: {city: &#8220;Paris&#8221;}}
  })
});
</code></code></pre><p><strong>Response Phase (Server-Sent Events):</strong></p><pre><code><code>// Server can stream responses back
res.setHeader(&#8217;Content-Type&#8217;, &#8216;text/event-stream&#8217;);
res.write(&#8217;data: {&#8221;jsonrpc&#8221;:&#8221;2.0&#8221;,&#8221;id&#8221;:3,&#8221;result&#8221;:{...}}\n\n&#8217;);
</code></code></pre><p><strong>Why HTTP + SSE?</strong></p><ul><li><p>Works across networks</p></li><li><p>SSE allows server-initiated messages</p></li><li><p>Handles long-running operations</p></li><li><p>Supports progress updates</p></li><li><p>Can maintain session state</p></li></ul><p><strong>Data Flow:</strong></p><pre><code><code>[Claude - Browser/Desktop]          [MCP Server - Cloud]
         &#8595;
    HTTP POST request to /mcp
    (contains JSON-RPC message)
         &#8595;
    [Server receives, processes]
         &#8595;
    HTTP Response or SSE stream
    (contains JSON-RPC response)
         &#8595;
    Claude processes response
</code></code></pre><h3>Session Management</h3><p>For stateful interactions:</p><pre><code><code>First Request:
Claude &#8594; Server: {&#8221;jsonrpc&#8221;:&#8221;2.0&#8221;,&#8221;id&#8221;:1,&#8221;method&#8221;:&#8221;initialize&#8221;,...}
Server &#8594; Claude: HTTP 200, Header: &#8220;Mcp-Session-Id: abc123&#8221;

Subsequent Requests:
Claude &#8594; Server: Header: &#8220;Mcp-Session-Id: abc123&#8221;, {&#8221;jsonrpc&#8221;:&#8221;2.0&#8221;,...}
Server: Recognizes session, maintains context
</code></code></pre><h2>Security and Authentication</h2><p>An often overlooked aspect of &#8220;how the puppet master controls the puppet&#8221; is security. Here&#8217;s how it works:</p><h3>Authentication Flow</h3><p><strong>For Remote Servers:</strong></p><ol><li><p><strong>OAuth 2.1 Flow</strong> (most common):</p></li></ol><pre><code><code>User &#8594; Claude: &#8220;Connect to my Notion workspace&#8221;
    &#8595;
Claude &#8594; Notion MCP Server: Initiates OAuth
    &#8595;
Notion MCP Server &#8594; Notion: Redirects user to Notion login
    &#8595;
User authenticates with Notion directly
    &#8595;
Notion &#8594; MCP Server: Returns authorization code
    &#8595;
MCP Server &#8594; Notion: Exchanges code for access token
    &#8595;
MCP Server stores token securely
    &#8595;
Future tool calls include: Authorization: Bearer {access_token}
</code></code></pre><ol start="2"><li><p><strong>API Key Authentication:</strong></p></li></ol><pre><code><code>// In MCP Server environment variables
process.env.GITHUB_TOKEN = &#8220;ghp_abc123xyz...&#8221;

// When making API calls
fetch(&#8217;https://api.github.com/repos/...&#8217;, {
  headers: {
    &#8216;Authorization&#8217;: `Bearer ${process.env.GITHUB_TOKEN}`
  }
});
</code></code></pre><p><strong>Critical Security Point:</strong></p><ul><li><p>Claude NEVER sees the API keys or access tokens</p></li><li><p>MCP Server handles all authentication</p></li><li><p>Claude sends standardized requests</p></li><li><p>MCP Server adds authentication before calling third-party API</p></li></ul><h3>Permission and Approval System</h3><p>MCP includes a built-in approval mechanism:</p><pre><code><code>// Server marks tool as requiring approval
{
  name: &#8220;delete_repository&#8221;,
  description: &#8220;Permanently deletes a GitHub repository&#8221;,
  dangerous: true,
  requiresApproval: true
}

// When Claude tries to call this:
Claude &#8594; Server: {method: &#8220;tools/call&#8221;, params: {name: &#8220;delete_repository&#8221;}}
    &#8595;
Server &#8594; Claude: {requiresApproval: true, toolName: &#8220;delete_repository&#8221;}
    &#8595;
Claude &#8594; User: &#8220;The AI wants to delete a repository. Approve?&#8221;
    &#8595;
User clicks &#8220;Approve&#8221;
    &#8595;
Claude &#8594; Server: {method: &#8220;tools/call&#8221;, approved: true, ...}
    &#8595;
Server executes the action
</code></code></pre><h2>Error Handling: When Strings Break</h2><p>Here&#8217;s how MCP handles errors at each layer:</p><h3>Transport Layer Errors</h3><pre><code><code>// Connection fails
Server process crashes
    &#8595;
Claude detects broken pipe on stdin/stdout
    &#8595;
Claude shows user: &#8220;Weather server disconnected&#8221;
    &#8595;
Attempts reconnection or marks tool unavailable
</code></code></pre><h3>Protocol Layer Errors</h3><pre><code><code>// Invalid JSON-RPC message
Request: {&#8221;method&#8221;: &#8220;tools/call&#8221;}  // Missing required &#8216;id&#8217;
    &#8595;
Response: {
  &#8220;jsonrpc&#8221;: &#8220;2.0&#8221;,
  &#8220;id&#8221;: null,
  &#8220;error&#8221;: {
    &#8220;code&#8221;: -32600,
    &#8220;message&#8221;: &#8220;Invalid Request: missing id field&#8221;
  }
}
</code></code></pre><h3>Tool Execution Errors</h3><pre><code><code>// Tool fails during execution
Request: {method: &#8220;tools/call&#8221;, params: {name: &#8220;get_weather&#8221;, arguments: {city: &#8220;InvalidCity&#8221;}}}
    &#8595;
Response: {
  &#8220;jsonrpc&#8221;: &#8220;2.0&#8221;,
  &#8220;id&#8221;: 5,
  &#8220;result&#8221;: {
    &#8220;content&#8221;: [{
      &#8220;type&#8221;: &#8220;text&#8221;,
      &#8220;text&#8221;: &#8220;Error: City &#8216;InvalidCity&#8217; not found in weather database&#8221;
    }],
    &#8220;isError&#8221;: true
  }
}
</code></code></pre><p>Claude then tells the user: &#8220;I couldn&#8217;t find weather data for that city. Please check the spelling.&#8221;</p><h2>Understanding the Connection</h2><p>The &#8220;magic&#8221; of MCP isn&#8217;t magic at all. It&#8217;s a carefully designed protocol with three clear layers:</p><p><strong>1. Transport Layer:</strong> The physical connection (STDIO pipes or HTTP) <strong>2. Message Layer:</strong> JSON-RPC 2.0 format for structured communication<br><strong>3. Protocol Layer:</strong> Standardized MCP methods and data formats</p><p>The MCP Server is the crucial translator that:</p><ul><li><p>Speaks standardized MCP to the AI</p></li><li><p>Speaks service-specific APIs to the tool</p></li><li><p>Handles authentication and security</p></li><li><p>Translates data formats in both directions</p></li></ul><p>This separation of concerns is why MCP succeeds where custom integrations failed. The AI doesn&#8217;t need to know about every tool&#8217;s quirks, and tools don&#8217;t need to understand AI-specific formats. The MCP Server bridges the gap with a standard protocol that both sides can implement once and reuse everywhere.</p><p>The puppet master (AI + MCP Client) pulls strings (sends JSON-RPC messages over transport), which connect to the puppet&#8217;s joints (MCP Server translates to tool APIs), making the puppet move (tool executes action and returns result). Each layer has a specific job, and together they create the seamless integration that makes AI agents powerful and practical.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading IT Untold! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>Articles I enjoyed this week</h2><ul><li><p><a href="https://newsletter.francofernando.com/p/concurrency-and-parallelism">Concurrency and Parallelism</a> - <a href="https://substack.com/@francofernando">Franco Fernando</a></p></li><li><p><a href="https://newsletter.eng-leadership.com/p/how-to-stay-relevant-as-an-engineering">How to Stay Relevant as an Engineering Leader While Empowering Others</a> - <a href="https://substack.com/@gregorojstersek">Gregor Ojstersek</a>,  <a href="https://substack.com/@djordjemladenovic">Djordje Mladenovic</a></p></li></ul><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://ko-fi.com/rixlabs" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Cc4P!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3818867c-6a9d-4fd0-8136-22d158b9e3e0_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!Cc4P!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3818867c-6a9d-4fd0-8136-22d158b9e3e0_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!Cc4P!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3818867c-6a9d-4fd0-8136-22d158b9e3e0_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!Cc4P!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3818867c-6a9d-4fd0-8136-22d158b9e3e0_672x356.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Cc4P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3818867c-6a9d-4fd0-8136-22d158b9e3e0_672x356.webp" width="180" height="95.35714285714286" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3818867c-6a9d-4fd0-8136-22d158b9e3e0_672x356.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:356,&quot;width&quot;:672,&quot;resizeWidth&quot;:180,&quot;bytes&quot;:10010,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:&quot;https://ko-fi.com/rixlabs&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/174905055?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3818867c-6a9d-4fd0-8136-22d158b9e3e0_672x356.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Cc4P!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3818867c-6a9d-4fd0-8136-22d158b9e3e0_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!Cc4P!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3818867c-6a9d-4fd0-8136-22d158b9e3e0_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!Cc4P!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3818867c-6a9d-4fd0-8136-22d158b9e3e0_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!Cc4P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3818867c-6a9d-4fd0-8136-22d158b9e3e0_672x356.webp 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p>]]></content:encoded></item><item><title><![CDATA[Why I Can't Stop Digging]]></title><description><![CDATA[What happens when you need to build the tools that build the tools]]></description><link>https://ituntold.rixlabs.dev/p/why-i-cant-stop-digging</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/why-i-cant-stop-digging</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Mon, 15 Sep 2025 14:27:02 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!fUC_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67adaac8-4388-4fdd-931e-c4ca4eb57f27_1552x1422.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I studied engineering because I like to know how things work. Nowadays you hear "study it, you'll have a good career." At my time it was "study it, it's the future." Nobody was thinking about money and web development was at the beginning. I wanted to study audio engineering since I was playing guitar a lot at the time. My brother convinced me last second to enroll into IT as a backup that became the main option pretty soon.</p><p>This passion about understanding the HOW was a massive driver. In the audio field I wanted to know how amplifiers work and how I could obtain a certain sound. In IT, no matter the topic, I needed to go deeper. I need to understand algorithms. I need to fully understand how a web server works. Why a system needs a certain part.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fUC_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67adaac8-4388-4fdd-931e-c4ca4eb57f27_1552x1422.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fUC_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67adaac8-4388-4fdd-931e-c4ca4eb57f27_1552x1422.png 424w, https://substackcdn.com/image/fetch/$s_!fUC_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67adaac8-4388-4fdd-931e-c4ca4eb57f27_1552x1422.png 848w, https://substackcdn.com/image/fetch/$s_!fUC_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67adaac8-4388-4fdd-931e-c4ca4eb57f27_1552x1422.png 1272w, https://substackcdn.com/image/fetch/$s_!fUC_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67adaac8-4388-4fdd-931e-c4ca4eb57f27_1552x1422.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fUC_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67adaac8-4388-4fdd-931e-c4ca4eb57f27_1552x1422.png" width="1456" height="1334" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/67adaac8-4388-4fdd-931e-c4ca4eb57f27_1552x1422.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1334,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3007828,&quot;alt&quot;:&quot;Why I Can't Stop Digging&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/173664842?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67adaac8-4388-4fdd-931e-c4ca4eb57f27_1552x1422.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Why I Can't Stop Digging" title="Why I Can't Stop Digging" srcset="https://substackcdn.com/image/fetch/$s_!fUC_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67adaac8-4388-4fdd-931e-c4ca4eb57f27_1552x1422.png 424w, https://substackcdn.com/image/fetch/$s_!fUC_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67adaac8-4388-4fdd-931e-c4ca4eb57f27_1552x1422.png 848w, https://substackcdn.com/image/fetch/$s_!fUC_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67adaac8-4388-4fdd-931e-c4ca4eb57f27_1552x1422.png 1272w, https://substackcdn.com/image/fetch/$s_!fUC_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67adaac8-4388-4fdd-931e-c4ca4eb57f27_1552x1422.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>As a first Linux distribution I installed Gentoo with a uni colleague of mine. He was more experienced and enthusiastic about Linux and I was fascinated by the fact that Gentoo compiles all the packages with the legendary <code>emerge</code>. That I need to compile the kernel and know my hardware pretty well. Considering that it was 2006 the community was already amazing. The Gentoo documentation was the best around and it was translated in several languages already (at the time having the doc in Italian for me was a big plus). I loved the experience of that installation. It took me 1 week probably to have a usable machine. That was only one example.</p><p>Those years saw also the birth of Rails. How does the configuration work? How is this magic put together? What is a Rack server and all the middleware? Years later I re-did the same deep dive with Spring. I understand now that this need of mine to understand kept me away from some more abstract and complex concepts and algorithms. I was never a fast or particularly talented "coder" because if I don't understand the why and how immediately my brain will start grinding gears. Complex algorithms, ML stuff, and so on have always been tough for me. I know the concepts but cannot implement them confidently.</p><p>The will of understanding is still there. And that's why I want to go through the process of writing my own JVM-compatible programming language. It came to me like a random thought and the more I was thinking about it the more I remembered I was always fascinated by the concept. Some years ago a friend advised me to read "Ruby Under the Hood" by Pat Shaughnessy an amazing book going through every language feature. That book is a great inspiration for this project and I hope that I can manage to have some results. Another big inspiration is the amazing JRuby project by the great and powerful <a href="https://twitter.com/headius">Charles Oliver Nutter</a>. I will use AI to help me with explanations of the concepts but I will try to code on my own.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><h2>Finding My Language's Identity</h2><p>So here I am, starting this journey with the same curiosity that made me compile kernels in 2006. What kind of language do I actually want to create? The JVM already hosts dozens of languages. Kotlin brought null safety and conciseness. Scala merged functional and object-oriented paradigms. Clojure brought Lisp to the JVM. So what gap am I trying to fill with my language let's call it &#8220;rix&#8220;?</p><p>I needed to examine what I personally find frustrating in existing languages. Java's verbosity? Python's performance characteristics? JavaScript's... well, JavaScript-ness? After some reflection, I realized I wanted something that felt approachable like Ruby but could leverage the JVM's mature ecosystem and performance characteristics. Not revolutionary evolutionary.</p><p>The core question became: Should rix lean functional, object-oriented, or try to be everything to everyone? I've seen languages try to do everything and end up with confusing mental models. But I've also seen overly opinionated languages that feel restrictive. My answer: start with a functional lean but don't lock myself into a corner. Hybrid by design, functional by default.</p><h2>Syntax Philosophy: What Feels Right to My Brain?</h2><p>Here's where my need to understand everything deeply kicked in. I could go full Lisp with parentheses everywhere, or create something entirely novel. But why make developers learn completely new patterns when there are already elegant solutions?</p><p>Looking at Ruby's method definition syntax:</p><pre><code><code>def greet(name)
  "Hello, #{name}"
end
</code></code></pre><p>This feels <em>right</em> to me. No type annotations cluttering simple functions. No semicolons. The <code>def</code>/<code>end</code> blocks are clear without being verbose. It's what I reach for when sketching ideas on paper.</p><p>But wait does this work on the JVM? Ruby's dynamic nature seems at odds with Java's static typing. Here's where I had to dig deeper into how JRuby actually works, just like I did with Rails and Spring years ago. Turns out, you can absolutely start dynamic and add types later. The JVM's <code>Object</code> type can hold anything, and <code>invokedynamic</code> can handle method dispatch.</p><h2>The Type System Dilemma</h2><p>This led me to a crucial decision point that reminded me of my Gentoo days do I compile everything from source (static types from day one) or use a package manager approach (gradual typing)?</p><p><strong>Option A: Static from the start</strong></p><pre><code><code>def add(x: Int, y: Int): Int
  x + y
end
</code></code></pre><p><strong>Option B: Dynamic with optional types</strong></p><pre><code><code>def add(x, y)  # Start here
  x + y
end

# Later evolution:
def add(x: Int, y: Int): Int  # Add when needed
  x + y
end
</code></code></pre><p>I chose Option B. Why? Because I want to <em>use</em> this language while building it, just like I wanted a working desktop while learning Gentoo. Static typing is great, but it adds complexity to the compiler that I'm not ready to tackle in week one. Start simple, evolve incrementally. My brain needs to understand each layer before moving to the next.</p><h2>The Mutability Question</h2><p>Functional languages love immutability, but let's be honest about basic programming. My brain started grinding gears on this one:</p><pre><code><code>counter = 0
# How do I increment this if everything's immutable?
</code></code></pre><p>I found myself wrestling with purity versus practicality. Purely functional approaches are elegant but can be cognitive overhead for straightforward algorithms. And if I don't understand something immediately, I get stuck.</p><p>My compromise: <strong>mutable variables, immutable data structures by default</strong>.</p><pre><code><code># Variables can be reassigned (practical)
counter = 0
counter = counter + 1

# But lists don't mutate in place (functional flavor)
numbers = [1, 2, 3]
more_numbers = numbers.append(4)  # numbers unchanged
</code></code></pre><p>This gives me the best of both worlds: familiar control flow with functional data handling. I can understand and implement this without my brain grinding gears.</p><h2>Implementation Strategy: Learning by Building</h2><p>Now for the meta-question: How do I actually build this thing? This is where my engineering background kicks in.</p><p><strong>Parser Generation vs Hand-Written</strong>: I could write a recursive descent parser by hand for maximum control, but honestly? I want to iterate quickly on syntax, just like I needed that <code>emerge</code> command to quickly try different package configurations. ANTLR lets me modify grammar files and regenerate parsers instantly. Perfect for experimentation and learning.</p><p><strong>Bytecode Generation</strong>: The ASM library gives me direct control over JVM bytecode without javac's overhead. More work upfront, but I'll understand exactly what my language generates. This is the equivalent of compiling my own kernel more effort, but total understanding.</p><p><strong>Build System</strong>: Maven for now. Boring but reliable. Like choosing a stable Linux distribution after spending a week with Gentoo.</p><h2>What &#8220;rix&#8221; Looks Like (v0.1)</h2><p>After all this analysis, here's where I landed for the initial version:</p><pre><code><code># Simple function definition
def greet(name)
  "Hello, " + name
end

# Variables and basic types
age = 25
active = true
numbers = [1, 2, 3, 4]

# Control flow as expressions
status = if age &gt;= 18
  "adult"
else  
  "minor"
end

# Function calls
message = greet("World")
puts(message)
</code></code></pre><p>Clean, readable, familiar. Nothing groundbreaking, but a solid foundation to build on. Every piece of this I can understand and implement without getting lost in complexity.</p><h2>Next Steps</h2><p>With the basic syntax decided, it's time to make this real. That means diving into ANTLR grammar files and getting "Hello, World" to actually compile and run on the JVM. The journey from idea to working interpreter starts now, driven by the same curiosity that made me want to understand how amplifiers work and why Rails was so magical.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>Articles I enjoyed this week</h2><ul><li><p><a href="https://newsletter.optimistengineer.com/p/decoupling-your-monolithic-application">Decoupling Your Monolithic Application: A Practical Guide for Software Engineers</a> - <a href="https://substack.com/@optimistengineer">Marcos F. Lobo &#128507;&#129517;</a></p></li><li><p><a href="https://sketechnews.substack.com/p/rest-api-visual-guide">How 3 raw visuals teach you REST APIs, Linux Filesystems and SSO Instantly!</a> - <a href="https://substack.com/@sketech">Sketech | Unfiltered Dev Notes</a></p></li></ul><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://ko-fi.com/rixlabs" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Q4lP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e84ea0-2a37-475e-857d-9186511d785a_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!Q4lP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e84ea0-2a37-475e-857d-9186511d785a_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!Q4lP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e84ea0-2a37-475e-857d-9186511d785a_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!Q4lP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e84ea0-2a37-475e-857d-9186511d785a_672x356.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Q4lP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e84ea0-2a37-475e-857d-9186511d785a_672x356.webp" width="182" height="96.41666666666667" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c7e84ea0-2a37-475e-857d-9186511d785a_672x356.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:356,&quot;width&quot;:672,&quot;resizeWidth&quot;:182,&quot;bytes&quot;:10010,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:&quot;https://ko-fi.com/rixlabs&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/173664842?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e84ea0-2a37-475e-857d-9186511d785a_672x356.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Q4lP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e84ea0-2a37-475e-857d-9186511d785a_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!Q4lP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e84ea0-2a37-475e-857d-9186511d785a_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!Q4lP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e84ea0-2a37-475e-857d-9186511d785a_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!Q4lP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7e84ea0-2a37-475e-857d-9186511d785a_672x356.webp 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p>]]></content:encoded></item><item><title><![CDATA[Another kind of IT Untold]]></title><description><![CDATA[Why I Stopped Writing (And Why I'm Back)]]></description><link>https://ituntold.rixlabs.dev/p/another-kind-of-it-untold</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/another-kind-of-it-untold</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Sat, 06 Sep 2025 08:00:25 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!WKY0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d74ed8-d58d-4f3f-a4a6-563118d2195c_1350x1288.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>After several months of radio silence, I'm back at writing this newsletter. Let me tell you why I disappeared and, more importantly, what's coming next.</p><h2>Why I Disappeared</h2><p>Life got in the way, as it tends to do. I bought a house my first one and spent months renovating it from top to bottom. Between dealing with contractors, choosing tiles I'll probably regret in five years, and figuring out how rental agreements work when I decided to rent it out, my writing took a backseat.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WKY0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d74ed8-d58d-4f3f-a4a6-563118d2195c_1350x1288.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WKY0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d74ed8-d58d-4f3f-a4a6-563118d2195c_1350x1288.png 424w, https://substackcdn.com/image/fetch/$s_!WKY0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d74ed8-d58d-4f3f-a4a6-563118d2195c_1350x1288.png 848w, https://substackcdn.com/image/fetch/$s_!WKY0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d74ed8-d58d-4f3f-a4a6-563118d2195c_1350x1288.png 1272w, https://substackcdn.com/image/fetch/$s_!WKY0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d74ed8-d58d-4f3f-a4a6-563118d2195c_1350x1288.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WKY0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d74ed8-d58d-4f3f-a4a6-563118d2195c_1350x1288.png" width="1350" height="1288" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/50d74ed8-d58d-4f3f-a4a6-563118d2195c_1350x1288.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1288,&quot;width&quot;:1350,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2130866,&quot;alt&quot;:&quot;Why I Stopped Writing (And Why I'm Back)&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/172912267?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d74ed8-d58d-4f3f-a4a6-563118d2195c_1350x1288.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Why I Stopped Writing (And Why I'm Back)" title="Why I Stopped Writing (And Why I'm Back)" srcset="https://substackcdn.com/image/fetch/$s_!WKY0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d74ed8-d58d-4f3f-a4a6-563118d2195c_1350x1288.png 424w, https://substackcdn.com/image/fetch/$s_!WKY0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d74ed8-d58d-4f3f-a4a6-563118d2195c_1350x1288.png 848w, https://substackcdn.com/image/fetch/$s_!WKY0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d74ed8-d58d-4f3f-a4a6-563118d2195c_1350x1288.png 1272w, https://substackcdn.com/image/fetch/$s_!WKY0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d74ed8-d58d-4f3f-a4a6-563118d2195c_1350x1288.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Why I Stopped Writing (And Why I'm Back)</figcaption></figure></div><p></p><p>Summer didn't help. For once, I decided to actually enjoy the nice weather with my partner instead of being glued to my laptop. You know, doing all those things people say you should do but rarely make time for.</p><p>Then there's my new obsession with running. I enrolled in a marathon and I'm running like a maniac, especially on weekends. Turns out training for 42 kilometers takes up a surprising amount of mental bandwidth who knew?</p><p>But the real reason I stopped writing runs deeper than busy schedules and summer distractions.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><h2>The Content Problem</h2><p>I realized I don't want to and frankly, I can't keep writing my take on obvious, well-known, and thoroughly documented topics. No matter how entertaining I try to make it, a Pub/Sub pattern is always the same, and it's already explained in a million reputable places. No matter how much I want to showcase my knowledge, there are simply better resources out there for learning common patterns.</p><p>I cannot stand that kind of content anymore, and I sure as hell can't create it.</p><p>Most of my didactical content bored me to death. Looking back at what I've written both here and on X where I was trying to post consistently only the career-related pieces or the ones with practical examples actually interested me. I don't want to talk about stuff that bores me. I'm already struggling with liking my job and my field; I don't need to fuel the sensation that everything I do has lost its spark.</p><h2>A New Direction</h2><p>I'm writing again, but it's going to be different. Way more practical, way more interesting at least for me, and hopefully for you too. And don&#8217;t worry there will still be place for my rant about the industry and my draconian advice on career.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><p>I'll focus on practical guides and real advice. If I talk about architecture, it'll only be through concrete examples and only if I consider the topic worthy of your time, but mostly my time. I love writing and I still love discovering new things I just can't force myself into content I don't want to create because "that's my role."</p><p>I want to write about my personal passions in IT. My love for Linux, learning programming languages I'll never use at work, frameworks that caught my eye, tools that make my life easier. The stuff that actually gets me excited about technology again.</p><p>I want to go back to writing because the process is fun, and the content should be fun too. Not everything needs to be a comprehensive guide or a definitive resource. Sometimes it's enough to share what you're curious about, what you're tinkering with, what made you think "huh, that's interesting" while scrolling through GitHub at 2 AM.</p><p>This is my newsletter, after all. Time to make it actually mine.</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://ko-fi.com/rixlabs" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zZT3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4397ba51-83a7-4a08-b59f-e0d46b22c635_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!zZT3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4397ba51-83a7-4a08-b59f-e0d46b22c635_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!zZT3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4397ba51-83a7-4a08-b59f-e0d46b22c635_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!zZT3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4397ba51-83a7-4a08-b59f-e0d46b22c635_672x356.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zZT3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4397ba51-83a7-4a08-b59f-e0d46b22c635_672x356.webp" width="150" height="79.46428571428571" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4397ba51-83a7-4a08-b59f-e0d46b22c635_672x356.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:356,&quot;width&quot;:672,&quot;resizeWidth&quot;:150,&quot;bytes&quot;:10010,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:&quot;https://ko-fi.com/rixlabs&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/172912267?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4397ba51-83a7-4a08-b59f-e0d46b22c635_672x356.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zZT3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4397ba51-83a7-4a08-b59f-e0d46b22c635_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!zZT3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4397ba51-83a7-4a08-b59f-e0d46b22c635_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!zZT3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4397ba51-83a7-4a08-b59f-e0d46b22c635_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!zZT3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4397ba51-83a7-4a08-b59f-e0d46b22c635_672x356.webp 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div><hr></div><h2>Articles I enjoyed this week</h2><ul><li><p><a href="https://www.youtube.com/watch?v=gcwzWzC7gUA&amp;t=2433s">Rails World 2025 Opening Keynote</a> - <a href="https://x.com/dhh">David Heinemeier Hansson</a></p></li><li><p><a href="https://newsletter.francofernando.com/p/linear-interpolation">Linear Interpolation</a> - <a href="https://substack.com/@francofernando">Franco Fernando</a></p></li><li><p><a href="https://newsletter.systemdesigncodex.com/p/model-context-protocol-101">Model Context Protocol 101</a> - <a href="https://substack.com/@saurabhdashora">Saurabh Dashora</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[When Time Is Short, Choose Boring Tech]]></title><description><![CDATA[The case against bleeding-edge frameworks and tech gunslinging when delivery speed matters more than novelty.]]></description><link>https://ituntold.rixlabs.dev/p/when-time-is-short-choose-boring</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/when-time-is-short-choose-boring</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Sun, 11 May 2025 17:41:16 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!BVvv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe12a8125-a980-4536-946a-ffbbe7b60348_1024x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I&#8217;ve got an idea I want to try&#8212;and I want to monetize it fast.</p><p>As I started scaffolding the architecture, I reached that familiar crossroad: choosing the tech stack.<br>It&#8217;s my idea, my project. I could use whatever technology I like, from the most mainstream framework to some quirky self-made library.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BVvv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe12a8125-a980-4536-946a-ffbbe7b60348_1024x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BVvv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe12a8125-a980-4536-946a-ffbbe7b60348_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!BVvv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe12a8125-a980-4536-946a-ffbbe7b60348_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!BVvv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe12a8125-a980-4536-946a-ffbbe7b60348_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!BVvv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe12a8125-a980-4536-946a-ffbbe7b60348_1024x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BVvv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe12a8125-a980-4536-946a-ffbbe7b60348_1024x1536.png" width="1024" height="1536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e12a8125-a980-4536-946a-ffbbe7b60348_1024x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1536,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3527132,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/162767864?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe12a8125-a980-4536-946a-ffbbe7b60348_1024x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!BVvv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe12a8125-a980-4536-946a-ffbbe7b60348_1024x1536.png 424w, https://substackcdn.com/image/fetch/$s_!BVvv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe12a8125-a980-4536-946a-ffbbe7b60348_1024x1536.png 848w, https://substackcdn.com/image/fetch/$s_!BVvv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe12a8125-a980-4536-946a-ffbbe7b60348_1024x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!BVvv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe12a8125-a980-4536-946a-ffbbe7b60348_1024x1536.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>So what should I choose, and why?</p><p>Let&#8217;s go back to the premise:<br><strong>I want to monetize it fast.</strong></p><p>This scenario might sound familiar. Maybe it&#8217;s your own side project. Maybe it&#8217;s a custom solution for a client. Either way, if time is critical, there&#8217;s only one direction that makes real sense:</p><p><strong>Go with what you know best.</strong></p><p>If you need to deliver, maintain, and possibly expand fast, there&#8217;s no room for tech experiments.<br>Choosing a technology stack you're already familiar with lets you focus on what actually matters: building something that works and satisfies end users.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h3>But what if you want to experiment?</h3><p>There&#8217;s no doubt: doing a real project with an unfamiliar technology is one of the best ways to learn.<br>But&#8212;there&#8217;s always a &#8220;but&#8221;&#8212;you&#8217;ll spend a lot of time learning without making tangible progress on your project. That time loss can be frustrating, especially when delivery speed is a goal. You'll hit bumps, burn hours, and get blocked by things that have nothing to do with your core idea.</p><p>That&#8217;s fine when time isn&#8217;t a factor. But when it is? That learning curve becomes a liability.</p><p>That&#8217;s why I also brought up the example of custom work for a client. There&#8217;s no client on Earth without time constraints. If you want to reduce stress and risk, using a familiar stack is the most reliable path.</p><p>Every project already has enough uncertainty. Adding more on the technical side can turn friction into failure.</p><div><hr></div><h3>Real-world vs. tutorials</h3><p>Learning is great&#8212;but we all know real-world products have little in common with step-by-step tutorials. When you're on your own, you face a million edge cases and need to adapt well-known concepts to your specific use case. That takes time, even if you&#8217;re an experienced engineer.</p><div><hr></div><h3>A word on bleeding-edge tech</h3><p>Most of us in tech love innovation. There&#8217;s always a new language, framework, or tool dropping every week.<br>So what happens if you pick something ultra-new for your project?</p><p>You&#8217;ll probably run into incomplete documentation and missing features.</p><p>Sure, lack of docs can sometimes be solved by diving into the source code. But missing features? That&#8217;s another story. You might need to build significant parts yourself&#8212;components that the framework <em>should</em> handle. And those components will need to be solid: engineered properly, tested thoroughly, and ready for production.</p><p>Remember, we want to go live fast&#8212;and that means a certain level of maturity and stability is non-negotiable.</p><div><hr></div><h3>Personal example</h3><p>Contributing to new tech is exciting, no doubt. I remember back when I was deep into JavaScript, I contributed to a little-known framework called Vue.js. It was fun, I learned a lot, and I still remember what I did.</p><p>At the same time, at work, I was building production apps&#8212;and guess what I used there? Angular 2.<br>Well-established. Fairly complete. Backed by a large community.</p><p><strong>Learning and making money rarely move at the same pace.</strong></p><div><hr></div><h3>Flashy vs. reliable</h3><p>If you&#8217;ve got the luxury of time and money to invest two or three times longer in your project, more power to you. But for me, the reliability of a production tool is way more important than the flashiness of the tech stack.</p><p>In over 15 years of career, I don&#8217;t recall a single end user asking me which technology stack I used.<br>Sure, there are always a few nerdy exceptions who care about this stuff&#8212;but let&#8217;s be honest, they&#8217;re not the ones paying the bills.</p><p>As a lead architect, I&#8217;ve had countless conversations with enthusiastic junior devs or tech gunslingers about why we <em>aren&#8217;t</em> using the &#8220;next big thing.&#8221; And often, the reason is simple: it&#8217;s too new.<br>Statistically, fewer people know it. The community support isn&#8217;t there yet. Documentation might be spotty. Libraries might not exist. And when you need help, you&#8217;ll be mostly on your own.</p><div><hr></div><h3>Will AI change this?</h3><p>That said, I&#8217;m genuinely curious to see how this dynamic evolves with the rise of AI.</p><p>Right now, most AI models have a knowledge cutoff. Even when they can access the internet, their real strength still depends on the quality and volume of documentation available. The newer the tech, the less training data there is&#8212;so AI help is limited. I expect this will shift quickly, but today, it&#8217;s still a factor.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h3>Articles I enjoyed this week</h3><ul><li><p><a href="https://newsletter.systemdesigncodex.com/p/key-api-design-considerations?utm_source=%2Finbox&amp;utm_medium=reader2">Key API Design Considerations</a> by <strong><a href="https://substack.com/@saurabhdashora">Saurabh Dashora</a></strong></p></li><li><p><a href="https://newsletter.systemdesignclassroom.com/p/every-outbox-needs-an-inbox">Every Outbox Needs an Inbox</a> by <strong><a href="https://substack.com/@rauljuncov">Raul Junco</a></strong></p></li></ul><p></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://ko-fi.com/rixlabs" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yLIX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b19dba8-8b27-4c4b-8c1e-e6a6506a9d49_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!yLIX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b19dba8-8b27-4c4b-8c1e-e6a6506a9d49_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!yLIX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b19dba8-8b27-4c4b-8c1e-e6a6506a9d49_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!yLIX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b19dba8-8b27-4c4b-8c1e-e6a6506a9d49_672x356.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yLIX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b19dba8-8b27-4c4b-8c1e-e6a6506a9d49_672x356.webp" width="194" height="102.77380952380952" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1b19dba8-8b27-4c4b-8c1e-e6a6506a9d49_672x356.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:356,&quot;width&quot;:672,&quot;resizeWidth&quot;:194,&quot;bytes&quot;:10010,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:&quot;https://ko-fi.com/rixlabs&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/162767864?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b19dba8-8b27-4c4b-8c1e-e6a6506a9d49_672x356.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yLIX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b19dba8-8b27-4c4b-8c1e-e6a6506a9d49_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!yLIX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b19dba8-8b27-4c4b-8c1e-e6a6506a9d49_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!yLIX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b19dba8-8b27-4c4b-8c1e-e6a6506a9d49_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!yLIX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b19dba8-8b27-4c4b-8c1e-e6a6506a9d49_672x356.webp 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p>]]></content:encoded></item><item><title><![CDATA[False promises fatigue]]></title><description><![CDATA[From AI miracles to snake oil seller]]></description><link>https://ituntold.rixlabs.dev/p/false-promises-fatigue</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/false-promises-fatigue</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Thu, 24 Apr 2025 09:21:37 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!GVPX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f9fa87e-9a67-45e3-8aa9-2320782cf233_999x1326.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>What will I find if I start creating content and interacting on another platform?</em></p><p>This was my question back in October, when I created the <em>IT Untold</em> publication here on Substack.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading IT Untold! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>My idea was to start fresh&#8212;writing about tech on a platform that encourages long-form content and slower-paced media consumption.</p><p>And to some extent, that&#8217;s what I found. I began writing deeper articles, taking the time to explore topics more thoroughly, and posting less frequently but with more substance. But on the reading side, I quickly ran into the same old problem.</p><p><strong>Hype and buzzwords.</strong></p><p>This platform, like almost every social media space filled with tech content, is polluted by the same recurring noise.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GVPX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f9fa87e-9a67-45e3-8aa9-2320782cf233_999x1326.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GVPX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f9fa87e-9a67-45e3-8aa9-2320782cf233_999x1326.png 424w, https://substackcdn.com/image/fetch/$s_!GVPX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f9fa87e-9a67-45e3-8aa9-2320782cf233_999x1326.png 848w, https://substackcdn.com/image/fetch/$s_!GVPX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f9fa87e-9a67-45e3-8aa9-2320782cf233_999x1326.png 1272w, https://substackcdn.com/image/fetch/$s_!GVPX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f9fa87e-9a67-45e3-8aa9-2320782cf233_999x1326.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GVPX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f9fa87e-9a67-45e3-8aa9-2320782cf233_999x1326.png" width="999" height="1326" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4f9fa87e-9a67-45e3-8aa9-2320782cf233_999x1326.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1326,&quot;width&quot;:999,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3186724,&quot;alt&quot;:&quot;False promises fatigue&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/161375483?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea69e73c-0525-40ec-9868-9a6fa1b96587_1024x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="False promises fatigue" title="False promises fatigue" srcset="https://substackcdn.com/image/fetch/$s_!GVPX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f9fa87e-9a67-45e3-8aa9-2320782cf233_999x1326.png 424w, https://substackcdn.com/image/fetch/$s_!GVPX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f9fa87e-9a67-45e3-8aa9-2320782cf233_999x1326.png 848w, https://substackcdn.com/image/fetch/$s_!GVPX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f9fa87e-9a67-45e3-8aa9-2320782cf233_999x1326.png 1272w, https://substackcdn.com/image/fetch/$s_!GVPX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f9fa87e-9a67-45e3-8aa9-2320782cf233_999x1326.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p><strong>AI bros and people obsessed with numbers.</strong></p><p>The AI bubble started as a revolution in 2023. Like many others, I was genuinely excited to try it, explore its potential, and understand its limitations. For a moment, it really felt like something new and promising.</p><p>But soon, on every platform with tech news or commentary, the miraculous benefits of AI became omnipresent.</p><p>That&#8217;s when the infamous &#8220;10x developer&#8221; meme resurfaced, accompanied by dramatic talk about the end of &#8220;old developers&#8221; and the urgent need to embrace AI tools to avoid falling behind.</p><p>I&#8217;m not pessimistic about this shift&#8212;I&#8217;m quite sure that, in one way or another, everyone will end up using AI. That&#8217;s just how technology adoption works.</p><p>The problem is the <strong>spam</strong>. It got worse and worse.</p><p>Building LLM wrappers became <em>the</em> thing to do for all of 2023 and a good chunk of 2024. Useless chat apps popped up everywhere, with self-proclaimed &#8220;prompt engineers&#8221; repackaging your input in a slightly different prompt and calling it innovation.</p><p>Anyone with a basic understanding of IT could see through the nonsense. LLMs became so advanced that the so-called "art" of prompt engineering became mostly irrelevant.</p><p>And so, the AI bros needed to find new ways to stay relevant.</p><p>That&#8217;s been the real problem since the beginning. The AI revolution made a lot of people with nothing interesting to say look relevant&#8212;just because they rode the massive hype wave. I&#8217;ve never seen so many posts and courses about &#8220;growing your audience&#8221; until people figured out they could just slap &#8220;AI&#8221; on top of it.</p><p>Suddenly, everyone and their mom was trying to convince me that I needed AI to write. That I could generate passive income using AI. That I could use it to create content for social media. That AI would grow my audience from zero to profit.</p><p>"Are you a mom who wants to make extra money? Use this method to learn how to leverage AI tools."</p><p>For a while, I was intrigued by those bold claims.</p><p>Was it true? Could anyone really build an audience this way? Could you just generate content and magically start selling a product or service?</p><p>So I started digging.</p><p>And I noticed something odd: many of the people selling these &#8220;methods&#8221; used social media only for that&#8212;selling methods.</p><p>What do I mean?</p><p>The accounts of these snake-oil sellers were filled exclusively with content <em>about content creation</em>. There was no actual product. No past experience. No real expertise.</p><p>In my research, I came across an insane number of stay-at-home moms selling courses on "making money with digital products." But if you look across their entire online presence, the <em>only</em> product they have is a course on how to make money selling digital products.</p><p>It&#8217;s a weird chicken-and-egg situation, and it applies to countless other niches too.</p><p>So&#8212;what does this have to do with AI? A lot.</p><p>AI made it easier for people to produce grammatically correct, visually polished material, padded with filler that makes it look professional. It gives the illusion that the so-called expert spent time crafting a valuable course.</p><p>AI gave people the impression that making money online is effortless.</p><p>And while there are still many genuine, high-quality creators who love sharing knowledge and maybe earning from it, they now coexist with a tidal wave of fluff.</p><p>I&#8217;m absolutely <strong>pro-AI</strong> when it comes to content creation&#8212;don&#8217;t get me wrong. It&#8217;s an incredible partner for revising, polishing, avoiding repetition, and catching strange mistakes. But it&#8217;s not a panacea. It&#8217;s not a silver bullet.</p><p>Most people consume content in their free time. It&#8217;s a way to stay up to date, learn something new, or simply escape from everyday life.</p><p>That&#8217;s why the absurd amount of <em>pollution</em> in the content creation world feels even more frustrating&#8212;especially here on Substack, where the newsletter format is designed for depth, not surface-level noise.</p><p>I want to read about interesting concepts, exciting technologies, and genuine experiences. Sure, use an LLM to help you put an article together&#8212;but please, don&#8217;t bury me under a mountain of meaningless AI-themed posts.</p><p>If I sound dramatic, just try scrolling through the Technology tab on your Substack homepage. It&#8217;s ridiculous.</p><p>But this isn&#8217;t just a rant aimed at the tech space on social media. It&#8217;s mostly an <strong>invitation</strong>&#8212;for those who <em>do</em> have something to say: <strong>say it.</strong> Keep publishing good content. Keep sharing your thoughts, experiences, and knowledge.</p><p>Your voice matters. And sooner or later, your content <em>will</em> stand out.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://ko-fi.com/rixlabs" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LC6o!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbc5eff9-0b32-4993-8166-e29e73a1b05f_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!LC6o!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbc5eff9-0b32-4993-8166-e29e73a1b05f_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!LC6o!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbc5eff9-0b32-4993-8166-e29e73a1b05f_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!LC6o!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbc5eff9-0b32-4993-8166-e29e73a1b05f_672x356.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LC6o!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbc5eff9-0b32-4993-8166-e29e73a1b05f_672x356.webp" width="184" height="97.47619047619048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fbc5eff9-0b32-4993-8166-e29e73a1b05f_672x356.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:356,&quot;width&quot;:672,&quot;resizeWidth&quot;:184,&quot;bytes&quot;:10010,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:&quot;https://ko-fi.com/rixlabs&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/161375483?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbc5eff9-0b32-4993-8166-e29e73a1b05f_672x356.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!LC6o!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbc5eff9-0b32-4993-8166-e29e73a1b05f_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!LC6o!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbc5eff9-0b32-4993-8166-e29e73a1b05f_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!LC6o!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbc5eff9-0b32-4993-8166-e29e73a1b05f_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!LC6o!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbc5eff9-0b32-4993-8166-e29e73a1b05f_672x356.webp 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div><hr></div><h3>Articles I enjoyed this week</h3><ul><li><p><a href="https://newsletter.systemdesigncodex.com/p/how-kubernetes-works-internally">How Kubernetes Works Internally?</a> by <a href="https://substack.com/@saurabhdashora">Saurabh Dashora</a> </p></li><li><p><a href="https://newsletter.systemdesignclassroom.com/p/why-just-publishing-events-isnt-enough">Why Just Publishing Events Isn&#8217;t Enough</a> by <a href="https://substack.com/@rauljuncov">Raul Junco</a> &amp; <a href="https://substack.com/@optimistengineer">Marcos F. Lobo</a></p></li></ul><div><hr></div><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/false-promises-fatigue?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading IT Untold! If you like this article please share it with your friends and colleagues</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/false-promises-fatigue?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/p/false-promises-fatigue?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading IT Untold! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Threat Modeling as a Design Practice]]></title><description><![CDATA[Threat modeling isn&#8217;t a security checklist.]]></description><link>https://ituntold.rixlabs.dev/p/threat-modeling-as-a-design-practice</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/threat-modeling-as-a-design-practice</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Fri, 11 Apr 2025 11:31:50 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!AXy8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12cd79eb-ed55-44e4-89d3-4d4bf785d914_1802x1242.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Threat modeling isn&#8217;t a security checklist. It&#8217;s a design activity. It&#8217;s the deliberate act of thinking about what might go wrong in a system <em>before</em> it's built, or while it&#8217;s still possible to do something about it.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AXy8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12cd79eb-ed55-44e4-89d3-4d4bf785d914_1802x1242.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AXy8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12cd79eb-ed55-44e4-89d3-4d4bf785d914_1802x1242.png 424w, https://substackcdn.com/image/fetch/$s_!AXy8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12cd79eb-ed55-44e4-89d3-4d4bf785d914_1802x1242.png 848w, https://substackcdn.com/image/fetch/$s_!AXy8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12cd79eb-ed55-44e4-89d3-4d4bf785d914_1802x1242.png 1272w, https://substackcdn.com/image/fetch/$s_!AXy8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12cd79eb-ed55-44e4-89d3-4d4bf785d914_1802x1242.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AXy8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12cd79eb-ed55-44e4-89d3-4d4bf785d914_1802x1242.png" width="1802" height="1242" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/12cd79eb-ed55-44e4-89d3-4d4bf785d914_1802x1242.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1242,&quot;width&quot;:1802,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2384509,&quot;alt&quot;:&quot;Threat Modeling&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/160998243?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6015e04-412a-4e6e-88a5-1db7c4d0f2f3_1802x1242.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Threat Modeling" title="Threat Modeling" srcset="https://substackcdn.com/image/fetch/$s_!AXy8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12cd79eb-ed55-44e4-89d3-4d4bf785d914_1802x1242.png 424w, https://substackcdn.com/image/fetch/$s_!AXy8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12cd79eb-ed55-44e4-89d3-4d4bf785d914_1802x1242.png 848w, https://substackcdn.com/image/fetch/$s_!AXy8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12cd79eb-ed55-44e4-89d3-4d4bf785d914_1802x1242.png 1272w, https://substackcdn.com/image/fetch/$s_!AXy8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12cd79eb-ed55-44e4-89d3-4d4bf785d914_1802x1242.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Despite being around for years, threat modeling has recently gained renewed attention, including a mention in the latest <a href="https://www.thoughtworks.com/en-us/radar/techniques/summary/threat-modeling">ThoughtWorks Technology Radar</a>. The reason? Teams are starting to treat it less as a specialized security task and more as a regular design habit. And that&#8217;s a welcome shift.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2><strong>What Threat Modeling Actually Is</strong></h2><p>The premise of threat modeling is simple: every system has assets worth protecting, and every system makes assumptions about what can and cannot happen. Threat modeling is about identifying both, and then challenging those assumptions.</p><p>It often revolves around four recurring questions:</p><ol><li><p><strong>What are we building?</strong></p></li><li><p><strong>What could go wrong?</strong></p></li><li><p><strong>What are we going to do about it?</strong></p></li><li><p><strong>Did we do a good enough job?</strong></p></li></ol><p>It&#8217;s not a formal method or a framework. It&#8217;s a structured conversation, usually centered around architecture diagrams, that helps a team uncover risks and make design choices with intent, not just hope.</p><div><hr></div><h2><strong>Why It Matters in Architecture</strong></h2><p>Security flaws aren&#8217;t always the result of coding mistakes. They&#8217;re often a symptom of misplaced trust, implicit assumptions, or blind spots in the architecture itself.</p><p>If a service assumes the caller is authenticated because it's &#8220;internal,&#8221; or if a frontend trusts data returned from an API without verifying it, those are architectural issues. They aren&#8217;t going to be caught by linters or firewalls.</p><p>Threat modeling shifts the conversation left, before production, before implementation, and puts it in the hands of those making design decisions. It allows teams to reduce the attack surface and build in defense where it&#8217;s most effective: at the edges of architectural trust boundaries.</p><div><hr></div><h2><strong>Making It a Habit, Not an Event</strong></h2><p>One of the most effective things teams can do is <em>lower the barrier</em> to threat modeling. If it becomes a heavyweight activity with forms, templates, and formal reviews, it&#8217;ll get deferred until &#8220;later.&#8221; In most cases, later never comes.</p><p>Teams that do this well treat it as a recurring, informal discussion, often baked into sprint planning, story refinement, or design reviews. It doesn&#8217;t need to be exhaustive every time. A 30-minute conversation with a whiteboard sketch can go a long way, especially when focused on a single new feature or integration point.</p><p>The key is frequency, not completeness. Risks evolve as the system evolves. A &#8220;threat model&#8221; isn&#8217;t a static artifact, it&#8217;s a lens to regularly re-examine your system&#8217;s weak spots.</p><div><hr></div><h2><strong>How to Run an Effective Threat Modeling Session</strong></h2><p>Here&#8217;s what works in practice, no buzzwords, no silver bullets:</p><h3><strong>1. Start with a Diagram</strong></h3><p>Draw how the system works, even if it&#8217;s rough. Show components, users, data flows, and especially trust boundaries (e.g., between the browser and backend, between services, between your system and third parties). If you can&#8217;t draw it, you probably don&#8217;t understand it.</p><h3><strong>2. Ask &#8220;What Could Go Wrong?&#8221;</strong></h3><p>This is the heart of it. Walk through each part of the system and ask:</p><ul><li><p>What if this component is compromised?</p></li><li><p>What happens if this data is tampered with?</p></li><li><p>What assumptions are we making about the network, the identity provider, the user?</p></li></ul><h3><strong>3. Use Threat Categories If Needed</strong></h3><p>Many teams use the STRIDE model (Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege) as a checklist. It helps, but don&#8217;t follow it blindly. Think of it as training wheels &#8212; a way to spark questions, not to gatekeep answers.</p><h3><strong>4. Prioritize, Don&#8217;t Panic</strong></h3><p>Not every risk needs a mitigation. Some just need documentation. Some are so unlikely they&#8217;re not worth addressing now. But some will point to weak spots in the design that should be fixed early. The point is to surface them, discuss them, and make decisions deliberately.</p><h3><strong>5. Document the Assumptions</strong></h3><p>Even if you don&#8217;t write down a full report, log your assumptions. For example:</p><ul><li><p>&#8220;We assume service X cannot be accessed from the public internet.&#8221;</p></li><li><p>&#8220;We trust the identity provider&#8217;s tokens are valid and time-bound.&#8221;</p></li><li><p>&#8220;This system doesn't store PII, so data exposure is low-impact.&#8221;</p></li></ul><p>These assumptions are often what come back to bite you six months later, especially during incident response.</p><div><hr></div><h2><strong>Common Pitfalls to Avoid</strong></h2><p>Even with good intentions, threat modeling efforts can go off track. Here are the traps to watch for:</p><ul><li><p><strong>Trying to cover everything at once</strong> &#8211; It&#8217;s better to model one feature well than the whole system badly. Keep it scoped and focused.</p></li><li><p><strong>Over-formalizing the process</strong> &#8211; Threat modeling isn&#8217;t compliance. It&#8217;s about clarity and critical thinking, not checkboxes.</p></li><li><p><strong>Doing it once, then forgetting about it</strong> &#8211; Systems change. So do risks. If you don&#8217;t revisit your assumptions, they&#8217;ll silently rot.</p></li><li><p><strong>Relying only on security experts</strong> &#8211; Engineers, architects, product owners &#8212; all of them see different angles. Don&#8217;t gatekeep the process.</p></li></ul><div><hr></div><h2><strong>Threat Modeling in Agile Teams</strong></h2><p>Traditional security reviews often happened late, if they happened at all. That doesn&#8217;t work in iterative environments. Teams need lightweight, repeatable practices that match the pace of delivery.</p><p>Some useful strategies:</p><ul><li><p>Incorporate threat modeling in backlog grooming for features that affect trust boundaries or data flow.</p></li><li><p>Add &#8220;evil user stories&#8221; (e.g., &#8220;As an attacker, I want to bypass rate limits to scrape data&#8221;) to uncover threats from an adversary's point of view.</p></li><li><p>Treat architectural spikes as opportunities to explore security implications, not just technical feasibility.</p></li></ul><p>The point is not to slow down agility, it&#8217;s to build security thinking into the process <em>without friction</em>.</p><div><hr></div><p>Good architecture isn&#8217;t just about performance, scalability, or modularity. It&#8217;s about trust, knowing where your system is vulnerable and putting the right controls in place.</p><p>Threat modeling gives teams the space to challenge their assumptions and clarify their thinking. It&#8217;s not just a security technique; it&#8217;s a design discipline. And like all good design habits, its power comes from repetition, not complexity.</p><p>You don&#8217;t need a dedicated security team to start. You just need to care enough to ask, &#8220;What could go wrong?&#8221; and take the time to answer it while it still matters.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><p>If you like my content enough to pay me a coffee&#8230;</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://ko-fi.com/rixlabs" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zMbe!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59aaba89-9302-458b-8b9d-16637728c564_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!zMbe!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59aaba89-9302-458b-8b9d-16637728c564_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!zMbe!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59aaba89-9302-458b-8b9d-16637728c564_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!zMbe!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59aaba89-9302-458b-8b9d-16637728c564_672x356.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zMbe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59aaba89-9302-458b-8b9d-16637728c564_672x356.webp" width="188" height="99.5952380952381" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/59aaba89-9302-458b-8b9d-16637728c564_672x356.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:356,&quot;width&quot;:672,&quot;resizeWidth&quot;:188,&quot;bytes&quot;:10010,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:&quot;https://ko-fi.com/rixlabs&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/160998243?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59aaba89-9302-458b-8b9d-16637728c564_672x356.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zMbe!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59aaba89-9302-458b-8b9d-16637728c564_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!zMbe!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59aaba89-9302-458b-8b9d-16637728c564_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!zMbe!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59aaba89-9302-458b-8b9d-16637728c564_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!zMbe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59aaba89-9302-458b-8b9d-16637728c564_672x356.webp 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div><hr></div><h3>Articles I enjoyed this week</h3><ul><li><p><strong><a href="https://newsletter.francofernando.com/p/how-not-to-fail-a-system-design-interview">How (not to) fail a system design interview</a></strong> by <strong><a href="https://substack.com/@francofernando">Franco Fernando</a></strong> </p></li><li><p><strong><a href="https://softwarefrontier.substack.com/p/a-deep-dive-into-apache-iceberg-a?utm_source=%2Finbox&amp;utm_medium=reader2">A Deep Dive into Apache Iceberg: A Journey Through the Future of Data Lakehouse Table Formats</a></strong> by <strong><a href="https://substack.com/@lorenzobradanini">Lorenzo Bradanini</a></strong></p></li><li><p><strong><a href="https://newsletter.systemdesigncodex.com/p/load-balancer-gateway-bff-and-graphql?utm_source=%2Finbox&amp;utm_medium=reader2">Load Balancer, Gateway, BFF &amp; GraphQL: The Squad Handling API Calls</a> </strong>by<strong>  <a href="https://substack.com/@saurabhdashora">Saurabh Dashora</a> </strong></p></li></ul><div><hr></div><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/threat-modeling-as-a-design-practice?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading IT Untold! If you like this article please share it with your friends and colleagues</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/threat-modeling-as-a-design-practice?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/p/threat-modeling-as-a-design-practice?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p>]]></content:encoded></item><item><title><![CDATA[Infrastructure as Code: A Practical Approach]]></title><description><![CDATA[Before continuing with the Key Concept of system desing we need to talk about infrastructure]]></description><link>https://ituntold.rixlabs.dev/p/infrastructure-as-code-a-practical</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/infrastructure-as-code-a-practical</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Tue, 01 Apr 2025 19:56:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!19Do!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95853289-d922-4109-9bab-9c4dd3e1b506_1798x1240.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the Key concept of system design series we have took the decision of deploying our Discord clone application into the cloud. More specifically to MS Azure.</p><p>One aspect I consider key when talking about developing and deploying an application is Infrastructure as code (IaC). </p><p>I think it is crucial to touch this aspect before we move on to the deployment view.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><p>IaC is an essential practice in modern software development, especially when working in the cloud. It allows teams to define infrastructure through code rather than manual processes, making environments reproducible, scalable, and maintainable.</p><p>In this article, we'll explore what IaC is, the main technologies used to implement it, and why a build pipeline is crucial. We'll also look at key considerations when working with IaC in cloud environments&#8212;focusing on Microsoft Azure.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!19Do!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95853289-d922-4109-9bab-9c4dd3e1b506_1798x1240.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!19Do!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95853289-d922-4109-9bab-9c4dd3e1b506_1798x1240.png 424w, https://substackcdn.com/image/fetch/$s_!19Do!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95853289-d922-4109-9bab-9c4dd3e1b506_1798x1240.png 848w, https://substackcdn.com/image/fetch/$s_!19Do!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95853289-d922-4109-9bab-9c4dd3e1b506_1798x1240.png 1272w, https://substackcdn.com/image/fetch/$s_!19Do!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95853289-d922-4109-9bab-9c4dd3e1b506_1798x1240.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!19Do!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95853289-d922-4109-9bab-9c4dd3e1b506_1798x1240.png" width="1456" height="1004" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/95853289-d922-4109-9bab-9c4dd3e1b506_1798x1240.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1004,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2378632,&quot;alt&quot;:&quot;Infrastructure as Code: A Practical Approach&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/160332772?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95853289-d922-4109-9bab-9c4dd3e1b506_1798x1240.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Infrastructure as Code: A Practical Approach" title="Infrastructure as Code: A Practical Approach" srcset="https://substackcdn.com/image/fetch/$s_!19Do!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95853289-d922-4109-9bab-9c4dd3e1b506_1798x1240.png 424w, https://substackcdn.com/image/fetch/$s_!19Do!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95853289-d922-4109-9bab-9c4dd3e1b506_1798x1240.png 848w, https://substackcdn.com/image/fetch/$s_!19Do!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95853289-d922-4109-9bab-9c4dd3e1b506_1798x1240.png 1272w, https://substackcdn.com/image/fetch/$s_!19Do!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95853289-d922-4109-9bab-9c4dd3e1b506_1798x1240.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>What Is Infrastructure as Code?</h2><p>IaC is the practice of managing infrastructure (networks, virtual machines, storage, databases, etc.) using machine-readable definition files instead of manual configuration. This approach brings several advantages:</p><ul><li><p><strong>Consistency</strong> &#8211; Environments can be recreated reliably.</p></li><li><p><strong>Version Control</strong> &#8211; Infrastructure changes are tracked like application code.</p></li><li><p><strong>Automation</strong> &#8211; Reduces human error and speeds up deployment.</p></li><li><p><strong>Scalability</strong> &#8211; Makes it easier to replicate environments across teams and regions.</p></li></ul><h3>Declarative vs. Imperative IaC</h3><p>IaC tools fall into two main categories:</p><ul><li><p><strong>Declarative</strong> (e.g., Terraform, Pulumi, Bicep): Define the desired state, and the tool figures out how to get there.</p></li><li><p><strong>Imperative</strong> (e.g., Ansible, PowerShell, Bash scripts): Define step-by-step instructions to configure infrastructure.</p></li></ul><p>While both approaches have their use cases, declarative IaC is generally preferred for cloud environments because it simplifies state management and makes infrastructure changes predictable.</p><div><hr></div><h2>Main Technologies for Implementing IaC</h2><p>Several technologies are commonly used to define and deploy infrastructure:</p><ul><li><p><strong>Terraform</strong> &#8211; A widely adopted declarative IaC tool that works across multiple cloud providers.</p></li><li><p><strong>Bicep</strong> &#8211; A domain-specific language (DSL) for defining Azure infrastructure, designed as a more readable alternative to ARM templates.</p></li><li><p><strong>Pulumi</strong> &#8211; Allows writing IaC using general-purpose programming languages like Python, TypeScript, and Go.</p></li><li><p><strong>Ansible</strong> &#8211; Often used for configuration management but can also provision infrastructure in an imperative way.</p></li><li><p><strong>Cloud-Native Tools</strong> &#8211; Each cloud provider offers its own IaC tools (e.g., AWS CloudFormation, Azure Resource Manager).</p></li></ul><p>For Azure-focused IaC, <strong>Bicep</strong> and <strong>Terraform</strong> are the most common choices.</p><div><hr></div><h2>Why the Build Pipeline Matters</h2><p>Writing infrastructure code is just the first step. To make IaC truly effective, it should be integrated into a <strong>build pipeline</strong> that ensures:</p><ul><li><p><strong>Automated validation</strong> &#8211; Linting, syntax checks, and security scans.</p></li><li><p><strong>Plan and review processes</strong> &#8211; Seeing infrastructure changes before applying them (e.g., <code>terraform plan</code>).</p></li><li><p><strong>Safe deployment</strong> &#8211; Applying changes incrementally and avoiding downtime.</p></li></ul><p>A typical Azure DevOps or GitHub Actions pipeline for Terraform or Bicep would include:</p><ol><li><p><strong>Linting &amp; validation</strong> &#8211; Checking for syntax errors.</p></li><li><p><strong>Plan phase</strong> &#8211; Generating a preview of the changes.</p></li><li><p><strong>Approval process</strong> &#8211; Requiring human approval for critical infrastructure updates.</p></li><li><p><strong>Apply phase</strong> &#8211; Deploying changes only after approval.</p></li></ol><p>Without a proper pipeline, IaC can become a manual, error-prone process&#8212;defeating its purpose.</p><div><hr></div><h2>IaC in Cloud Environments: Why It&#8217;s Critical</h2><p>Cloud providers like Azure offer highly dynamic environments where infrastructure is created, modified, and destroyed frequently. Manually managing cloud resources is neither scalable nor reliable. <strong>IaC is essential for:</strong></p><ul><li><p><strong>Managing multiple environments (Dev, Staging, Production) consistently.</strong></p></li><li><p><strong>Scaling infrastructure dynamically without manual intervention.</strong></p></li><li><p><strong>Tracking changes in source control instead of relying on ad-hoc modifications.</strong></p></li><li><p><strong>Disaster recovery by enabling rapid environment restoration.</strong></p></li></ul><h3>Example: Provisioning an Azure AKS Cluster with Terraform</h3><p>To see how IaC simplifies cloud resource management, consider deploying an Azure Kubernetes Service (AKS) cluster using Terraform:</p><pre><code><code>resource "azurerm_resource_group" "example" {
  name     = "myResourceGroup"
  location = "East US"
}

resource "azurerm_kubernetes_cluster" "example" {
  name                = "myAKSCluster"
  location           = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  dns_prefix         = "myaks"
  
  default_node_pool {
    name       = "default"
    node_count = 2
    vm_size    = "Standard_DS2_v2"
  }

  identity {
    type = "SystemAssigned"
  }
}
</code></code></pre><p>This Terraform configuration defines an Azure resource group and an AKS cluster with a default node pool. Running <code>terraform apply</code> provisions the infrastructure automatically, ensuring consistency across environments.</p><div><hr></div><h2>Key Considerations When Implementing IaC in the Cloud</h2><p>When using IaC in cloud environments, there are several things to keep in mind:</p><h3>1. <strong>State Management</strong></h3><ul><li><p>Terraform stores state files that track deployed resources.</p></li><li><p>Use <strong>remote state backends</strong> (e.g., Azure Storage) instead of local files to avoid conflicts.</p></li><li><p>Enable state locking to prevent concurrent updates.</p></li></ul><h3>2. <strong>Security Best Practices</strong></h3><ul><li><p>Never hardcode secrets in IaC files; use <strong>Azure Key Vault</strong>.</p></li><li><p>Apply <strong>least privilege principles</strong> with managed identities instead of storing credentials in code.</p></li><li><p>Scan IaC files for security vulnerabilities before applying changes.</p></li></ul><h3>3. <strong>Modularization &amp; Reusability</strong></h3><ul><li><p>Break infrastructure into reusable <strong>modules</strong> instead of monolithic files.</p></li><li><p>Define separate IaC configurations for networking, compute, and applications.</p></li><li><p>Use parameterization to make configurations flexible across environments.</p></li></ul><h3>4. <strong>Handling Cloud Drift</strong></h3><ul><li><p>Cloud environments can change outside of IaC tools (manual updates, API calls).</p></li><li><p>Regularly run <code>terraform plan</code> or equivalent commands to detect <strong>drift</strong>.</p></li><li><p>Implement <strong>policy enforcement</strong> (e.g., Azure Policy) to prevent unauthorized changes.</p></li></ul><h3>5. <strong>Cost Control</strong></h3><ul><li><p>IaC makes it easy to spin up resources, but costs can escalate quickly.</p></li><li><p>Use <strong>resource tagging</strong> and budget monitoring to track expenses.</p></li><li><p>Implement automatic <strong>resource cleanup</strong> for non-production environments.</p></li></ul><div><hr></div><p>Infrastructure as Code is a fundamental practice for managing cloud infrastructure efficiently. By using tools like Terraform or Bicep, integrating IaC into a build pipeline, and following best practices, teams can ensure their infrastructure is consistent, scalable, and secure.</p><p>When working in cloud environments&#8212;especially Azure&#8212;careful consideration of state management, security, and cost control is essential. While IaC simplifies many aspects of infrastructure provisioning, it still requires a well-thought-out approach to avoid pitfalls.</p><p>If you're not using IaC yet, now is the time to start!</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><p>If you like my content enough to pay me a coffee&#8230;</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://ko-fi.com/rixlabs" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Wa5x!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd554e37d-ede9-43b5-8764-9e6ce2779ca3_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!Wa5x!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd554e37d-ede9-43b5-8764-9e6ce2779ca3_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!Wa5x!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd554e37d-ede9-43b5-8764-9e6ce2779ca3_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!Wa5x!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd554e37d-ede9-43b5-8764-9e6ce2779ca3_672x356.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Wa5x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd554e37d-ede9-43b5-8764-9e6ce2779ca3_672x356.webp" width="162" height="85.82142857142857" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d554e37d-ede9-43b5-8764-9e6ce2779ca3_672x356.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:356,&quot;width&quot;:672,&quot;resizeWidth&quot;:162,&quot;bytes&quot;:10010,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:&quot;https://ko-fi.com/rixlabs&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/160332772?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd554e37d-ede9-43b5-8764-9e6ce2779ca3_672x356.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Wa5x!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd554e37d-ede9-43b5-8764-9e6ce2779ca3_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!Wa5x!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd554e37d-ede9-43b5-8764-9e6ce2779ca3_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!Wa5x!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd554e37d-ede9-43b5-8764-9e6ce2779ca3_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!Wa5x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd554e37d-ede9-43b5-8764-9e6ce2779ca3_672x356.webp 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div><hr></div><h3>Articles I enjoyed this week</h3><ul><li><p><strong><a href="https://newsletter.systemdesigncodex.com/p/5-must-know-deployment-strategies">5 Must-Know Deployment Strategies</a></strong> by <strong><a href="https://substack.com/@saurabhdashora">Saurabh Dashora</a></strong> </p></li><li><p><strong><a href="https://newsletter.techworld-with-milan.com/p/trends-6-typescript-is-getting-10x">Trends #7: TypeScript is getting 10x faster!</a></strong> by <strong><a href="https://substack.com/@techworldwithmilan">Milan Milanovi&#263;</a></strong></p></li><li><p><strong><a href="https://newsletter.systemdesign.one/p/how-does-apple-pay-work">How Apple Pay Handles 41 Million Transactions a Day Securely &#128184;</a></strong><a href="https://newsletter.systemdesign.one/p/how-does-apple-pay-work"> </a>by <strong><a href="https://substack.com/@systemdesignone">Neo Kim</a></strong></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Is lazy loading really lazy?]]></title><description><![CDATA[A deep dive into Suppliers in Java]]></description><link>https://ituntold.rixlabs.dev/p/is-lazy-loading-really-lazy</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/is-lazy-loading-really-lazy</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Sun, 23 Mar 2025 19:06:17 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Md05!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb39d28-bfb5-4ce4-82ed-a3df190c701a_1804x1252.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2><strong>A Curious Question</strong></h2><p>Some time ago, a junior developer I was working with asked an interesting question:</p><p><em>"I know that passing a </em><code>Supplier&lt;T&gt;</code><em> to a method allows for lazy loading, but what happens under the hood? If the supplier calls a service method that fetches data from a REST API, is the API call made immediately? If not, how does dependency injection work in this case?"</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Md05!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb39d28-bfb5-4ce4-82ed-a3df190c701a_1804x1252.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Md05!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb39d28-bfb5-4ce4-82ed-a3df190c701a_1804x1252.png 424w, https://substackcdn.com/image/fetch/$s_!Md05!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb39d28-bfb5-4ce4-82ed-a3df190c701a_1804x1252.png 848w, https://substackcdn.com/image/fetch/$s_!Md05!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb39d28-bfb5-4ce4-82ed-a3df190c701a_1804x1252.png 1272w, https://substackcdn.com/image/fetch/$s_!Md05!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb39d28-bfb5-4ce4-82ed-a3df190c701a_1804x1252.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Md05!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb39d28-bfb5-4ce4-82ed-a3df190c701a_1804x1252.png" width="1456" height="1010" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6fb39d28-bfb5-4ce4-82ed-a3df190c701a_1804x1252.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1010,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2814746,&quot;alt&quot;:&quot;Are suppliers really lazy&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/159694528?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb39d28-bfb5-4ce4-82ed-a3df190c701a_1804x1252.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Are suppliers really lazy" title="Are suppliers really lazy" srcset="https://substackcdn.com/image/fetch/$s_!Md05!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb39d28-bfb5-4ce4-82ed-a3df190c701a_1804x1252.png 424w, https://substackcdn.com/image/fetch/$s_!Md05!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb39d28-bfb5-4ce4-82ed-a3df190c701a_1804x1252.png 848w, https://substackcdn.com/image/fetch/$s_!Md05!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb39d28-bfb5-4ce4-82ed-a3df190c701a_1804x1252.png 1272w, https://substackcdn.com/image/fetch/$s_!Md05!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb39d28-bfb5-4ce4-82ed-a3df190c701a_1804x1252.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>This was a great question because it touched on multiple important concepts: functional interfaces, lazy evaluation, and dependency injection. While many Java developers use <code>Supplier&lt;T&gt;</code> in their code, not everyone fully understands its inner workings. So, let&#8217;s dive into it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2><strong>A Quick Refresher: What is </strong><code>Supplier&lt;T&gt;</code><strong>?</strong></h2><p><code>Supplier&lt;T&gt;</code> is a functional interface in Java that represents a function that takes no arguments but returns a value of type <code>T</code>.</p><p>Here&#8217;s its simple definition from <code>java.util.function</code>:</p><pre><code><code>@FunctionalInterface
public interface Supplier&lt;T&gt; {
    T get();
}</code></code></pre><ul><li><p>It has a single abstract method, <code>get()</code>, which returns a value but does not take any parameters.</p></li><li><p>It is commonly used for <strong>lazy evaluation</strong>, <strong>deferred execution</strong>, and <strong>factory methods</strong>.</p></li></ul><h3><strong>Basic Example</strong></h3><p>To see <code>Supplier&lt;T&gt;</code> in action, let&#8217;s define one that generates a greeting:</p><pre><code><code>Supplier&lt;String&gt; greetingSupplier = () -&gt; "Hello, World!";
System.out.println(greetingSupplier.get());  // Only now is the value generated</code></code></pre><p>Since <code>Supplier&lt;T&gt;</code> does not execute immediately, it allows us to <strong>delay computations</strong> until they are actually needed.</p><div><hr></div><h2><strong>What Happens at the JVM Level?</strong></h2><p>When you pass a <code>Supplier&lt;T&gt;</code> to a method, you are passing a <strong>lambda expression</strong> (or a method reference) that represents a piece of code to be executed later.</p><p>At the <strong>JVM level</strong>:</p><ul><li><p>The lambda expression or method reference is converted into an instance of a <strong>functional interface</strong> (<code>Supplier&lt;T&gt;</code>).</p></li><li><p>If the lambda captures variables from the enclosing scope, the compiler generates a <strong>synthetic class</strong> that holds references to those captured variables.</p></li><li><p>The actual code inside the lambda or method reference is <strong>not executed immediately</strong>. Instead, it is stored as an instance of <code>Supplier&lt;T&gt;</code> and invoked later using <code>.get()</code>.</p></li></ul><p>Example:</p><pre><code><code>Supplier&lt;String&gt; lazySupplier = () -&gt; "Hello, World!";</code></code></pre><p>At runtime, the JVM creates an instance of a synthetic class implementing <code>Supplier&lt;String&gt;</code>, where <code>get()</code> returns <code>"Hello, World!"</code> when called.</p><div><hr></div><h2><strong>Understanding the Lazy Execution of </strong><code>Supplier&lt;T&gt;</code></h2><p>Let&#8217;s consider a slightly more interesting example. Suppose we have a method that retrieves data from an external service:</p><pre><code><code>class DataService {
    public String fetchData() {
        System.out.println("Fetching data...");
        return "Data from API";
    }
}</code></code></pre><p>If we create a <code>Supplier&lt;String&gt;</code> using a method reference:</p><pre><code><code>DataService service = new DataService();
Supplier&lt;String&gt; dataSupplier = service::fetchData;</code></code></pre><h3><strong>What happens here?</strong></h3><ol><li><p><strong>No API call is made yet</strong> &#8211; <code>service::fetchData</code> is just a reference, not an execution.</p></li><li><p>When <code>.get()</code> is called, <strong>only then</strong> does <code>fetchData()</code> execute.</p></li></ol><p>Here&#8217;s a full example demonstrating this behavior:</p><pre><code><code>public class LazyLoadingExample {
    public static void main(String[] args) {
        DataService service = new DataService();
        Supplier&lt;String&gt; dataSupplier = service::fetchData;
        
        System.out.println("Before calling get()");
        String result = dataSupplier.get();  // Triggers the actual API call
        System.out.println("Result: " + result);
    }
}</code></code></pre><h3><strong>Console Output:</strong></h3><pre><code><code>Before calling get()
Fetching data...
Result: Data from API</code></code></pre><p>As you can see, <code>fetchData()</code> is <strong>not executed at the time of supplier creation</strong>, only when <code>.get()</code> is called.</p><div><hr></div><h2><strong>How Dependency Injection Works with </strong><code>Supplier&lt;T&gt;</code></h2><p>A natural follow-up question is:<br><em>"If the service is injected using a dependency injection (DI) framework like Spring, will it still work?"</em></p><p>Let&#8217;s see how <code>Supplier&lt;T&gt;</code> interacts with DI.</p><h3><strong>Spring Example</strong></h3><pre><code><code>@Service
class DataService {
    public String fetchData() {
        System.out.println("Fetching data from REST API...");
        return "Data from API";
    }
}

@Component
class ConsumerComponent {
    private final DataService dataService;

    @Autowired
    public ConsumerComponent(DataService dataService) {
        this.dataService = dataService;
    }

    public void execute() {
        Supplier&lt;String&gt; dataSupplier = dataService::fetchData;

        System.out.println("Before calling get()");
        System.out.println("Fetched: " + dataSupplier.get()); // Triggers API call
    }
}</code></code></pre><p>Spring&#8217;s dependency injection ensures that <code>dataService</code> is available when needed, and lazy evaluation means that the API call happens only when requested.</p><div><hr></div><h2><strong>Real-World Use Cases for </strong><code>Supplier&lt;T&gt;</code></h2><ol><li><p><strong>Avoiding Unnecessary Computations</strong></p></li></ol><pre><code><code>public void process(Supplier&lt;String&gt; expensiveOperation) {
    if (shouldUseResult()) {
        System.out.println(expensiveOperation.get()); // Only called if needed
    }
}</code></code></pre><ol><li><p><strong>Lazy Initialization</strong></p></li></ol><pre><code><code>private Supplier&lt;Connection&gt; connectionSupplier = this::createConnection;</code></code></pre><ol><li><p><strong>Deferred Logging</strong></p></li></ol><pre><code><code>private static void log(Supplier&lt;String&gt; message) {
    if (isDebugEnabled()) {
        System.out.println(message.get());
    }
}</code></code></pre><div><hr></div><h2><strong>Key Takeaways</strong></h2><ul><li><p><code>Supplier&lt;T&gt;</code> is a <strong>functional interface</strong> that provides a value <strong>on demand</strong>.</p></li><li><p>When passing a method reference (<code>service::fetchData</code>), <strong>no execution happens until </strong><code>.get()</code><strong> is called</strong>.</p></li><li><p>In Spring DI, injected services <strong>work as expected</strong>, and lazy evaluation ensures API calls are made only when needed.</p></li><li><p>Common use cases include <strong>avoiding unnecessary computations</strong>, <strong>lazy initialization</strong>, and <strong>performance optimization</strong>.</p></li></ul><div><hr></div><p>Understanding how <code>Supplier&lt;T&gt;</code> works under the hood helps us write more efficient and performant code while leveraging modern Java practices.</p><p>If you&#8217;ve used <code>Supplier&lt;T&gt;</code> in an interesting way, I&#8217;d love to hear about it! Let&#8217;s continue the discussion in the comments.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CJFn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63268925-ec49-4373-8dbc-21f72558ee4a_672x356.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CJFn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63268925-ec49-4373-8dbc-21f72558ee4a_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!CJFn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63268925-ec49-4373-8dbc-21f72558ee4a_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!CJFn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63268925-ec49-4373-8dbc-21f72558ee4a_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!CJFn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63268925-ec49-4373-8dbc-21f72558ee4a_672x356.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CJFn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63268925-ec49-4373-8dbc-21f72558ee4a_672x356.webp" width="110" height="58.273809523809526" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/63268925-ec49-4373-8dbc-21f72558ee4a_672x356.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:356,&quot;width&quot;:672,&quot;resizeWidth&quot;:110,&quot;bytes&quot;:10010,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/159694528?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63268925-ec49-4373-8dbc-21f72558ee4a_672x356.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CJFn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63268925-ec49-4373-8dbc-21f72558ee4a_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!CJFn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63268925-ec49-4373-8dbc-21f72558ee4a_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!CJFn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63268925-ec49-4373-8dbc-21f72558ee4a_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!CJFn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63268925-ec49-4373-8dbc-21f72558ee4a_672x356.webp 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div><hr></div><h3>Articles I enjoyed this week</h3><ul><li><p><strong><a href="https://sketechnews.substack.com/p/apache-kafka-tutorial">Apache Kafka &#128293; Your Gateway to High-Demand Jobs - Sketech #22</a></strong> by <strong><a href="https://substack.com/@heynina101">Nina</a></strong></p></li><li><p><strong><a href="https://softwarefrontier.substack.com/p/databricks-photon-engine-boosting">Databricks Photon Engine: Boosting Query Performance and Optimizing Big Data Processing</a></strong> by <a href="https://substack.com/@lorenzobradanini">Lorenzo Bradanini</a> </p></li></ul><div><hr></div><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/is-lazy-loading-really-lazy?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading IT Untold! If you like this article please share it with your friends and colleagues</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/is-lazy-loading-really-lazy?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/p/is-lazy-loading-really-lazy?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p>]]></content:encoded></item><item><title><![CDATA[Java 24 special edition]]></title><description><![CDATA[I'm a Java guy, I cannot miss this one]]></description><link>https://ituntold.rixlabs.dev/p/java-24-special-edition</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/java-24-special-edition</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Tue, 18 Mar 2025 17:02:09 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!rV2w!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea9c5cef-e66b-414e-83b1-b31d14ffcde8_2024x1464.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Java 24 (JDK 24), released today, March 18, 2025, introduces a variety of new functionalities and enhancements aimed at improving developer productivity, runtime performance, and language capabilities. Below is an overview of the key features, categorized by their status (permanent, preview, incubator, or experimental) based on the Java Enhancement Proposals (JEPs) integrated into this release.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rV2w!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea9c5cef-e66b-414e-83b1-b31d14ffcde8_2024x1464.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rV2w!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea9c5cef-e66b-414e-83b1-b31d14ffcde8_2024x1464.png 424w, https://substackcdn.com/image/fetch/$s_!rV2w!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea9c5cef-e66b-414e-83b1-b31d14ffcde8_2024x1464.png 848w, https://substackcdn.com/image/fetch/$s_!rV2w!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea9c5cef-e66b-414e-83b1-b31d14ffcde8_2024x1464.png 1272w, https://substackcdn.com/image/fetch/$s_!rV2w!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea9c5cef-e66b-414e-83b1-b31d14ffcde8_2024x1464.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rV2w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea9c5cef-e66b-414e-83b1-b31d14ffcde8_2024x1464.png" width="1456" height="1053" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ea9c5cef-e66b-414e-83b1-b31d14ffcde8_2024x1464.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1053,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1730411,&quot;alt&quot;:&quot;Java 24&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/159255338?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea9c5cef-e66b-414e-83b1-b31d14ffcde8_2024x1464.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Java 24" title="Java 24" srcset="https://substackcdn.com/image/fetch/$s_!rV2w!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea9c5cef-e66b-414e-83b1-b31d14ffcde8_2024x1464.png 424w, https://substackcdn.com/image/fetch/$s_!rV2w!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea9c5cef-e66b-414e-83b1-b31d14ffcde8_2024x1464.png 848w, https://substackcdn.com/image/fetch/$s_!rV2w!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea9c5cef-e66b-414e-83b1-b31d14ffcde8_2024x1464.png 1272w, https://substackcdn.com/image/fetch/$s_!rV2w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea9c5cef-e66b-414e-83b1-b31d14ffcde8_2024x1464.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p><strong>Permanent Features</strong></p><p>These features are finalized and fully integrated into JDK 24:</p><ol><li><p><strong>Ahead-of-Time Class Loading &amp; Linking (JEP 483)</strong></p><ul><li><p>Part of Project Leyden, this feature improves JVM startup time by making an application's classes instantly available in a loaded and linked state when the JVM starts. It builds on Application Class Data Sharing (AppCDS) to reduce overhead, particularly beneficial for short-lived programs or cloud-based applications.</p></li></ul></li><li><p><strong>Class-File API (JEP 484)</strong></p><ul><li><p>A standardized API for parsing, generating, and transforming Java class files, now finalized after previews in JDK 22 and 23. It serves as an internal replacement for ASM in the JDK and supports tools and frameworks like Spring and Hibernate that manipulate bytecode.</p></li></ul></li><li><p><strong>Stream Gatherers (JEP 485)</strong></p><ul><li><p>Enhances the Stream API by allowing developers to define custom intermediate operations. This makes stream pipelines more flexible and expressive, enabling operations on infinite streams. The java.util.stream.Gatherers class provides standard implementations, and developers can create their own using functional interfaces like Integrator.</p></li></ul></li><li><p><strong>Synchronize Virtual Threads without Pinning (JEP 486)</strong></p><ul><li><p>Improves virtual thread performance by eliminating pinning (where a virtual thread remains tied to a platform thread) when using synchronized blocks or methods around blocking operations. This makes virtual threads more practical for a wider range of use cases.</p></li></ul></li><li><p><strong>Key Derivation Function API (JEP 478)</strong></p><ul><li><p>Introduces a new javax.crypto.KDF API for key derivation functions, enabling cryptographic algorithms like HMAC-based Extract-and-Expand (HKDF) and Argon2. This supports post-quantum cryptography efforts, such as Hybrid Public Key Encryption (HPKE), and enhances security for applications interacting with cryptographic hardware.</p></li></ul></li><li><p><strong>Late Barrier Expansion for G1 (JEP 491)</strong></p><ul><li><p>Optimizes the G1 garbage collector by shifting barrier expansion (used to track memory accesses) to a later stage in the C2 JIT compilation pipeline, simplifying implementation and potentially improving performance.</p></li></ul></li><li><p><strong>Remove the Windows 32-bit x86 Port (JEP 479)</strong></p><ul><li><p>Discontinues support for the 32-bit Windows x86 JVM, following its deprecation in JDK 21, as modern hardware overwhelmingly uses 64-bit architectures.</p></li></ul></li><li><p><strong>Permanently Disable the Security Manager (JEP 493)</strong></p><ul><li><p>Removes the Security Manager entirely (deprecated since JDK 17), reflecting its diminished role in modern Java security. Applications relying on it may require architectural changes.</p></li></ul></li><li><p><strong>ZGC: Remove the Non-Generational Mode (JEP 490)</strong></p><ul><li><p>Eliminates the non-generational mode of the Z Garbage Collector, streamlining maintenance and focusing on the generational mode, which is more efficient for most use cases.</p></li></ul></li><li><p><strong>Warn upon Use of Memory-Access Methods in sun.misc.Unsafe (JEP 498)</strong></p><ul><li><p>Issues runtime warnings when memory-access methods in sun.misc.Unsafe are invoked, encouraging migration to safer alternatives like the VarHandle API or Foreign Function &amp; Memory API.</p></li></ul></li><li><p><strong>Deprecate the 32-bit Linux x86 Port for Removal (JEP 501)</strong></p><ul><li><p>Marks the 32-bit Linux x86 port as deprecated, with removal planned for a future release, aligning with the shift away from 32-bit architectures.</p></li></ul></li><li><p><strong>Linking Runtime Images without JMODs (JEP 482)</strong></p><ul><li><p>Allows jlink to create custom runtime images without JMOD files when built with the --enable-linkable-runtime option, reducing image size for cloud-optimized deployments.</p></li></ul></li></ol><p><strong>Preview Features</strong></p><p>These features are fully implemented but subject to change based on feedback:</p><ol><li><p><strong>Scoped Values (Fourth Preview) (JEP 487)</strong></p><ul><li><p>Enables sharing immutable data within and across threads more efficiently than thread-local variables. This fourth preview refines the feature introduced in JDK 20.</p></li></ul></li><li><p><strong>Primitive Types in Patterns, instanceof, and switch (Second Preview) (JEP 488)</strong></p><ul><li><p>Extends pattern matching to support primitive types in instanceof and switch statements, enhancing expressiveness (introduced in JDK 23).</p></li></ul></li><li><p><strong>Flexible Constructor Bodies (Second Preview) (JEP 492)</strong></p><ul><li><p>Allows more natural initialization logic in constructors by permitting statements before super() calls, reducing reliance on auxiliary methods (introduced in JDK 23).</p></li></ul></li><li><p><strong>Module Import Declarations (Second Preview) (JEP 494)</strong></p><ul><li><p>Simplifies importing all packages exported by a module with a single declaration, improving modularity (introduced in JDK 23).</p></li></ul></li><li><p><strong>Simple Source Files and Instance Main Methods (Fourth Preview) (JEP 495)</strong></p><ul><li><p>Evolves the Java language to ease beginners into programming by supporting streamlined single-class programs with implicit declarations (refined since JDK 21).</p></li></ul></li><li><p><strong>Structured Concurrency (Fourth Preview) (JEP 499)</strong></p><ul><li><p>Simplifies multithreaded programming by treating groups of related tasks as a single unit, enhancing reliability and observability (refined since JDK 21).</p></li></ul></li></ol><p><strong>Incubator Features</strong></p><p>These are still in development and provided for early feedback:</p><ol><li><p><strong>Vector API (Ninth Incubator) (JEP 489)</strong></p><ul><li><p>Enhances vector computations for performance on modern CPUs, adding support for 16-bit floats (Float16) and refining operations. It remains in incubation until Project Valhalla&#8217;s features mature.</p></li></ul></li></ol><p><strong>Experimental Features</strong></p><p>These are exploratory and disabled by default:</p><ol><li><p><strong>Generational Shenandoah (JEP 404)</strong></p><ul><li><p>Introduces an experimental generational mode to the Shenandoah garbage collector, aiming to reduce pause times by separating young and old objects.</p></li></ul></li><li><p><strong>Compact Object Headers (JEP 450)</strong></p><ul><li><p>Reduces object header size from 96-128 bits to 64 bits on 64-bit architectures (Project Lilliput), lowering memory usage but requiring explicit enabling due to potential risks.</p></li></ul></li><li><p><strong>Quantum-Resistant Module-Lattice-Based Key Encapsulation Mechanism (JEP 496)</strong></p><ul><li><p>Provides an implementation of a quantum-resistant key encapsulation mechanism (ML-KEM, FIPS 203), enhancing cryptographic security.</p></li></ul></li><li><p><strong>Quantum-Resistant Module-Lattice-Based Digital Signature Algorithm (JEP 497)</strong></p><ul><li><p>Implements a quantum-resistant digital signature algorithm (ML-DSA, FIPS 204), complementing JEP 496 for post-quantum cryptography.</p></li></ul></li></ol><p><strong>Additional Notes</strong></p><ul><li><p><strong>Performance and Internal Changes</strong>: Features like Ahead-of-Time Class Loading, Compact Object Headers, and G1 optimizations target runtime efficiency, particularly for cloud and serverless environments.</p></li><li><p><strong>Deprecations and Removals</strong>: The removal of legacy components (e.g., Windows 32-bit port, Security Manager) reflects Java&#8217;s focus on modern platforms and security practices.</p></li><li><p><strong>Preview Continuity</strong>: Many preview features are iterations of prior work under projects like Amber (pattern matching, module imports), Loom (virtual threads, structured concurrency), and Panama (Vector API), indicating ongoing refinement.</p></li></ul><p>Java 24 is a non-LTS release, supported for six months until JDK 25 (an LTS release) arrives in September 2025. Developers can explore these features to prepare for future standards while leveraging immediate benefits in performance and flexibility. For detailed examples and usage, the official JDK 24 documentation and JEP pages provide comprehensive resources.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://ko-fi.com/rixlabs" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!27G4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8497f-ecfe-4802-90cc-702242cedd92_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!27G4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8497f-ecfe-4802-90cc-702242cedd92_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!27G4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8497f-ecfe-4802-90cc-702242cedd92_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!27G4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8497f-ecfe-4802-90cc-702242cedd92_672x356.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!27G4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8497f-ecfe-4802-90cc-702242cedd92_672x356.webp" width="124" height="65.69047619047619" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0de8497f-ecfe-4802-90cc-702242cedd92_672x356.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:356,&quot;width&quot;:672,&quot;resizeWidth&quot;:124,&quot;bytes&quot;:10010,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:&quot;https://ko-fi.com/rixlabs&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/159255338?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8497f-ecfe-4802-90cc-702242cedd92_672x356.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!27G4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8497f-ecfe-4802-90cc-702242cedd92_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!27G4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8497f-ecfe-4802-90cc-702242cedd92_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!27G4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8497f-ecfe-4802-90cc-702242cedd92_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!27G4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0de8497f-ecfe-4802-90cc-702242cedd92_672x356.webp 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p>]]></content:encoded></item><item><title><![CDATA[Beyond Documentation: The Art of Technical Writing for Engineers]]></title><description><![CDATA[How to craft insightful, engaging, and valuable tech content that resonates with a wider audience.]]></description><link>https://ituntold.rixlabs.dev/p/beyond-documentation-the-art-of-technical</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/beyond-documentation-the-art-of-technical</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Sun, 16 Mar 2025 07:01:48 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Vgut!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab68c13e-c83c-45c2-a121-d50135c12f5d_1802x1248.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Technical writing is a skill that many engineers develop naturally&#8212;whether through documentation, internal guides, or design proposals. However, writing for a public audience is a different craft. Unlike documentation, which is typically written for precision and completeness, public-facing technical content must be compelling, engaging, and instructional while also helping to establish a personal brand.</p><p>Learning to write compelling public technical content is a journey, and I&#8217;m still in the middle of it&#8212;learning and improving every day. Writing is a craft that evolves with practice, and the more we write, the better we understand how to connect with an audience.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Vgut!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab68c13e-c83c-45c2-a121-d50135c12f5d_1802x1248.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Vgut!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab68c13e-c83c-45c2-a121-d50135c12f5d_1802x1248.png 424w, https://substackcdn.com/image/fetch/$s_!Vgut!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab68c13e-c83c-45c2-a121-d50135c12f5d_1802x1248.png 848w, https://substackcdn.com/image/fetch/$s_!Vgut!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab68c13e-c83c-45c2-a121-d50135c12f5d_1802x1248.png 1272w, https://substackcdn.com/image/fetch/$s_!Vgut!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab68c13e-c83c-45c2-a121-d50135c12f5d_1802x1248.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Vgut!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab68c13e-c83c-45c2-a121-d50135c12f5d_1802x1248.png" width="1456" height="1008" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ab68c13e-c83c-45c2-a121-d50135c12f5d_1802x1248.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1008,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2247335,&quot;alt&quot;:&quot;Beyond Documentation: The Art of Technical Writing for Engineers&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/159068125?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab68c13e-c83c-45c2-a121-d50135c12f5d_1802x1248.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Beyond Documentation: The Art of Technical Writing for Engineers" title="Beyond Documentation: The Art of Technical Writing for Engineers" srcset="https://substackcdn.com/image/fetch/$s_!Vgut!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab68c13e-c83c-45c2-a121-d50135c12f5d_1802x1248.png 424w, https://substackcdn.com/image/fetch/$s_!Vgut!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab68c13e-c83c-45c2-a121-d50135c12f5d_1802x1248.png 848w, https://substackcdn.com/image/fetch/$s_!Vgut!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab68c13e-c83c-45c2-a121-d50135c12f5d_1802x1248.png 1272w, https://substackcdn.com/image/fetch/$s_!Vgut!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab68c13e-c83c-45c2-a121-d50135c12f5d_1802x1248.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>So how does an engineer transition from writing structured documentation to crafting public tech content that resonates? This article explores the nuances of public technical writing, the mindset shift required, and how engineers can develop a unique voice that builds a following.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><h2><strong>The Key Difference: Documentation vs. Public Technical Writing</strong></h2><p>Many engineers equate technical writing with documentation&#8212;after all, writing API references, architecture diagrams, and system design documents is an essential part of software development. But documentation serves a different purpose than public writing:</p><ul><li><p><strong>Documentation is structured, exhaustive, and neutral.</strong> It&#8217;s meant to be referenced, not necessarily read from start to finish. Clarity and completeness are more important than engagement.</p></li><li><p><strong>Public writing is engaging, opinionated, and designed to teach or persuade.</strong> The goal is to capture interest, provide insight, and sometimes even entertain. It doesn&#8217;t just inform&#8212;it tells a story.</p></li></ul><p>When you write documentation, you assume the reader needs to know exactly how something works. But when you write for a public audience, you assume the reader needs to be drawn in before they even decide to care. This requires a shift from structuring information to structuring a narrative.</p><h2><strong>Write About What You Learn</strong></h2><p>One of the best ways to improve as a technical writer is to write about what you are learning. Sharing new concepts, ideas, and challenges not only reinforces your own understanding but also helps others who might be on the same journey. Writing about what you learn makes it easier to remember and apply the concepts in real-world scenarios. Additionally, it creates a sense of relatability with your readers, as they see your growth and can connect with similar experiences.</p><p>By documenting your learning process, you also establish yourself as someone who is continuously evolving, which can be inspiring to your audience. Even if you&#8217;re not an expert on a topic, writing about it from a learner&#8217;s perspective can provide valuable insights to others who are just starting.</p><h2><strong>Developing an Engaging Writing Style</strong></h2><p>Public technical writing isn&#8217;t just about <em>what</em> you say&#8212;it&#8217;s about <em>how</em> you say it. A few characteristics make public tech content stand out:</p><ul><li><p><strong>Conversational yet authoritative tone</strong> &#8211; The best public-facing technical writing balances clarity with personality. It&#8217;s not as rigid as documentation but still maintains credibility.</p></li><li><p><strong>Storytelling and real-world examples</strong> &#8211; Instead of just explaining how a technology works, illustrate why it matters. Case studies, failures, and personal experiences make content relatable.</p></li><li><p><strong>Layered complexity</strong> &#8211; Unlike documentation, which often assumes the reader has already committed to learning, public writing should ease the reader in, starting with an accessible explanation before diving into depth.</p></li></ul><p>Technical concepts don&#8217;t need to be dry. Think of your content as a conversation with an intelligent but skeptical reader&#8212;someone who needs to be convinced that what you&#8217;re writing is worth their time.</p><h2><strong>Choosing the Right Topics</strong></h2><p>A key difference between documentation and public writing is that documentation tells people <em>how</em> something works, while public writing often explores <em>why</em> it matters.</p><p>Some of the best public-facing technical content falls into these broad categories:</p><ul><li><p><strong>Explaining complex topics simply</strong> &#8211; Distilling a challenging concept into an accessible explanation is an invaluable skill.</p></li><li><p><strong>Sharing lessons from experience</strong> &#8211; Writing about mistakes, lessons learned, or unconventional insights adds authenticity.</p></li><li><p><strong>Exploring trends and opinions</strong> &#8211; Well-reasoned opinions on where technology is headed can spark discussion and engagement.</p></li><li><p><strong>Guiding career and skill growth</strong> &#8211; Technical readers appreciate insights on how to improve in their field.</p></li></ul><p>The best topics come from experience&#8212;things you&#8217;ve struggled with, problems you&#8217;ve solved, and ideas you&#8217;ve tested. If something surprised you or changed how you think, it will likely resonate with others.</p><h2><strong>Building a Personal Brand Through Writing</strong></h2><p>Public technical writing isn&#8217;t just about sharing knowledge&#8212;it&#8217;s about building a reputation. Your writing becomes part of your online presence, shaping how others perceive your expertise.</p><ul><li><p><strong>Find your niche</strong> &#8211; Writing consistently about a specific area (e.g., cloud architecture, DevOps, or programming practices) helps establish you as an authority.</p></li><li><p><strong>Develop a unique voice</strong> &#8211; A distinctive perspective or writing style makes your content memorable. Avoid sounding like generic documentation.</p></li><li><p><strong>Engage with your audience</strong> &#8211; Writing isn&#8217;t a one-way street. Engaging with readers through comments, discussions, or follow-up posts helps build a following.</p></li></ul><p>A strong personal brand is built through consistency. One well-written article won&#8217;t make you known, but regular, high-quality posts will.</p><div><hr></div><p>Like any skill, technical writing improves with time and practice. I&#8217;m still learning, refining my style, and discovering what resonates with readers. The important thing is to start, experiment, and continuously learn from both successes and failures.</p><p>For engineers, transitioning from documentation to public technical writing requires a shift in approach. It&#8217;s about moving from structured information delivery to storytelling, engagement, and insight-sharing. The best public technical writers don&#8217;t just inform&#8212;they capture attention, challenge perspectives, and add value beyond what documentation provides.</p><p>By focusing on clear, engaging writing and developing a personal brand, engineers can build an audience that values their insights. Whether through blog posts, newsletters, or social media, good public technical writing can open doors, create connections, and establish a lasting presence in the tech community.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://ko-fi.com/rixlabs" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!D-YM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a556589-79b5-4a43-9536-6ee8e68b2a28_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!D-YM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a556589-79b5-4a43-9536-6ee8e68b2a28_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!D-YM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a556589-79b5-4a43-9536-6ee8e68b2a28_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!D-YM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a556589-79b5-4a43-9536-6ee8e68b2a28_672x356.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!D-YM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a556589-79b5-4a43-9536-6ee8e68b2a28_672x356.webp" width="114" height="60.392857142857146" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6a556589-79b5-4a43-9536-6ee8e68b2a28_672x356.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:356,&quot;width&quot;:672,&quot;resizeWidth&quot;:114,&quot;bytes&quot;:10010,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:&quot;https://ko-fi.com/rixlabs&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/159068125?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a556589-79b5-4a43-9536-6ee8e68b2a28_672x356.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!D-YM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a556589-79b5-4a43-9536-6ee8e68b2a28_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!D-YM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a556589-79b5-4a43-9536-6ee8e68b2a28_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!D-YM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a556589-79b5-4a43-9536-6ee8e68b2a28_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!D-YM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a556589-79b5-4a43-9536-6ee8e68b2a28_672x356.webp 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div><hr></div><h3>Articles I enjoyed this week</h3><ul><li><p><strong><a href="https://newsletter.systemdesigncodex.com/p/transform-your-codebase-to-intuitive">Transform Your Codebase to Intuitive Diagrams in a Few Seconds</a></strong> by The Master of Diagrams himself <strong><a href="https://substack.com/@saurabhdashora">Saurabh Dashora</a></strong></p></li><li><p><a href="https://softwarefrontier.substack.com/p/system-design-simplified-a-beginners-573">System Design Simplified: A Beginner's Guide to Everything You Need to Know (Part 11.1)</a> by <strong><a href="https://substack.com/@lorenzobradanini">Lorenzo Bradanini</a></strong></p></li><li><p><a href="https://newsletter.systemdesignclassroom.com/p/the-architecture-that-gets-you-here">The Architecture That Gets You Here Won&#8217;t Take You There</a> by <a href="https://substack.com/@rauljuncov">Raul Junco</a></p></li></ul><div><hr></div><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/beyond-documentation-the-art-of-technical?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading IT Untold! If you like this article please share it with your friends and colleagues</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/beyond-documentation-the-art-of-technical?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/p/beyond-documentation-the-art-of-technical?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p>]]></content:encoded></item><item><title><![CDATA[Key concept of System design going backward]]></title><description><![CDATA[I left out some important informations and I want to make things right]]></description><link>https://ituntold.rixlabs.dev/p/key-concept-of-system-design-going</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/key-concept-of-system-design-going</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Tue, 11 Mar 2025 17:04:13 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!SU8W!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7284f4ed-e95b-4964-a55f-2d951d16a606_1746x1284.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Going back to my article about system design, I realized that I took some concepts for granted.</p><p>To make good decisions when designing a system, a solid understanding of the key technologies required to build such a platform is essential.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SU8W!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7284f4ed-e95b-4964-a55f-2d951d16a606_1746x1284.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SU8W!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7284f4ed-e95b-4964-a55f-2d951d16a606_1746x1284.png 424w, https://substackcdn.com/image/fetch/$s_!SU8W!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7284f4ed-e95b-4964-a55f-2d951d16a606_1746x1284.png 848w, https://substackcdn.com/image/fetch/$s_!SU8W!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7284f4ed-e95b-4964-a55f-2d951d16a606_1746x1284.png 1272w, https://substackcdn.com/image/fetch/$s_!SU8W!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7284f4ed-e95b-4964-a55f-2d951d16a606_1746x1284.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SU8W!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7284f4ed-e95b-4964-a55f-2d951d16a606_1746x1284.png" width="1456" height="1071" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7284f4ed-e95b-4964-a55f-2d951d16a606_1746x1284.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1071,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2648889,&quot;alt&quot;:&quot;Three pillars of our Discord clone&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/158857677?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7284f4ed-e95b-4964-a55f-2d951d16a606_1746x1284.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Three pillars of our Discord clone" title="Three pillars of our Discord clone" srcset="https://substackcdn.com/image/fetch/$s_!SU8W!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7284f4ed-e95b-4964-a55f-2d951d16a606_1746x1284.png 424w, https://substackcdn.com/image/fetch/$s_!SU8W!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7284f4ed-e95b-4964-a55f-2d951d16a606_1746x1284.png 848w, https://substackcdn.com/image/fetch/$s_!SU8W!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7284f4ed-e95b-4964-a55f-2d951d16a606_1746x1284.png 1272w, https://substackcdn.com/image/fetch/$s_!SU8W!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7284f4ed-e95b-4964-a55f-2d951d16a606_1746x1284.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h1>3 Core Technologies Behind Real-Time Communication Apps </h1><p>Building a real-time communication platform requires more than just a sleek UI and scalable infrastructure. At its core, such an application relies on key technologies that enable instant messaging, seamless API interactions, and high-quality voice and video calls. While many developers are familiar with REST APIs and basic WebSockets, fewer have worked with the powerful protocols that make these platforms truly fast and scalable.</p><p>In this article, I want to highlight three essential but often overlooked technologies: <strong>WebSockets, gRPC, and WebRTC</strong>. These are the foundation of a <strong>Discord clone</strong>, yet many engineers,especially those new to system design,may not have had the chance to work with them in depth. By understanding their roles, strengths, and trade-offs, you can better design and optimize real-time applications.</p><p>Let&#8217;s dive into each of these technologies and explore why they are essential for a modern <strong>Discord clone</strong>.</p><h2><strong>1. WebSockets &#8211; Enabling Real-Time Messaging</strong></h2><p>At the heart of any instant messaging system lies <strong>WebSockets</strong>, a protocol designed for persistent, two-way communication between clients and servers. Unlike traditional HTTP, which follows a request-response model, WebSockets establish a continuous connection, allowing messages to flow in real time without the overhead of repeatedly opening new connections.</p><h3><strong>Why WebSockets Matter</strong></h3><p>WebSockets are particularly important for chat applications, where real-time message delivery is essential. With WebSockets:</p><ul><li><p>A client receives messages instantly rather than polling the server for updates.</p></li><li><p>Users see presence indicators (e.g., "typing&#8230;" or "online now") with minimal delay.</p></li><li><p>Event-driven interactions, such as notifications or real-time status updates, become seamless.</p></li></ul><h3><strong>How They Work</strong></h3><p>A WebSocket connection begins as an HTTP request, but instead of closing after a response, it <strong>upgrades</strong> to a persistent, bidirectional connection. This allows both the client and server to send and receive messages at any time.</p><p>While WebSockets are powerful, they require careful handling of reconnections, message ordering, and scaling across multiple servers. That&#8217;s where additional technologies come in.</p><h2><strong>2. gRPC &#8211; Efficient API Communication for a Discord Clone</strong></h2><p>While WebSockets handle real-time interactions, a <strong>Discord clone</strong> still needs a reliable way to serve structured API requests, fetching message history, managing user data, handling authentication, and more. Many applications default to RESTful APIs with JSON payloads, but a more efficient alternative exists: <strong>gRPC (gRPC Remote Procedure Call)</strong>.</p><h3><strong>What Makes gRPC Different?</strong></h3><p>gRPC is a modern RPC framework built on <strong>HTTP/2</strong>, offering several advantages over REST APIs:</p><ul><li><p><strong>Binary data over Protobuf</strong> &#8211; Unlike JSON, which is text-based and verbose, gRPC uses <strong>Protocol Buffers (Protobuf)</strong>, a compact and efficient binary format.</p></li><li><p><strong>Multiplexing</strong> &#8211; HTTP/2 allows multiple requests to be sent and received simultaneously over a single connection, reducing latency.</p></li><li><p><strong>Built-in streaming</strong> &#8211; gRPC natively supports <strong>bidirectional streaming</strong>, making it a powerful choice for live updates.</p></li><li><p><strong>Strong typing and auto-generated code</strong> &#8211; Protobuf enforces strict data contracts and generates client and server code automatically, reducing errors and improving maintainability.</p></li></ul><h3><strong>Why gRPC Over REST?</strong></h3><p>For a <strong>Discord clone</strong>, gRPC offers clear benefits in terms of speed and efficiency, especially when handling high-throughput API calls. For example:</p><ul><li><p>Fetching thousands of messages in a channel is significantly faster with gRPC&#8217;s binary format and multiplexed requests.</p></li><li><p>Streaming capabilities allow efficient delivery of real-time updates without requiring a dedicated WebSocket for every API call.</p></li><li><p>Strong typing reduces the risk of API contract mismatches between services.</p></li></ul><p>However, gRPC isn&#8217;t always the right choice for public APIs or third-party integrations, where REST and JSON remain more universally supported. But for internal service-to-service communication, it&#8217;s a game-changer.</p><h2><strong>3. WebRTC &#8211; Powering Real-Time Voice and Video Calls</strong></h2><p>A real-time communication platform wouldn&#8217;t be complete without voice and video capabilities. This is where <strong>WebRTC (Web Real-Time Communication)</strong> comes in. Unlike WebSockets and gRPC, which focus on messaging and data exchange, WebRTC is specifically designed for <strong>low-latency, peer-to-peer audio and video communication</strong>.</p><h3><strong>Why WebRTC Is Essential</strong></h3><p>WebRTC enables <strong>direct</strong> media streaming between users, reducing the need for centralized servers to process and relay audio/video data. This results in:</p><ul><li><p><strong>Lower latency</strong> &#8211; Avoiding unnecessary hops through a backend server keeps voice and video lag to a minimum.</p></li><li><p><strong>Reduced server costs</strong> &#8211; Unlike traditional VoIP systems, WebRTC establishes <strong>peer-to-peer connections</strong> whenever possible.</p></li><li><p><strong>Built-in NAT traversal</strong> &#8211; WebRTC includes mechanisms to work around firewalls and NAT restrictions, making it easier to establish connections even in restrictive network environments.</p></li></ul><h3><strong>How WebRTC Works</strong></h3><p>WebRTC sessions typically involve three key components:</p><ol><li><p><strong>Signaling</strong> &#8211; Before a direct connection is established, WebRTC relies on a signaling process (often using WebSockets or gRPC) to exchange connection details.</p></li><li><p><strong>STUN/TURN Servers</strong> &#8211; These help devices discover their public IP addresses and relay data when direct peer-to-peer connections are not possible.</p></li><li><p><strong>Peer-to-Peer Streaming</strong> &#8211; Once a connection is established, audio and video streams flow directly between users with minimal delay.</p></li></ol><p>WebRTC is what makes Discord&#8217;s voice channels feel so responsive, even when hundreds of users are connected. It&#8217;s also the technology behind many modern video conferencing platforms.</p><h2><strong>Bringing It All Together</strong></h2><p>Building a <strong>Discord clone</strong> isn&#8217;t just about writing code,it&#8217;s about choosing the right technologies to deliver an experience that feels instantaneous and seamless. <strong>WebSockets</strong>, <strong>gRPC</strong>, and <strong>WebRTC</strong> each play a critical role:</p><ul><li><p><strong>WebSockets</strong> enable persistent, bidirectional communication for messaging and live updates.</p></li><li><p><strong>gRPC</strong> provides a fast, efficient way to handle structured API requests and backend communication.</p></li><li><p><strong>WebRTC</strong> powers low-latency voice and video calls through peer-to-peer streaming.</p></li></ul><p>Each of these technologies is powerful on its own, but together they form the backbone of real-time applications like a <strong>Discord clone</strong>. Whether you&#8217;re a junior engineer exploring real-time communication for the first time or a senior architect refining your system design, understanding these technologies will give you the tools to build highly responsive and scalable applications.</p><p>In the next sections, we&#8217;ll dive deeper into each of these technologies, exploring their implementation details, best practices, and potential challenges.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://ko-fi.com/rixlabs" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GqyD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F298ee880-f32c-4ad6-bef0-a53d8dfb9a40_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!GqyD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F298ee880-f32c-4ad6-bef0-a53d8dfb9a40_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!GqyD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F298ee880-f32c-4ad6-bef0-a53d8dfb9a40_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!GqyD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F298ee880-f32c-4ad6-bef0-a53d8dfb9a40_672x356.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GqyD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F298ee880-f32c-4ad6-bef0-a53d8dfb9a40_672x356.webp" width="130" height="68.86904761904762" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/298ee880-f32c-4ad6-bef0-a53d8dfb9a40_672x356.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:356,&quot;width&quot;:672,&quot;resizeWidth&quot;:130,&quot;bytes&quot;:10010,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:&quot;https://ko-fi.com/rixlabs&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/158857677?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F298ee880-f32c-4ad6-bef0-a53d8dfb9a40_672x356.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!GqyD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F298ee880-f32c-4ad6-bef0-a53d8dfb9a40_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!GqyD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F298ee880-f32c-4ad6-bef0-a53d8dfb9a40_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!GqyD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F298ee880-f32c-4ad6-bef0-a53d8dfb9a40_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!GqyD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F298ee880-f32c-4ad6-bef0-a53d8dfb9a40_672x356.webp 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div><hr></div><h3>Articles I enjoyed this week</h3><ul><li><p><strong><a href="https://newsletter.francofernando.com/p/the-shopify-checkout-architecture">The Shopify Checkout Architecture</a></strong> by <strong><a href="https://substack.com/@francofernando">Franco Fernando</a></strong></p></li><li><p><strong><a href="https://codingchallenges.substack.com/p/coding-challenge-85-time-zone-converter">Coding Challenge #85 - Time Zone Converter</a></strong> by <strong><a href="https://substack.com/@johncrickett">John Crickett</a></strong></p></li></ul><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading IT Untold! If you like this article please share it with your friends and colleagues</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[You don't need to be an entrepreneur to profit from Side Projects]]></title><description><![CDATA[I&#8217;ve never really started, or better, finished, a side project.]]></description><link>https://ituntold.rixlabs.dev/p/you-dont-need-to-be-an-entrepreneur</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/you-dont-need-to-be-an-entrepreneur</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Sun, 02 Mar 2025 15:51:29 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!1-hl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b7eb20d-aaed-4ed2-87db-466ce44bb617_1013x732.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I&#8217;ve never really started, or better, finished, a side project. Not a big one, at least. And I regret it.</p><p>I love the saying <em>scratch your own itch</em>. Over the years, I&#8217;ve built small tools to make my life easier. Nothing groundbreaking, but each of them taught me something valuable. Side projects, big or small, are an incredible way to learn. Whether it&#8217;s a basic open-source contribution, a command-line tool to streamline your development workflow, or even a small web app, everything you build reinforces your skills. If you hold yourself to a certain quality standard, side projects become the perfect sandbox to experiment, fail, and improve without pressure.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1-hl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b7eb20d-aaed-4ed2-87db-466ce44bb617_1013x732.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1-hl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b7eb20d-aaed-4ed2-87db-466ce44bb617_1013x732.png 424w, https://substackcdn.com/image/fetch/$s_!1-hl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b7eb20d-aaed-4ed2-87db-466ce44bb617_1013x732.png 848w, https://substackcdn.com/image/fetch/$s_!1-hl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b7eb20d-aaed-4ed2-87db-466ce44bb617_1013x732.png 1272w, https://substackcdn.com/image/fetch/$s_!1-hl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b7eb20d-aaed-4ed2-87db-466ce44bb617_1013x732.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1-hl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b7eb20d-aaed-4ed2-87db-466ce44bb617_1013x732.png" width="1013" height="732" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9b7eb20d-aaed-4ed2-87db-466ce44bb617_1013x732.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:732,&quot;width&quot;:1013,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:886029,&quot;alt&quot;:&quot;You Don't Need to Be an Entrepreneur to Profit from Side Projects&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/158230908?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b7eb20d-aaed-4ed2-87db-466ce44bb617_1013x732.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="You Don't Need to Be an Entrepreneur to Profit from Side Projects" title="You Don't Need to Be an Entrepreneur to Profit from Side Projects" srcset="https://substackcdn.com/image/fetch/$s_!1-hl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b7eb20d-aaed-4ed2-87db-466ce44bb617_1013x732.png 424w, https://substackcdn.com/image/fetch/$s_!1-hl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b7eb20d-aaed-4ed2-87db-466ce44bb617_1013x732.png 848w, https://substackcdn.com/image/fetch/$s_!1-hl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b7eb20d-aaed-4ed2-87db-466ce44bb617_1013x732.png 1272w, https://substackcdn.com/image/fetch/$s_!1-hl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b7eb20d-aaed-4ed2-87db-466ce44bb617_1013x732.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Not everyone wants to start a side project from scratch, and that&#8217;s fine. Open-source software (OSS) projects are an excellent alternative. Find a project you like, look for &#8220;help wanted&#8221; or &#8220;good first issue&#8221; tags, and contribute. If you&#8217;re comfortable, propose a new feature, a utility, or even write tests to improve an existing codebase.</p><p>Side projects aren&#8217;t just for entrepreneurs. You don&#8217;t need to launch a startup or aim for the next big SaaS product to benefit from them. If you&#8217;re thinking about changing jobs or expanding your expertise, a well-documented side project can serve as a portfolio that showcases your skills in a way no resume can. It&#8217;s also an opportunity to familiarize yourself with technologies outside your day job without the constraints of a corporate environment.</p><p>I say all this as someone who never truly built a portfolio of side projects, and I regret it. If you&#8217;re in the same boat, start now. You won&#8217;t regret having something tangible to show for your efforts.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><p></p><h2>Different Types of Side Projects and How to Leverage Them</h2><h3>1. Create a Product That Can Be Sold</h3><p>Some developers turn their side projects into revenue-generating products. This doesn&#8217;t mean you need to quit your job and become a full-time entrepreneur, but building something that others find valuable can be an interesting challenge. It could be a SaaS tool, a mobile app, or even a paid Notion template. Even if it never turns into a full-fledged business, launching a product forces you to think about user experience, scalability, and marketing, skills that are valuable even in a traditional job.</p><h3>2. Contribute to Open-Source Software</h3><p>If starting from scratch feels daunting, contributing to open-source software is one of the best ways to sharpen your skills. It exposes you to real-world codebases, best practices, and collaboration with experienced developers. Many OSS projects welcome contributions of all sizes, from fixing bugs to improving documentation to adding new features. Your contributions not only help the community but also build up your reputation in the industry.</p><h3>3. Build a Tool for Yourself</h3><p>Sometimes the best side projects are the ones you wish already existed. Maybe you need a command-line tool to quickly switch environments, a script to automate a boring task, or a browser extension that streamlines your workflow. These projects may never turn into products, but they serve a practical purpose and often teach you a lot along the way. Plus, if they&#8217;re useful to you, chances are they&#8217;ll be useful to others.</p><h3>4. Experiment with New Technologies</h3><p>If you&#8217;ve been meaning to learn a new programming language, cloud platform, or framework, a side project is the best way to do it. Want to play with IoT? Build a smart home automation project. Curious about mesh networks? Try setting one up and see how it works. The key is to make your learning hands-on, tutorials are great, but nothing beats solving a real problem.</p><h2>Overcoming Common Challenges</h2><p>One of the biggest obstacles to starting (and finishing) a side project is time. Between work, life, and other commitments, it&#8217;s easy to let a side project slip. The key is to set realistic expectations. A side project doesn&#8217;t need to be an immediate success; it just needs to keep moving forward.</p><p>Another challenge is motivation. If you start a project purely for career benefits, you might lose interest quickly. That&#8217;s why it&#8217;s important to pick something that genuinely excites you. Whether it&#8217;s a problem you want to solve, a technology you want to explore, or just a creative outlet, passion will keep you going.</p><p>Finally, perfectionism can be paralyzing. Many developers hesitate to share their work because they think it&#8217;s not good enough. But side projects are supposed to be messy. The best way to learn is to put something out there, get feedback, and improve over time.</p><h2>Balancing Side Projects with Work and Life</h2><p>A common concern is how to balance side projects with a full-time job and personal life. Here are a few ways to make it work:</p><ul><li><p><strong>Set small, achievable goals.</strong> Instead of aiming for a fully completed project, break it into tiny milestones that you can tackle in short sessions.</p></li><li><p><strong>Make it a habit.</strong> Even dedicating just 30 minutes a few times a week can add up over time.</p></li><li><p><strong>Work on things that energize you.</strong> A good side project shouldn&#8217;t feel like extra work&#8212;it should be something you look forward to.</p></li><li><p><strong>Take breaks when needed.</strong> Avoid burnout by recognizing when you need to step away. It&#8217;s okay to pause and return when you feel refreshed.</p></li><li><p><strong>Don&#8217;t feel guilty for taking time off.</strong> If you want to spend a weekend playing video games, traveling, or just relaxing with friends and family, do it. Side projects should be fulfilling, not a source of pressure.</p></li></ul><p>A common concern is how to balance side projects with a full-time job and personal life. Here are a few ways to make it work:</p><ul><li><p><strong>Set small, achievable goals.</strong> Instead of aiming for a fully completed project, break it into tiny milestones that you can tackle in short sessions.</p></li><li><p><strong>Make it a habit.</strong> Even dedicating just 30 minutes a few times a week can add up over time.</p></li><li><p><strong>Work on things that energize you.</strong> A good side project shouldn&#8217;t feel like extra work&#8212;it should be something you look forward to.</p></li><li><p><strong>Take breaks when needed.</strong> Avoid burnout by recognizing when you need to step away. It&#8217;s okay to pause and return when you feel refreshed.</p></li></ul><h2>Showcasing and Promoting Your Work</h2><p>A side project is only as valuable as its visibility. If no one knows about it, it won&#8217;t have much impact. Here&#8217;s how to make sure your efforts don&#8217;t go unnoticed:</p><ul><li><p><strong>Document your work.</strong> Keep a README file updated, write about your process, and explain your decisions.</p></li><li><p><strong>Use GitHub effectively.</strong> Keep your repositories organized, use meaningful commit messages, and make your project approachable for others.</p></li><li><p><strong>Share your journey.</strong> Post updates on LinkedIn, Twitter, or a personal blog. People love following the progress of interesting projects.</p></li><li><p><strong>Engage with communities.</strong> Platforms like Reddit, Dev.to, and Hacker News can be great places to share what you&#8217;re working on and get valuable feedback.</p></li><li><p><strong>Showcase it in job interviews.</strong> A strong side project can be a talking point that demonstrates your technical ability and initiative better than a resume alone.</p></li></ul><h2>How to Make the Most of Your Side Projects and OSS Contributions</h2><ol><li><p><strong>Keep Your Scope Realistic</strong> &#8211; Start small. A tool that automates a tedious task is a great first step. Avoid projects so large that they become overwhelming.</p></li><li><p><strong>Treat It Like Production Code</strong> &#8211; Use version control, write documentation, and follow best practices. The closer it is to real-world standards, the more valuable it becomes for learning and showcasing your skills.</p></li><li><p><strong>Track Your Progress</strong> &#8211; Maintain a simple log or portfolio of what you&#8217;ve built. Even if a project isn&#8217;t finished, documenting what you learned from it makes a difference.</p></li><li><p><strong>Engage with the Community</strong> &#8211; Contribute to OSS, ask for feedback, and learn from others. Seeing how experienced maintainers handle issues and PRs is an education in itself.</p></li><li><p><strong>Know When to Move On</strong> &#8211; Not every side project needs to be maintained forever. If you&#8217;ve learned what you wanted, it&#8217;s okay to move on to something new.</p></li></ol><p>You don&#8217;t need to launch a business to benefit from side projects. You just need to start.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://ko-fi.com/rixlabs" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QFBO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26153b19-8075-4f13-96e9-ef529b243039_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!QFBO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26153b19-8075-4f13-96e9-ef529b243039_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!QFBO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26153b19-8075-4f13-96e9-ef529b243039_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!QFBO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26153b19-8075-4f13-96e9-ef529b243039_672x356.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QFBO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26153b19-8075-4f13-96e9-ef529b243039_672x356.webp" width="124" height="65.69047619047619" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/26153b19-8075-4f13-96e9-ef529b243039_672x356.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:356,&quot;width&quot;:672,&quot;resizeWidth&quot;:124,&quot;bytes&quot;:10010,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:&quot;https://ko-fi.com/rixlabs&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/158230908?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26153b19-8075-4f13-96e9-ef529b243039_672x356.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!QFBO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26153b19-8075-4f13-96e9-ef529b243039_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!QFBO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26153b19-8075-4f13-96e9-ef529b243039_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!QFBO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26153b19-8075-4f13-96e9-ef529b243039_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!QFBO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26153b19-8075-4f13-96e9-ef529b243039_672x356.webp 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div><hr></div><h3>Articles I enjoyed this week</h3><ul><li><p><strong><a href="https://softwarefrontier.substack.com/p/system-design-simplified-a-beginners-807">System Design Simplified: A Beginner's Guide to Everything You Need to Know (Part 9.2)</a></strong> by <strong><a href="https://substack.com/@lorenzobradanini">Lorenzo Bradanini</a></strong><a href="https://substack.com/@lorenzobradanini"> </a></p></li><li><p><strong><a href="https://newsletter.systemdesign.one/p/how-do-websockets-work">How Do Websockets Work &#10024;</a></strong> by <strong><a href="https://substack.com/@systemdesignone">Neo Kim</a></strong></p></li><li><p><strong><a href="https://newsletter.systemdesignclassroom.com/p/testing-in-production-best-practices">I used to think testing in production was a bad joke. I was wrong.</a></strong> by <strong><a href="https://substack.com/@rauljuncov">Raul Junco</a></strong></p></li></ul><div><hr></div><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/you-dont-need-to-be-an-entrepreneur?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading IT Untold! If you like this article please share it with your friends and colleagues</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/you-dont-need-to-be-an-entrepreneur?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/p/you-dont-need-to-be-an-entrepreneur?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p>]]></content:encoded></item><item><title><![CDATA[Key concepts of System design 4 Redux: let's break it down]]></title><description><![CDATA[A building blocks decomposition]]></description><link>https://ituntold.rixlabs.dev/p/key-concepts-of-system-design-4-redux</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/key-concepts-of-system-design-4-redux</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Sun, 23 Feb 2025 19:52:38 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!-C19!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b313efb-b59f-4267-a03b-76c98a4d4bbe_1638x1354.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2><strong>Introduction</strong></h2><p>In a <a href="https://ituntold.rixlabs.dev/p/key-concepts-of-system-design-4-system">previous article of this series</a>, we explored the high-level design of the system, outlining its key components and interactions. Now, we shift our focus to the <strong>backend architecture</strong>, ensuring that we have a solid foundation before we start coding. A well-defined architecture serves as a battle plan, helping to avoid unnecessary complexity, improve maintainability, and facilitate future scalability.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-C19!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b313efb-b59f-4267-a03b-76c98a4d4bbe_1638x1354.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-C19!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b313efb-b59f-4267-a03b-76c98a4d4bbe_1638x1354.png 424w, https://substackcdn.com/image/fetch/$s_!-C19!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b313efb-b59f-4267-a03b-76c98a4d4bbe_1638x1354.png 848w, https://substackcdn.com/image/fetch/$s_!-C19!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b313efb-b59f-4267-a03b-76c98a4d4bbe_1638x1354.png 1272w, https://substackcdn.com/image/fetch/$s_!-C19!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b313efb-b59f-4267-a03b-76c98a4d4bbe_1638x1354.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-C19!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b313efb-b59f-4267-a03b-76c98a4d4bbe_1638x1354.png" width="1456" height="1204" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5b313efb-b59f-4267-a03b-76c98a4d4bbe_1638x1354.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1204,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2570352,&quot;alt&quot;:&quot;Components drill down&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/157729693?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b313efb-b59f-4267-a03b-76c98a4d4bbe_1638x1354.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Components drill down" title="Components drill down" srcset="https://substackcdn.com/image/fetch/$s_!-C19!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b313efb-b59f-4267-a03b-76c98a4d4bbe_1638x1354.png 424w, https://substackcdn.com/image/fetch/$s_!-C19!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b313efb-b59f-4267-a03b-76c98a4d4bbe_1638x1354.png 848w, https://substackcdn.com/image/fetch/$s_!-C19!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b313efb-b59f-4267-a03b-76c98a4d4bbe_1638x1354.png 1272w, https://substackcdn.com/image/fetch/$s_!-C19!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b313efb-b59f-4267-a03b-76c98a4d4bbe_1638x1354.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>In this article, we will explore the <strong>Onion Architecture</strong> and how it is applied within a <strong>modular monolith</strong>. By progressively drilling down from a high-level black box to detailed module structures, we ensure a clear separation of concerns and a scalable design.</p><p>All the diagram in the article are just an example. When designing a solution they should live and evolve. Since I want you to be able to reproduce this kind of documentation for your project I have added the PlantUML code of each diagram.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2><strong>High-Level Black Box View</strong></h2><p>At the highest level, the system consists of two major components:</p><ul><li><p><strong>Frontend</strong>: A React-based web application that communicates with the backend.</p></li><li><p><strong>Backend</strong>: A Spring Boot application handling all business logic and data persistence.</p></li></ul><p><strong>Diagram:</strong></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iT6h!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde66b269-bffa-4d01-a7f7-9b94dcabba26_148x215.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iT6h!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde66b269-bffa-4d01-a7f7-9b94dcabba26_148x215.png 424w, https://substackcdn.com/image/fetch/$s_!iT6h!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde66b269-bffa-4d01-a7f7-9b94dcabba26_148x215.png 848w, https://substackcdn.com/image/fetch/$s_!iT6h!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde66b269-bffa-4d01-a7f7-9b94dcabba26_148x215.png 1272w, https://substackcdn.com/image/fetch/$s_!iT6h!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde66b269-bffa-4d01-a7f7-9b94dcabba26_148x215.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iT6h!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde66b269-bffa-4d01-a7f7-9b94dcabba26_148x215.png" width="148" height="215" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/de66b269-bffa-4d01-a7f7-9b94dcabba26_148x215.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:215,&quot;width&quot;:148,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:8131,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/157729693?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde66b269-bffa-4d01-a7f7-9b94dcabba26_148x215.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!iT6h!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde66b269-bffa-4d01-a7f7-9b94dcabba26_148x215.png 424w, https://substackcdn.com/image/fetch/$s_!iT6h!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde66b269-bffa-4d01-a7f7-9b94dcabba26_148x215.png 848w, https://substackcdn.com/image/fetch/$s_!iT6h!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde66b269-bffa-4d01-a7f7-9b94dcabba26_148x215.png 1272w, https://substackcdn.com/image/fetch/$s_!iT6h!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde66b269-bffa-4d01-a7f7-9b94dcabba26_148x215.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><pre><code><code>@startuml
package "System" {
    [Frontend] --&gt; [Backend]
}
@enduml
</code></code></pre><div><hr></div><h2><strong>Backend Architecture Drill-Down</strong></h2><h3><strong>Black Box View</strong></h3><p>The backend follows a <strong>modular monolith</strong> approach, meaning it consists of multiple independent modules while sharing a common codebase. This design promotes maintainability and scalability without the complexity of microservices.</p><p><strong>Backend Modules:</strong></p><ol><li><p><strong>User Management</strong> (Handles authentication, profiles, and permissions)</p></li><li><p><strong>Messaging</strong> (Manages chat and real-time communication)</p></li><li><p><strong>Channel Management</strong> (Organizes conversations and groups)</p></li><li><p><strong>Notification Service</strong> (Delivers push and in-app notifications)</p></li><li><p><strong>Media Processing</strong> (Handles file uploads, storage, and playback)</p><p></p></li></ol><p>Modules communicate via <strong>synchronous REST APIs</strong> and <strong>asynchronous messaging (Azure Event Hubs)</strong> where necessary.</p><p><strong>Black Box Diagram: Modular Monolith with Modules</strong></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ve4M!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc105a5fb-f036-4b1c-868e-0cde2a9a9cc7_2682x336.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ve4M!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc105a5fb-f036-4b1c-868e-0cde2a9a9cc7_2682x336.png 424w, https://substackcdn.com/image/fetch/$s_!Ve4M!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc105a5fb-f036-4b1c-868e-0cde2a9a9cc7_2682x336.png 848w, https://substackcdn.com/image/fetch/$s_!Ve4M!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc105a5fb-f036-4b1c-868e-0cde2a9a9cc7_2682x336.png 1272w, https://substackcdn.com/image/fetch/$s_!Ve4M!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc105a5fb-f036-4b1c-868e-0cde2a9a9cc7_2682x336.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ve4M!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc105a5fb-f036-4b1c-868e-0cde2a9a9cc7_2682x336.png" width="1456" height="182" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c105a5fb-f036-4b1c-868e-0cde2a9a9cc7_2682x336.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:182,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:80732,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/157729693?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc105a5fb-f036-4b1c-868e-0cde2a9a9cc7_2682x336.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Ve4M!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc105a5fb-f036-4b1c-868e-0cde2a9a9cc7_2682x336.png 424w, https://substackcdn.com/image/fetch/$s_!Ve4M!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc105a5fb-f036-4b1c-868e-0cde2a9a9cc7_2682x336.png 848w, https://substackcdn.com/image/fetch/$s_!Ve4M!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc105a5fb-f036-4b1c-868e-0cde2a9a9cc7_2682x336.png 1272w, https://substackcdn.com/image/fetch/$s_!Ve4M!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc105a5fb-f036-4b1c-868e-0cde2a9a9cc7_2682x336.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p><pre><code><code>@startuml
scale 1.2

package "Backend (Modular Monolith)" {
    package "User Management Module" {
    }
    package "Messaging Module" {
    }
    package "Channel Management Module" {
    }
    package "Notification Service Module" {
    }
    package "Media Processing Module" {
    }
}
"User Management Module" -[hidden]d-&gt; "Messaging Module"

"Channel Management Module" -[hidden]d-&gt; "Messaging Module"

"User Management Module" -[-&gt; "Messaging Module" : "REST API"]
"Messaging Module" -[-&gt; "Notification Service Module" : "Event Hub"]
"Channel Management Module" -[-&gt; "Messaging Module" : "REST API"]
"User Management Module" -[-&gt; "Channel Management Module" : "REST API"]
"Media Processing Module" -[-&gt; "Messaging Module" : "Event Hub"]
@enduml
</code></code></pre><p>Each module is responsible for a distinct business function, ensuring a clear separation of concerns.</p><div><hr></div><h3><strong>White Box View</strong></h3><p>Within each module, we apply <strong>Onion Architecture</strong>, structuring the internals into concentric layers that enforce dependency rules.</p><p><strong>Onion Architecture Layers:</strong></p><ol><li><p><strong>Core Layer (Domain)</strong>: Contains domain models and business rules.</p></li><li><p><strong>Application Layer</strong>: Defines use cases and orchestrates business logic.</p></li><li><p><strong>Infrastructure Layer</strong>: Implements repositories, external integrations, and APIs.</p></li></ol><p>Each module follows this layered approach to maintain a clean architecture.</p><p><strong>White Box Diagram: Internal Structure of Modules with Onion Architecture</strong></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!z1l0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd65a582c-e64c-4b57-b35b-47d305a2c889_2038x343.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!z1l0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd65a582c-e64c-4b57-b35b-47d305a2c889_2038x343.png 424w, https://substackcdn.com/image/fetch/$s_!z1l0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd65a582c-e64c-4b57-b35b-47d305a2c889_2038x343.png 848w, https://substackcdn.com/image/fetch/$s_!z1l0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd65a582c-e64c-4b57-b35b-47d305a2c889_2038x343.png 1272w, https://substackcdn.com/image/fetch/$s_!z1l0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd65a582c-e64c-4b57-b35b-47d305a2c889_2038x343.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!z1l0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd65a582c-e64c-4b57-b35b-47d305a2c889_2038x343.png" width="1456" height="245" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d65a582c-e64c-4b57-b35b-47d305a2c889_2038x343.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:245,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:60859,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/157729693?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd65a582c-e64c-4b57-b35b-47d305a2c889_2038x343.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!z1l0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd65a582c-e64c-4b57-b35b-47d305a2c889_2038x343.png 424w, https://substackcdn.com/image/fetch/$s_!z1l0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd65a582c-e64c-4b57-b35b-47d305a2c889_2038x343.png 848w, https://substackcdn.com/image/fetch/$s_!z1l0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd65a582c-e64c-4b57-b35b-47d305a2c889_2038x343.png 1272w, https://substackcdn.com/image/fetch/$s_!z1l0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd65a582c-e64c-4b57-b35b-47d305a2c889_2038x343.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p><pre><code><code>@startuml
scale 1.2

package "User Management Module" {
    package "Core Layer" {
        class User
        class Role
        class Permission
    }
    package "Application Layer" {
        class UserService
        class AuthService
    }
    package "Infrastructure Layer" {
        class UserRepository
        class AuthProvider
    }
}

package "Messaging Module" {
    package "Core Layer" {
        class Message
        class Conversation
    }
    package "Application Layer" {
        class MessagingService
    }
    package "Infrastructure Layer" {
        class ChatRepository
    }
}

@enduml
</code></code></pre><p>This white box view reveals the internal structure of each module, showing how classes interact within layers while adhering to the Onion Architecture principles.</p><div><hr></div><h2><strong>Why Use Onion Architecture in a Modular Monolith?</strong></h2><ul><li><p><strong>Separation of Concerns</strong>: Business logic remains independent of frameworks.</p></li><li><p><strong>Decoupled Dependencies</strong>: Core business logic does not depend on external services.</p></li><li><p><strong>Explicit Boundaries</strong>: Communication between layers follows well-defined interfaces.</p></li><li><p><strong>Maintainability</strong>: Changes in external technologies don&#8217;t impact the core.</p></li><li><p><strong>Scalability</strong>: Modules can be extracted into microservices if needed later.</p></li><li><p><strong>Testability</strong>: Domain logic can be tested in isolation without external dependencies.</p></li></ul><div><hr></div><p>This structure ensures that the backend remains <strong>well-organized, scalable, and adaptable</strong> while leveraging <strong>Azure technologies</strong> for storage, authentication, and messaging. </p><p></p><p>As said before these diagrams could be incomplete at the moment but they give an idea of what does it mean do decide the main software architecture and document it.</p><p>Let me know if you think I should go deeper, otherwise we will proceed with the next topics: some detail about the technology selection and the deployment view.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://ko-fi.com/rixlabs" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TpmZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11407990-5c8d-4ef9-86f3-7ffa250ec8df_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!TpmZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11407990-5c8d-4ef9-86f3-7ffa250ec8df_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!TpmZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11407990-5c8d-4ef9-86f3-7ffa250ec8df_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!TpmZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11407990-5c8d-4ef9-86f3-7ffa250ec8df_672x356.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TpmZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11407990-5c8d-4ef9-86f3-7ffa250ec8df_672x356.webp" width="124" height="65.69047619047619" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/11407990-5c8d-4ef9-86f3-7ffa250ec8df_672x356.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:356,&quot;width&quot;:672,&quot;resizeWidth&quot;:124,&quot;bytes&quot;:10010,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:&quot;https://ko-fi.com/rixlabs&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ituntold.rixlabs.dev/i/157729693?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11407990-5c8d-4ef9-86f3-7ffa250ec8df_672x356.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!TpmZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11407990-5c8d-4ef9-86f3-7ffa250ec8df_672x356.webp 424w, https://substackcdn.com/image/fetch/$s_!TpmZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11407990-5c8d-4ef9-86f3-7ffa250ec8df_672x356.webp 848w, https://substackcdn.com/image/fetch/$s_!TpmZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11407990-5c8d-4ef9-86f3-7ffa250ec8df_672x356.webp 1272w, https://substackcdn.com/image/fetch/$s_!TpmZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F11407990-5c8d-4ef9-86f3-7ffa250ec8df_672x356.webp 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div><hr></div><h3>Articles I enjoyed this week</h3><ul><li><p><strong><a href="https://prog21.dadgum.com/177.html">Organizational Skills Beat Algorithmic Wizardry</a></strong> by <strong>James Hague</strong></p></li><li><p><strong><a href="https://codingchallenges.substack.com/p/coding-challenge-84-mandelbrot-set">Coding Challenge #84 - Mandelbrot Set Explorer</a></strong> by <strong><a href="https://substack.com/@johncrickett">John Crickett</a></strong></p></li><li><p><strong><a href="https://newsletter.francofernando.com/p/how-not-to-fail-a-coding-interview">How (not to) fail a coding interview</a></strong> by <strong><a href="https://substack.com/@francofernando">Franco Fernando</a></strong> </p></li></ul><p></p><div><hr></div><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/key-concepts-of-system-design-4-redux?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading IT Untold! If you like this article please share it with your friends and colleagues</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/key-concepts-of-system-design-4-redux?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/p/key-concepts-of-system-design-4-redux?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p>]]></content:encoded></item><item><title><![CDATA[The Fear Factor]]></title><description><![CDATA[How Enterprise IT Buys Big, Plays It Safe, and Locks Itself in (No, Not the Show With Joe Rogan)]]></description><link>https://ituntold.rixlabs.dev/p/the-fear-factor</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/the-fear-factor</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Tue, 18 Feb 2025 19:17:16 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!jO0R!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdf9f48-8262-48bd-a454-7b15cf275027_2024x1442.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Enterprise IT is not about innovation, efficiency, or even technology. It&#8217;s about fear, blame, and making sure middle managers can keep their jobs without actually managing anything. The safest way to do that? Buy expensive commercial products, sign million-dollar support contracts, and lock the company into proprietary solutions that will haunt them for decades.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jO0R!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdf9f48-8262-48bd-a454-7b15cf275027_2024x1442.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jO0R!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdf9f48-8262-48bd-a454-7b15cf275027_2024x1442.png 424w, https://substackcdn.com/image/fetch/$s_!jO0R!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdf9f48-8262-48bd-a454-7b15cf275027_2024x1442.png 848w, https://substackcdn.com/image/fetch/$s_!jO0R!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdf9f48-8262-48bd-a454-7b15cf275027_2024x1442.png 1272w, https://substackcdn.com/image/fetch/$s_!jO0R!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdf9f48-8262-48bd-a454-7b15cf275027_2024x1442.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jO0R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdf9f48-8262-48bd-a454-7b15cf275027_2024x1442.png" width="1456" height="1037" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3cdf9f48-8262-48bd-a454-7b15cf275027_2024x1442.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1037,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2203117,&quot;alt&quot;:&quot;The Fear Factor, How Enterprise IT Buys Big, Plays It Safe, and Locks Itself in (No, Not the Show With Joe Rogan)&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The Fear Factor, How Enterprise IT Buys Big, Plays It Safe, and Locks Itself in (No, Not the Show With Joe Rogan)" title="The Fear Factor, How Enterprise IT Buys Big, Plays It Safe, and Locks Itself in (No, Not the Show With Joe Rogan)" srcset="https://substackcdn.com/image/fetch/$s_!jO0R!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdf9f48-8262-48bd-a454-7b15cf275027_2024x1442.png 424w, https://substackcdn.com/image/fetch/$s_!jO0R!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdf9f48-8262-48bd-a454-7b15cf275027_2024x1442.png 848w, https://substackcdn.com/image/fetch/$s_!jO0R!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdf9f48-8262-48bd-a454-7b15cf275027_2024x1442.png 1272w, https://substackcdn.com/image/fetch/$s_!jO0R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdf9f48-8262-48bd-a454-7b15cf275027_2024x1442.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h2>Fear as a Business Model</h2><p>The bigger the company, the more terrified it is of making the "wrong" IT decision. So, instead of empowering teams to build expertise and take control of their technology, they do the safest thing: throw money at a well-known vendor.</p><ul><li><p>Open source? <em>Too risky.</em> "What if there&#8217;s no support?" (As if paid support has ever magically fixed a production outage at 2 AM.)</p></li><li><p>In-house expertise? <em>Too dangerous.</em> "What if they leave?" (Better to rely on expensive consultants who will never truly transfer knowledge.)</p></li><li><p>Flexibility? <em>Too unpredictable.</em> "What if something goes wrong?" (Better to be locked into an outdated product for the next decade.)</p></li></ul><p>And when things inevitably go south, guess what? There&#8217;s always someone to blame the external vendor, the consultant, the software itself. Never the people who made the decision.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>The Middle Manager&#8217;s Best Friend: Expensive Software</h2><p>For middle managers who don't understand tech but need to "own" an initiative, commercial software is a godsend.</p><ol><li><p><strong>They buy it.</strong> (Big budgets make them look important.)</p></li><li><p><strong>They don't have to manage it.</strong> (That's the vendor's problem.)</p></li><li><p><strong>They have a built-in scapegoat.</strong> ("The tool isn't working, let&#8217;s escalate!")</p></li></ol><p>It&#8217;s the perfect cycle. They&#8217;re not measured on results just on whether they <em>purchased</em> the &#8220;best&#8221; solution. Bonus points if the product comes with an army of consultants who will bill triple the cost of an internal team while delivering half the results.</p><h3>Oracle DBMS: The Default Choice for No Reason</h3><p>And if there&#8217;s one product that perfectly represents this mindset, it&#8217;s Oracle DBMS.</p><p>It doesn&#8217;t matter if the company&#8217;s workload could run just fine on PostgreSQL, MySQL, or even a managed cloud database. <strong>If it&#8217;s enterprise IT, Oracle must be considered.</strong> Why?</p><ul><li><p><strong>It&#8217;s expensive.</strong> (And expensive means "serious.")</p></li><li><p><strong>It comes with premium support.</strong> (Which mostly involves escalating tickets until you give up.)</p></li><li><p><strong>It locks you in forever.</strong> (Try migrating off Oracle and see how much fun you have.)</p></li></ul><p>Many enterprises don&#8217;t even question whether they need Oracle. It&#8217;s just assumed to be the right choice because that&#8217;s what <em>other big companies do</em>. It&#8217;s the IT equivalent of buying a Ferrari to drive to the grocery store completely unnecessary, but it makes people feel important.</p><p>And when the licensing costs spiral out of control? "Oh well, it&#8217;s Oracle. What can we do?"</p><p>This is why so many companies are now scrambling to escape Oracle&#8217;s grip after spending <strong>years</strong> and <strong>millions</strong> pretending that nothing else could possibly work.</p><h2>Why Build Knowledge When You Can Overpay for Consultants?</h2><p>Take SAP as a prime example. Instead of building an internal team that actually understands the platform, many enterprises happily pay external consultants three times more than an in-house expert would cost. Why?</p><ul><li><p>If something breaks, <strong>it&#8217;s the consultant&#8217;s fault.</strong></p></li><li><p>If things are slow, <strong>it&#8217;s the system&#8217;s fault.</strong></p></li><li><p>If budgets spiral out of control, <strong>"this is just how enterprise IT works."</strong></p></li></ul><p>Meanwhile, those same consultants ensure the company remains dependent on them by never fully documenting anything, keeping just enough critical knowledge in their own hands.</p><h2>Vendor Lock-in: The Gift That Keeps on Taking</h2><p>And let&#8217;s not forget the ultimate enterprise IT failure: vendor lock-in. The moment you adopt some obscure functionality that <strong>only</strong> works with a single vendor, you're doomed. Need to migrate later? Good luck! The cost and complexity will be so absurd that even suggesting a change will get you laughed out of the room.</p><p>Looking at you, Lotus Notes. A graveyard of unreadable archives, broken workflows, and companies still trying to escape your clutches decades later.</p><h2>The IT Illusion Continues</h2><p>The cycle keeps going because it benefits the wrong people. Enterprises spend billions not on <strong>better</strong> technology, but on <strong>safe</strong> decisions. IT should be about agility, adaptability, and ownership but in too many places, it's just a blame game wrapped in a fat invoice.</p><p>And the best part? When the same company that swore open source was too risky ends up migrating to Kubernetes, embracing Linux, and using PostgreSQL all after spending years and millions fighting against them.</p><p>Because nothing says "enterprise IT strategy" like paying extra to do what should have been obvious from the start.</p><div><hr></div><h2>Breaking the Cycle: How to Convince Management to Consider Alternatives</h2><p>Challenging the status quo in enterprise IT isn&#8217;t easy. The fear-driven mindset, the love for big-name vendors, and the obsession with &#8220;safe&#8221; decisions make it difficult to push for open-source or cost-effective solutions. But it&#8217;s not impossible. Here&#8217;s how you can start shifting the conversation:</p><h3>1. <strong>Speak Their Language: Cost and Risk Reduction</strong></h3><p>Management won&#8217;t care that PostgreSQL is technically superior to Oracle, but they will care about <strong>licensing cost savings</strong> and <strong>reduced vendor dependency</strong>. Instead of arguing about tech specs, frame the discussion around:</p><ul><li><p>How much money the company could save over 3&#8211;5 years.</p></li><li><p>The hidden costs of vendor lock-in and migration difficulties.</p></li><li><p>How avoiding proprietary dependencies makes the company more agile.</p></li></ul><h3>2. <strong>Leverage Success Stories</strong></h3><p>No one wants to be the first to take a risk, but they&#8217;re happy to follow if others have succeeded. Gather case studies of major companies that have successfully adopted open-source alternatives:</p><ul><li><p>Netflix, Uber, and Twitter running on open-source databases.</p></li><li><p>Large financial institutions moving away from Oracle or SAP.</p></li><li><p>Governments adopting Linux and open-source stacks to reduce costs.</p></li></ul><p>Show that open source isn&#8217;t just for startups it&#8217;s a strategic move even for <strong>big</strong> players.</p><h3>3. <strong>Start Small: Pilot Projects and Low-Risk Adoption</strong></h3><p>Instead of proposing a full-scale migration, suggest a <strong>pilot project</strong> using an open-source or alternative tool. For example:</p><ul><li><p>Deploy a <strong>new</strong> application on PostgreSQL instead of Oracle.</p></li><li><p>Run a <strong>non-critical</strong> workload on an open-source solution.</p></li><li><p>Implement a <strong>hybrid approach</strong> where the company can compare results side-by-side.</p></li></ul><p>Once leadership sees it working <strong>without disaster</strong>, they&#8217;ll be more open to expanding it.</p><h3>4. <strong>Expose the Myth of Enterprise Support</strong></h3><p>A key argument against open source is "we need enterprise support." But in reality:</p><ul><li><p>Many "supported" enterprise products have <strong>horrendous</strong> support experiences.</p></li><li><p>Open-source solutions often have <strong>commercial support options</strong> (e.g., Red Hat, Percona, HashiCorp).</p></li><li><p>Internal expertise is often <strong>more effective</strong> than waiting on vendor responses.</p></li></ul><p>Show them real-world examples where companies got burned by expensive &#8220;support&#8221; contracts that delivered little value.</p><h3>5. <strong>Demonstrate the Long-Term Strategic Advantage</strong></h3><p>Proprietary software <strong>locks you into a single vendor&#8217;s roadmap</strong>, while open-source tools give companies the flexibility to adapt and evolve. Position alternatives as <strong>strategic investments</strong> rather than just cost-cutting measures:</p><ul><li><p>Avoiding licensing audits and compliance headaches.</p></li><li><p>Being able to scale or pivot without waiting for vendor updates.</p></li><li><p>Hiring from a broader talent pool (many engineers prefer working with modern, open tools).</p></li></ul><h3>6. <strong>Make It About Business, Not IT</strong></h3><p>At the end of the day, management cares about <strong>business outcomes</strong>, not technology choices. Focus your arguments on:</p><ul><li><p>Faster time to market.</p></li><li><p>Cost efficiency and budget flexibility.</p></li><li><p>Competitive advantage by avoiding rigid, outdated enterprise solutions.</p></li></ul><p>The more you align your pitch with <strong>business goals</strong>, the harder it will be for them to ignore.</p><div><hr></div><p>Enterprise IT&#8217;s love affair with expensive, bloated software won&#8217;t end overnight. But by shifting the conversation, showing real-world successes, and making incremental changes, professionals can help their organizations move toward <strong>smarter, more flexible, and cost-effective solutions</strong>.</p><p>And who knows maybe one day, we&#8217;ll look back at Oracle DBMS, SAP consultants, and Lotus Notes the way we now look at dial-up internet: a necessary evil of the past that we&#8217;re glad to have moved on from.</p><div><hr></div><h3>Articles I enjoyed this week</h3><ul><li><p><strong><a href="https://newsletter.systemdesigncodex.com/p/4-challenges-of-distributed-systems">4 Challenges of Distributed Systems - And Possible Solutions</a></strong> by <strong><a href="https://substack.com/@saurabhdashora">Saurabh Dashora</a></strong></p></li><li><p><strong><a href="https://newsletter.systemdesignclassroom.com/p/what-works-in-a-monolith-can-break">What Works in a Monolith Can Break a Microservice</a></strong> by <strong><a href="https://substack.com/@rauljuncov">Raul Junco</a></strong></p><p></p></li></ul><div><hr></div><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/the-fear-factor?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading IT Untold! If you like this article please share it with your friends and colleagues</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/the-fear-factor?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/p/the-fear-factor?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p>]]></content:encoded></item><item><title><![CDATA[Key concepts of System design 4: System Design]]></title><description><![CDATA[Tech stack and important choices]]></description><link>https://ituntold.rixlabs.dev/p/key-concepts-of-system-design-4-system</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/key-concepts-of-system-design-4-system</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Sun, 09 Feb 2025 08:40:58 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!-ME0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c84ddd6-fca3-4112-9c79-d0ef49f5b789_1778x1524.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Finally, we are entering the nitty-gritty of the design of the system. It is time to make choices regarding components and technology. </p><p>We focus on the internal design of the system, ensuring that each component serves its purpose efficiently and integrates seamlessly with others. At this stage, we do not discuss infrastructure aspects such as cloud deployment, load balancing, or CI/CD pipelines in depth; these will be addressed in a later chapter. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-ME0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c84ddd6-fca3-4112-9c79-d0ef49f5b789_1778x1524.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-ME0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c84ddd6-fca3-4112-9c79-d0ef49f5b789_1778x1524.png 424w, https://substackcdn.com/image/fetch/$s_!-ME0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c84ddd6-fca3-4112-9c79-d0ef49f5b789_1778x1524.png 848w, https://substackcdn.com/image/fetch/$s_!-ME0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c84ddd6-fca3-4112-9c79-d0ef49f5b789_1778x1524.png 1272w, https://substackcdn.com/image/fetch/$s_!-ME0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c84ddd6-fca3-4112-9c79-d0ef49f5b789_1778x1524.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-ME0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c84ddd6-fca3-4112-9c79-d0ef49f5b789_1778x1524.png" width="1456" height="1248" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0c84ddd6-fca3-4112-9c79-d0ef49f5b789_1778x1524.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1248,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2846400,&quot;alt&quot;:&quot;System design: technologies and choices&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="System design: technologies and choices" title="System design: technologies and choices" srcset="https://substackcdn.com/image/fetch/$s_!-ME0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c84ddd6-fca3-4112-9c79-d0ef49f5b789_1778x1524.png 424w, https://substackcdn.com/image/fetch/$s_!-ME0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c84ddd6-fca3-4112-9c79-d0ef49f5b789_1778x1524.png 848w, https://substackcdn.com/image/fetch/$s_!-ME0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c84ddd6-fca3-4112-9c79-d0ef49f5b789_1778x1524.png 1272w, https://substackcdn.com/image/fetch/$s_!-ME0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c84ddd6-fca3-4112-9c79-d0ef49f5b789_1778x1524.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>There is anyway a really important aspect of the platform that we need to consider. As we discussed in the third installment of this series, the constraint chapter, we opted for a cloud solution instead of on-prem or VPS.</p><p></p><blockquote><p><strong>From the <a href="https://ituntold.rixlabs.dev/i/153481248/technical-constraints">technical constraints</a> chapter </strong></p><p><strong>Decision Point</strong>: Given the need for scalability and low upfront cost for a Discord clone, cloud deployment is the preferred option.</p><p><strong>Justification</strong>: Cloud infrastructure allows us to leverage auto-scaling, managed services, and global CDNs to minimize latency and optimize costs.</p></blockquote><p></p><p></p><p>The cloud provider of choice for our example is <strong>MS Azure</strong>. Lately, I'm working a lot with this platform, and designing this system is a good way to practice a little more.</p><p>The components described in this chapter will, when possible, leverage the capabilities of <strong>MS Azure</strong>. It doesn't make any sense to deploy an application using a cloud provider and implementing everything custom. At least not at the beginning. There is always time to find out that we are in an edge case in terms of performance or specific functionality, but these kinds of problems, even if difficult to solve, are normally a consequence of a successful launch of an application. </p><p>So let's hope we will end up with one of these "standard cloud component" kinds of problems. The three major cloud providers Azure, AWS, and GCP all offer equivalent tools to design and implement our Discord clone example application. In case you want to follow my structure with another cloud provider, please post your component list of choice in the comments.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h1>Core Components Overview</h1><p>A well-designed system is composed of clearly defined components, each responsible for specific functionality. In our practical example, we have chosen specific technologies to implement these components while following a <strong>modular monolith</strong> architectural approach. There are several distinct component but It would be extremely pretentious to design an example app using a Microservice architecture. The key system components include:</p><ul><li><p><strong>Client Applications</strong> &#8211; Interfaces through which users interact with the system.</p></li><li><p><strong>API Gateway</strong> &#8211; Centralized entry point for client requests.</p></li><li><p><strong>Authentication &amp; Authorization Service</strong> &#8211; Manages user identity and permissions.</p></li><li><p><strong>Real-Time Messaging Service</strong> &#8211; Handles real-time communication.</p></li><li><p><strong>User &amp; Channel Management Service</strong> &#8211; Maintains user data and communication channels.</p></li><li><p><strong>Media Processing Service</strong> &#8211; Manages audio and video streaming.</p></li><li><p><strong>Storage Services</strong> &#8211; Handles persistent and ephemeral data.</p></li><li><p><strong>Notification Service</strong> &#8211; Sends real-time notifications.</p></li><li><p><strong>Analytics &amp; Monitoring Service</strong> &#8211; Collects and processes system metrics.</p></li></ul><p>Each of these components is designed with scalability, maintainability, and performance in mind. The golas and constraints were decided in the previous chapters.</p><div><hr></div><h2>Client Applications</h2><p>Client applications provide the interface for end users to interact with the system. In our practical example, we defined some constraint in Chapter 3.1 about and those lead me to chose a web-only client using a Typescript framework. To challange my knowledge I chosed <strong>React</strong>. It is a major framework in the landscape and it can for sure cover any requirement I could have in term of UI. The client will communicate with the backend via REST and WebSocket APIs.</p><p><strong>Responsibilities:</strong></p><ul><li><p>Display user interface and handle user interactions.</p></li><li><p>Communicate with backend services through API requests.</p></li><li><p>Maintain session state and caching for performance optimization.</p></li></ul><div><hr></div><h2>API Gateway</h2><p>The API Gateway acts as the single entry point for all client requests, handling routing, load balancing, and security enforcement.</p><p><strong>Responsibilities:</strong></p><ul><li><p>Forward requests to appropriate backend services.</p></li><li><p>Implement rate limiting and security policies.</p></li><li><p>Handle authentication tokens and request validation.</p></li></ul><p>As defined in the constraints , we will use <strong>Azure API Management</strong> as our API Gateway solution, ensuring a scalable and secure request-handling mechanism.</p><div><hr></div><h2>Authentication &amp; Authorization Service</h2><p>This service is responsible for user authentication, session management, and role-based access control.</p><p><strong>Responsibilities:</strong></p><ul><li><p>Authenticate users using OAuth2 and JWT.</p></li><li><p>Manage permissions and access control lists (ACLs).</p></li><li><p>Support third-party authentication (e.g., Google, GitHub login).</p></li></ul><p>In our practical example, we have chosen <strong>Azure Active Directory (Azure AD)</strong> as our identity provider, integrating it with the API Gateway and other backend services.</p><div><hr></div><h2>Backend Service</h2><p>The backend is responsible for handling business logic and processing client requests.As I said in the past I am a Java guy. Lately I'm using more Quarkus and "standard JEE" but my home base for backend with <strong>Java</strong> is still <strong>Spring Boot</strong>, so this is the backend framework of choice.</p><p><strong>Responsibilities:</strong></p><ul><li><p>Expose REST and WebSocket endpoints.</p></li><li><p>Handle business logic for messaging, user management, and channels.</p></li><li><p>Interact with databases, messaging systems, and external services.</p></li></ul><p><strong>Spring Boot</strong> was chosen due to its extensive ecosystem, strong community support, and seamless integration with other Java-based tools and frameworks. But mostly as said it is the Framework that I know best.</p><div><hr></div><h2>Real-Time Messaging Service</h2><p>The messaging service handles the real-time exchange of messages between users, ensuring low latency and high throughput.</p><p><strong>Responsibilities:</strong></p><ul><li><p>Manage WebSocket connections for live messaging.</p></li><li><p>Implement message delivery guarantees (at-least-once, at-most-once, exactly-once).</p></li><li><p>Support presence and typing indicators.</p></li></ul><p>As defined in the constraints , we will use <strong>Azure Event Hubs</strong> for event-driven communication, ensuring scalability and resilience in message delivery. This is another example where the cloud provider offer already an out of the box solution. My experience will make me lean more in the direction of Apache Kafka or Rabbit MQ for simplicity but Azure Event Hub dos exactly what we need without the necessity of managing the installation ourself.</p><div><hr></div><h2>User &amp; Channel Management Service</h2><p>This service is responsible for maintaining user profiles and managing communication channels.</p><p><strong>Responsibilities:</strong></p><ul><li><p>Store and retrieve user profile information.</p></li><li><p>Manage chat rooms, groups, and user membership.</p></li><li><p>Provide search and discovery features for channels.</p></li></ul><p>I generally prefer to use Relational database when I can. I'm a big fan of DDD but I know the struggle of designing aggregates that can be managed easily in the real world. This part of the application will for sure need some hierarchical structure and relation between stored data objects. For this scenario relational databases are a straight forward choice for me.</p><p>We will use <strong>Azure SQL Database</strong> as our relational database for structured data storage. This choice provides a fully managed, scalable solution with built-in high availability, automatic backups, and advanced security features. Compared to PostgreSQL and MySQL, Azure SQL Database offers seamless integration with other Azure services, supports serverless compute and hyperscale storage, and includes intelligent performance tuning capabilities. While PostgreSQL is known for its advanced indexing and JSON support, and MySQL for its widespread adoption and simplicity, Azure SQL Database provides a balanced option optimized for enterprise-grade workloads in an Azure-native environment.</p><div><hr></div><h2>Storage Services</h2><p>Storage services handle both persistent and temporary data storage needs.</p><p><strong>Responsibilities:</strong></p><ul><li><p>Store chat messages and media files.</p></li><li><p>Maintain ephemeral storage for temporary messages.</p></li><li><p>Provide backup and disaster recovery mechanisms.</p></li></ul><p>The second major database system. After users data channels and so on we need a place to persist the messages and the files exchanged.</p><p>For file storage, we will use <strong>Azure Blob Storage</strong>, which provides a highly available, durable, and scalable solution for unstructured data. This service is ideal for storing chat media such as images, voice messages, and attachments. It supports automatic replication, ensuring data resilience, and integrates seamlessly with other Azure services, such as Azure Content Delivery Network (CDN), to optimize content delivery performance. Given the need for efficient media storage and retrieval in our system, Azure Blob Storage aligns well with our requirements for scalability and reliability.</p><div><hr></div><h2>Notification Service</h2><p>This service ensures users receive notifications for relevant events.</p><p><strong>Responsibilities:</strong></p><ul><li><p>Send push notifications to mobile and web clients.</p></li><li><p>Deliver email and in-app notifications.</p></li><li><p>Manage notification preferences for users.</p></li></ul><p>We will integrate <strong>Azure Notification Hubs</strong> for push notifications, as it provides a scalable, cross-platform solution for sending notifications to various client applications. Azure Notification Hubs supports high-throughput push notifications, offering integration with both APNs (Apple Push Notification service) and FCM (Firebase Cloud Messaging), ensuring reliable and efficient message delivery. Its ability to segment audiences and personalize notifications makes it an ideal choice for our system's real-time engagement needs.</p><div><hr></div><h2>Analytics &amp; Monitoring Service</h2><p>To maintain system health and performance, we need a dedicated service for collecting metrics and logs.</p><p><strong>Responsibilities:</strong></p><ul><li><p>Track system performance (e.g., latency, request throughput).</p></li><li><p>Monitor user engagement and feature usage.</p></li><li><p>Provide alerts for anomalies and failures.</p></li></ul><p>As defined in the constraints , we will use <strong>Azure Monitor</strong> for monitoring and <strong>Azure Monitor Metrics</strong> for performance tracking and visualization. Azure Monitor provides centralized logging, metric collection, and alerting capabilities, allowing us to gain real-time insights into application performance and system health. Compared to <strong>Prometheus</strong> and <strong>Grafana</strong>, which require self-managed setups and manual scaling, Azure Monitor offers a fully managed solution with seamless integration into the Azure ecosystem. It supports automatic scaling, intelligent anomaly detection, and deep integration with Azure security and compliance features, making it a robust choice for our monitoring needs.</p><div><hr></div><h2>Media Processing Service - OPTIONAL</h2><p>This is an optional component that would be nice to implement but that can be kept out of an MVP.</p><p>I will anyway describe the responsibility and the choices made on the topic.</p><p>The media processing service enables users to send and receive voice and video streams, supporting live calls and media playback.</p><p><strong>Responsibilities:</strong></p><ul><li><p>Encode and decode audio/video streams.</p></li><li><p>Provide media storage and retrieval.</p></li><li><p>Enable live streaming and conferencing.</p></li></ul><p>For media handling, we will leverage <strong>Azure Communication Services</strong>, which provides built-in support for real-time voice, video, and chat communication. This service is fully managed, allowing us to integrate seamless peer-to-peer and group communication capabilities without handling complex infrastructure. It supports SDKs for multiple platforms, ensuring interoperability between web and mobile clients. Additionally, Azure Communication Services integrates natively with other Azure solutions, improving scalability and security for our media processing requirements.</p><div><hr></div><p>By defining these components in detail, we establish a solid foundation for our application&#8217;s design. In the next chapters, we will explore how these components interact within an infrastructure, addressing scalability, deployment strategies, and cloud considerations.</p><p>This chapter needs to describe the basic architecture of the software components themselves. I think though that it would make this chapter too long and convoluted. So stay tuned for part two of the design process, where we will do a component drill-down and decide what will be implemented where and the common structure of the applications.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h3>Articles I enjoyed this week</h3><ul><li><p><strong><a href="https://newsletter.francofernando.com/p/database-sharding-case-study-postgresql">Database sharding case study: PostgreSQL</a></strong> by <strong><a href="https://substack.com/@francofernando">Franco Fernando</a></strong></p></li><li><p><strong><a href="http://The C4 Model for Software Architecture">The C4 Model for Software Architecture</a> by <a href="https://www.infoq.com/profile/Simon-Brown/#allActivity">Simon Brown</a></strong></p></li><li><p>For the friends who speak Portuguese: <strong><a href="https://substack.com/home/post/p-156552131">Por que nos deixamos definir pela nossa profiss&#227;o?</a></strong> by Paula Alves (<strong><a href="https://substack.com/@ondeestapaula">@ondeestapaula</a></strong>)</p></li><li><p><strong><a href="https://sketechnews.substack.com/p/essential-network-protocols-guide">8 Key Protocols You Can&#8217;t Ignore, 5 Steps to Understand How VPN Tunneling Works, and 7 Smart Strategies to Reduce Latency &#8211; Sketech #18</a></strong> by <strong><a href="https://substack.com/@sketech">Nina</a></strong></p></li></ul><p></p><div><hr></div><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/key-concepts-of-system-design-4-system?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading IT Untold! If you like this article please share it with your friends and colleagues</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/key-concepts-of-system-design-4-system?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/p/key-concepts-of-system-design-4-system?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p>]]></content:encoded></item><item><title><![CDATA[Antipattern necessity]]></title><description><![CDATA[Can we always act virtuously?]]></description><link>https://ituntold.rixlabs.dev/p/antipattern-necessity</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/antipattern-necessity</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Sun, 02 Feb 2025 16:56:15 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!bj0Y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eedfa38-152c-4b41-9cf8-f3f6e414176c_1948x1446.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I was thinking about what to write today, and as I reflected on the week, a particular project came to mind. One of the initiatives I'm currently following involves migrating a suite of service integration tests to the cloud as part of a broader microservices migration. The infrastructure is a complex, hybrid mix of cloud and on-premises systems, which is common in non-big-bang migrations.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bj0Y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eedfa38-152c-4b41-9cf8-f3f6e414176c_1948x1446.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bj0Y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eedfa38-152c-4b41-9cf8-f3f6e414176c_1948x1446.png 424w, https://substackcdn.com/image/fetch/$s_!bj0Y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eedfa38-152c-4b41-9cf8-f3f6e414176c_1948x1446.png 848w, https://substackcdn.com/image/fetch/$s_!bj0Y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eedfa38-152c-4b41-9cf8-f3f6e414176c_1948x1446.png 1272w, https://substackcdn.com/image/fetch/$s_!bj0Y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eedfa38-152c-4b41-9cf8-f3f6e414176c_1948x1446.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bj0Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eedfa38-152c-4b41-9cf8-f3f6e414176c_1948x1446.png" width="1456" height="1081" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9eedfa38-152c-4b41-9cf8-f3f6e414176c_1948x1446.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1081,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:4351428,&quot;alt&quot;:&quot;Are all antipattern avoidable?&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Are all antipattern avoidable?" title="Are all antipattern avoidable?" srcset="https://substackcdn.com/image/fetch/$s_!bj0Y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eedfa38-152c-4b41-9cf8-f3f6e414176c_1948x1446.png 424w, https://substackcdn.com/image/fetch/$s_!bj0Y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eedfa38-152c-4b41-9cf8-f3f6e414176c_1948x1446.png 848w, https://substackcdn.com/image/fetch/$s_!bj0Y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eedfa38-152c-4b41-9cf8-f3f6e414176c_1948x1446.png 1272w, https://substackcdn.com/image/fetch/$s_!bj0Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eedfa38-152c-4b41-9cf8-f3f6e414176c_1948x1446.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Everything seemed to be on track until a discussion arose in a meeting about configuring Kafka topics across the on-prem and cloud environments. The decision was made to use a replication mechanism where services always publish to the "real" topic, while consumers retrieve messages from a "replica" topic.</p><p>This approach introduces a challenge: many services must now configure both the real and replica topics solely to enable testing. And here is where the debate began.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h4>What Are Architectural Antipatterns?</h4><p>At the core of this issue is a fundamental question: should production configurations (or even code) be altered for the sake of tests? This is a classic <strong>antipattern</strong>.</p><p>In software architecture, an <strong>antipattern</strong> is a seemingly reasonable solution that, over time, introduces significant long-term problems. Unlike bad practices, which are poor choices from the outset, antipatterns often stem from well-intentioned decisions that gradually degrade system quality.</p><h5>Example: Changing Production Code to Allow Tests</h5><p>Returning to the Kafka configuration case, modifying production settings to facilitate testing introduces several risks:</p><ul><li><p><strong>Increased complexity</strong> in production configurations, raising the likelihood of misconfigurations.</p></li><li><p><strong>Unintended dependencies</strong> between test environments and production settings, reducing flexibility and increasing operational risks.</p></li><li><p><strong>Higher maintenance burden</strong>, as teams must validate and manage multiple configuration paths.</p></li></ul><p>A better approach would involve designing the system for testability from the outset, using techniques like dependency injection, feature toggles, or environment-specific overrides. This way, teams can ensure comprehensive test coverage without introducing risky production changes.</p><div><hr></div><h3>How Far Should We Go to Avoid Architectural Antipatterns?</h3><p>Avoiding antipatterns is important, but rigidly rejecting anything that resembles one can lead to <strong>paralysis by analysis</strong> another form of inefficiency. Instead of focusing solely on avoidance, architects should prioritize <strong>pragmatic trade-offs</strong>.</p><h4>1. Recognize Context and Constraints</h4><p>Some antipatterns arise from real-world constraints such as tight deadlines, team expertise, or evolving business needs. For instance, a startup might allow minor code structure shortcuts to meet time-to-market goals, with the understanding that refactoring will follow. In contrast, a large enterprise with strict maintainability requirements may find the same decision introduces long-term risks.</p><p><strong>Example Edge Case:</strong> A team working on a legacy system with poor test coverage might temporarily expose private methods to improve testability. While this could be justifiable as an interim step, making it a widespread practice would weaken system encapsulation over time.</p><h4>2. Prioritize Long-Term Sustainability</h4><p>Short-term workarounds can be tempting, but architects should advocate for decisions that minimize future refactoring costs. Strategies such as modular design, clear API boundaries, and automated testing help prevent antipatterns from spiraling out of control.</p><p><strong>Example:</strong> Instead of modifying production code to accommodate tests, better alternatives include:</p><ul><li><p>Applying <strong>dependency inversion</strong> to support test mocks.</p></li><li><p>Refactoring <strong>monolithic functions</strong> into smaller, testable components.</p></li><li><p>Using <strong>test doubles</strong> (mocks, stubs, fakes) rather than exposing implementation details.</p></li></ul><p>A real-world failure occurred when multiple teams needed to test private logic in a shared library. To accommodate testing, they made private methods public, creating unintended dependencies that later obstructed refactoring. A better approach would have been using a well-defined interface with dependency injection to facilitate testing without compromising design principles.</p><h4>3. Balance Theory and Practice</h4><p>Architectural purity isn&#8217;t always practical. The key is <strong>early detection</strong> and <strong>incremental refactoring</strong> identifying when an antipattern is forming and addressing it before it becomes an unmanageable problem.</p><p><strong>Example:</strong> A team working with a legacy codebase might need to introduce an antipattern as a temporary workaround. Instead of rejecting the change outright, they could document it with a clear plan for future refactoring.</p><p><strong>Edge Case:</strong> In highly regulated industries like finance or healthcare, exposing production logic for tests could introduce security and compliance risks. In such cases, alternative approaches such as testing through APIs or improving testability through refactoring should be prioritized.</p><div><hr></div><h3>Finding the Right Balance</h3><p>Architectural antipatterns emerge when seemingly good solutions introduce long-term complexity (The good old temporary fix). While avoiding them is important, blindly chasing architectural perfection can be just as harmful. A skilled architect understands when to accept imperfection in service of progress and when to invest in long-term maintainability. Making pragmatic trade-offs, considering business constraints, and planning for refactoring are key to sustainable software architecture.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h3>Articles I enjoyed this week</h3><ul><li><p><a href="https://newsletter.techworld-with-milan.com/p/what-is-cdn">What is CDN?</a> by <strong><a href="https://substack.com/@techworldwithmilan">Milan Milanovi&#263;</a></strong></p></li><li><p><a href="https://sketechnews.substack.com/p/api-design-mistakes-to-avoid">4 API Design Mistakes You Must Avoid (Or Risk Total Chaos!), 6 Essential Kafka Concepts You Need to Master, Forward vs Reverse Proxies Explained in 7 Easy Steps! - Sketech #17</a> by <a href="https://substack.com/@sketech">Nina</a></p></li></ul><div><hr></div><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/antipattern-necessity?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading IT Untold! If you like this article please share it with your friends and colleagues</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/antipattern-necessity?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/p/antipattern-necessity?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p>]]></content:encoded></item><item><title><![CDATA[The Definition of Experience]]></title><description><![CDATA[What makes you better over time]]></description><link>https://ituntold.rixlabs.dev/p/the-definition-of-experience</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/the-definition-of-experience</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Tue, 28 Jan 2025 18:20:21 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!IX2c!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64a72daa-e846-49a0-ae51-5f308a44bd88_1966x1428.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As a senior solution architect, one of the most valuable lessons I have learned over the years is the importance of anticipation. The ability to anticipate to foresee potential scenarios before they unfold is a skill that separates good engineers from great ones. It equips you to respond more effectively to challenges, whether you&#8217;re learning a new programming language, adopting a new tool, or troubleshooting a critical production issue.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IX2c!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64a72daa-e846-49a0-ae51-5f308a44bd88_1966x1428.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IX2c!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64a72daa-e846-49a0-ae51-5f308a44bd88_1966x1428.png 424w, https://substackcdn.com/image/fetch/$s_!IX2c!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64a72daa-e846-49a0-ae51-5f308a44bd88_1966x1428.png 848w, https://substackcdn.com/image/fetch/$s_!IX2c!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64a72daa-e846-49a0-ae51-5f308a44bd88_1966x1428.png 1272w, https://substackcdn.com/image/fetch/$s_!IX2c!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64a72daa-e846-49a0-ae51-5f308a44bd88_1966x1428.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IX2c!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64a72daa-e846-49a0-ae51-5f308a44bd88_1966x1428.png" width="1456" height="1058" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/64a72daa-e846-49a0-ae51-5f308a44bd88_1966x1428.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1058,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3984065,&quot;alt&quot;:&quot;Anticipation comes from exposure to different things&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Anticipation comes from exposure to different things" title="Anticipation comes from exposure to different things" srcset="https://substackcdn.com/image/fetch/$s_!IX2c!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64a72daa-e846-49a0-ae51-5f308a44bd88_1966x1428.png 424w, https://substackcdn.com/image/fetch/$s_!IX2c!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64a72daa-e846-49a0-ae51-5f308a44bd88_1966x1428.png 848w, https://substackcdn.com/image/fetch/$s_!IX2c!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64a72daa-e846-49a0-ae51-5f308a44bd88_1966x1428.png 1272w, https://substackcdn.com/image/fetch/$s_!IX2c!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64a72daa-e846-49a0-ae51-5f308a44bd88_1966x1428.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Anticipation is not a magical talent; it is a skill forged through experience and exposure to diverse situations. When you&#8217;ve encountered enough varied challenges, patterns begin to emerge, allowing you to predict what might come next. This capacity to anticipate makes you better prepared and more adaptable in any given situation.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h4>Anticipation in Action</h4><p>Let&#8217;s consider a scenario familiar to many engineers: a high-stakes production outage. When systems fail, there is no time for trial and error. Engineers who have honed their anticipation skills can quickly zero in on potential root causes. They know, for example, that a sudden spike in resource usage might point to a memory leak or an unoptimized query. They&#8217;ve seen these patterns before, and this familiarity enables them to act decisively and efficiently.</p><p>Similarly, when adopting a new tool or programming language, anticipation plays a key role. Experienced professionals know the common pitfalls poor documentation, unexpected edge cases, or integration challenges. They proactively seek out these potential issues, often asking the right questions before they even arise. This foresight accelerates the learning process and helps mitigate risks early.</p><h4>How to Build Anticipation</h4><p>Developing the ability to anticipate takes time, but it is achievable for anyone willing to put in the effort. Here are some strategies to help:</p><ol><li><p><strong>Broaden Your Exposure:</strong> Seek out diverse projects, teams, and technologies. The more varied your experiences, the more patterns you&#8217;ll recognize over time.</p></li><li><p><strong>Learn from Others:</strong> Collaborate with colleagues, participate in code reviews, and engage in technical discussions. Learning from others&#8217; experiences can give you insights you might not encounter on your own.</p></li><li><p><strong>Reflect on Past Experiences:</strong> After completing a project or solving a problem, take time to reflect. What went well? What didn&#8217;t? Documenting these lessons helps you recognize similar situations in the future.</p></li><li><p><strong>Stay Curious:</strong> Continuously learning keeps your skills sharp. Whether it&#8217;s a new framework, a different programming paradigm, or a deeper understanding of system internals, every new piece of knowledge adds to your ability to anticipate.</p></li><li><p><strong>Simulate Scenarios:</strong> If you&#8217;re learning something new, actively think about possible failure points or challenges. Try to preemptively address them, even if you&#8217;ve never encountered them before.</p></li></ol><h4>The Experience Paradox</h4><p>Here&#8217;s the catch: anticipation is largely a byproduct of experience. But you don&#8217;t need to wait decades to start building it. By being intentional about exposing yourself to challenges and learning from them, you can accelerate the process.</p><p>For those early in their careers, leverage the experiences of others. Ask questions like, &#8220;What should I watch out for?&#8221; or &#8220;What do you wish you had known when you started?&#8221; Senior colleagues, mentors, and even industry articles can provide a wealth of foresight.</p><h4>Why It Matters</h4><p>Anticipation doesn&#8217;t just make you a better engineer; it makes you a more reliable and effective team member. When you can foresee issues and take steps to address them, you reduce risks for your team and projects. This skill inspires trust and confidence among your peers and stakeholders, paving the way for career growth.</p><p>In a fast-paced, ever-evolving industry, the ability to anticipate is a superpower. It allows you to stay ahead of the curve, adapt to change, and deliver value consistently. While experience remains the foundation of anticipation, deliberate effort and curiosity can fast-track its development.</p><p>So, embrace new challenges, learn voraciously, and reflect deeply. The more you cultivate this skill, the better prepared you&#8217;ll be for whatever comes your way&#8212;because in the world of technology, the unexpected is always just around the corner.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h3>Articles I enjoyed this week</h3><ul><li><p><strong><a href="https://newsletter.systemdesigncodex.com/p/how-to-do-well-in-system-design-interviews">How To Do Well in System Design Interviews?</a></strong> by <strong><a href="https://substack.com/@saurabhdashora">Saurabh Dashora</a></strong></p></li><li><p><strong><a href="https://newsletter.francofernando.com/p/space-complexity">Space Complexity</a></strong> by <strong><a href="https://substack.com/@francofernando">Franco Fernando</a></strong></p></li><li><p><strong><a href="https://sketechnews.substack.com/p/kafka-use-cases-scalable-reliable-systems">How API Pagination, Kafka Use Cases and Security Practices Solve Data Handling, Scalability and Protection Challenges Sketech #16</a></strong> by <strong><a href="https://substack.com/@sketech">Nina</a></strong></p></li></ul><div><hr></div><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/the-definition-of-experience?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading IT Untold! If you like this article please share it with your friends and colleagues</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/p/the-definition-of-experience?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/p/the-definition-of-experience?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><div><hr></div><p>Every little contribution help. If you want to help me produce this content you can do it <a href="https://ko-fi.com/rixlabs">here.</a></p>]]></content:encoded></item><item><title><![CDATA[New year resolution realisation]]></title><description><![CDATA[I decided to catch up an old hobby and I noticed some similarity with software engineering]]></description><link>https://ituntold.rixlabs.dev/p/new-year-resolution-realisation</link><guid isPermaLink="false">https://ituntold.rixlabs.dev/p/new-year-resolution-realisation</guid><dc:creator><![CDATA[Riccardo Causo]]></dc:creator><pubDate>Sun, 19 Jan 2025 16:44:47 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!C1PX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ccb25e-1ab3-49f8-9cf7-c4c7fbdfa94a_1988x1446.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I&#8217;m not someone who makes New Year&#8217;s resolutions you can count on a list. Instead, I try to add a new habit I&#8217;d like to incorporate into my life.</p><p>This year, by pure coincidence, I kept seeing ads on social media about digital drawing and painting.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!C1PX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ccb25e-1ab3-49f8-9cf7-c4c7fbdfa94a_1988x1446.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!C1PX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ccb25e-1ab3-49f8-9cf7-c4c7fbdfa94a_1988x1446.png 424w, https://substackcdn.com/image/fetch/$s_!C1PX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ccb25e-1ab3-49f8-9cf7-c4c7fbdfa94a_1988x1446.png 848w, https://substackcdn.com/image/fetch/$s_!C1PX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ccb25e-1ab3-49f8-9cf7-c4c7fbdfa94a_1988x1446.png 1272w, https://substackcdn.com/image/fetch/$s_!C1PX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ccb25e-1ab3-49f8-9cf7-c4c7fbdfa94a_1988x1446.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!C1PX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ccb25e-1ab3-49f8-9cf7-c4c7fbdfa94a_1988x1446.png" width="1456" height="1059" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/78ccb25e-1ab3-49f8-9cf7-c4c7fbdfa94a_1988x1446.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1059,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1626366,&quot;alt&quot;:&quot;Drawing and coding&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Drawing and coding" title="Drawing and coding" srcset="https://substackcdn.com/image/fetch/$s_!C1PX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ccb25e-1ab3-49f8-9cf7-c4c7fbdfa94a_1988x1446.png 424w, https://substackcdn.com/image/fetch/$s_!C1PX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ccb25e-1ab3-49f8-9cf7-c4c7fbdfa94a_1988x1446.png 848w, https://substackcdn.com/image/fetch/$s_!C1PX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ccb25e-1ab3-49f8-9cf7-c4c7fbdfa94a_1988x1446.png 1272w, https://substackcdn.com/image/fetch/$s_!C1PX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78ccb25e-1ab3-49f8-9cf7-c4c7fbdfa94a_1988x1446.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>I already own an iPad, which I bought last year with the intention of using it for note-taking. As you can imagine, that plan didn&#8217;t quite work out. However, I did purchase the Procreate app to experiment with digital drawing. Months went by, but those ads, combined with the fact that I already had the tools, nudged me to give digital drawing another try.</p><p>I have some experience with paper and ink pens, so I&#8217;m not starting from scratch. But saying I&#8217;m rusty would be a massive understatement.</p><p>I began by doodling some imaginary characters, and somehow, a strange &#8220;Forkman&#8221; emerged from my brain a roundish figure without arms and a trident for a head.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7pSI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f1f0ef-74b7-4d2c-9633-c85578e0f139_322x530.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7pSI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f1f0ef-74b7-4d2c-9633-c85578e0f139_322x530.png 424w, https://substackcdn.com/image/fetch/$s_!7pSI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f1f0ef-74b7-4d2c-9633-c85578e0f139_322x530.png 848w, https://substackcdn.com/image/fetch/$s_!7pSI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f1f0ef-74b7-4d2c-9633-c85578e0f139_322x530.png 1272w, https://substackcdn.com/image/fetch/$s_!7pSI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f1f0ef-74b7-4d2c-9633-c85578e0f139_322x530.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7pSI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f1f0ef-74b7-4d2c-9633-c85578e0f139_322x530.png" width="322" height="530" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f7f1f0ef-74b7-4d2c-9633-c85578e0f139_322x530.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:530,&quot;width&quot;:322,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:66046,&quot;alt&quot;:&quot;Forkman&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Forkman" title="Forkman" srcset="https://substackcdn.com/image/fetch/$s_!7pSI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f1f0ef-74b7-4d2c-9633-c85578e0f139_322x530.png 424w, https://substackcdn.com/image/fetch/$s_!7pSI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f1f0ef-74b7-4d2c-9633-c85578e0f139_322x530.png 848w, https://substackcdn.com/image/fetch/$s_!7pSI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f1f0ef-74b7-4d2c-9633-c85578e0f139_322x530.png 1272w, https://substackcdn.com/image/fetch/$s_!7pSI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7f1f0ef-74b7-4d2c-9633-c85578e0f139_322x530.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>After this first attempt, I decided to challenge myself: draw Forkman from a 30-degree angle. I figured it would be a good way to get familiar with proportions, perspective, and overall drawing fundamentals.</p><p>Needless to say, it was a huge struggle. The proportions were off, but the hardest part was drawing the fork head at an angle. How much of each spike would be visible? How thick should I make them? How would one spike overlap the others?</p><p>It took several tries and even duct-taping three pens together as a makeshift model only to realize that what I drew didn&#8217;t make any sense. Not just because Forkman is an absurd doodle with shaky lines, but because the proportions and perspective I wanted to train were completely distorted.</p><p>After taking a day off and watching a couple of YouTube videos about drawing, I remembered the most basic technique: break down what you want to draw into simpler shapes.</p><p>So, I gave it a shot. First, I created a main rectangular parallelepiped at a 30-degree angle as the frame. Then, I carved out three smaller rectangular parallelepipeds for the spikes of the fork head.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CI7h!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8614eec-0d9c-4b1a-b831-13cee6a4d26c_662x904.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CI7h!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8614eec-0d9c-4b1a-b831-13cee6a4d26c_662x904.png 424w, https://substackcdn.com/image/fetch/$s_!CI7h!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8614eec-0d9c-4b1a-b831-13cee6a4d26c_662x904.png 848w, https://substackcdn.com/image/fetch/$s_!CI7h!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8614eec-0d9c-4b1a-b831-13cee6a4d26c_662x904.png 1272w, https://substackcdn.com/image/fetch/$s_!CI7h!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8614eec-0d9c-4b1a-b831-13cee6a4d26c_662x904.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CI7h!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8614eec-0d9c-4b1a-b831-13cee6a4d26c_662x904.png" width="662" height="904" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c8614eec-0d9c-4b1a-b831-13cee6a4d26c_662x904.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:904,&quot;width&quot;:662,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:100388,&quot;alt&quot;:&quot;The guide box made of simple shapes&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The guide box made of simple shapes" title="The guide box made of simple shapes" srcset="https://substackcdn.com/image/fetch/$s_!CI7h!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8614eec-0d9c-4b1a-b831-13cee6a4d26c_662x904.png 424w, https://substackcdn.com/image/fetch/$s_!CI7h!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8614eec-0d9c-4b1a-b831-13cee6a4d26c_662x904.png 848w, https://substackcdn.com/image/fetch/$s_!CI7h!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8614eec-0d9c-4b1a-b831-13cee6a4d26c_662x904.png 1272w, https://substackcdn.com/image/fetch/$s_!CI7h!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8614eec-0d9c-4b1a-b831-13cee6a4d26c_662x904.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The guide box made of simple shapes</figcaption></figure></div><p></p><p>Using this new framework, I redrew my figure. And, unsurprisingly, the results were much better. The drawing itself is still rough let&#8217;s call it &#8220;garbage with potential&#8221; but it has some sense of perspective now, even if it is still incomplete.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7uHy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0ecdf16-93a1-436f-993f-f6ae9b24b381_478x694.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7uHy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0ecdf16-93a1-436f-993f-f6ae9b24b381_478x694.png 424w, https://substackcdn.com/image/fetch/$s_!7uHy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0ecdf16-93a1-436f-993f-f6ae9b24b381_478x694.png 848w, https://substackcdn.com/image/fetch/$s_!7uHy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0ecdf16-93a1-436f-993f-f6ae9b24b381_478x694.png 1272w, https://substackcdn.com/image/fetch/$s_!7uHy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0ecdf16-93a1-436f-993f-f6ae9b24b381_478x694.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7uHy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0ecdf16-93a1-436f-993f-f6ae9b24b381_478x694.png" width="478" height="694" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a0ecdf16-93a1-436f-993f-f6ae9b24b381_478x694.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:694,&quot;width&quot;:478,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:88647,&quot;alt&quot;:&quot;Sideways Forkman&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Sideways Forkman" title="Sideways Forkman" srcset="https://substackcdn.com/image/fetch/$s_!7uHy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0ecdf16-93a1-436f-993f-f6ae9b24b381_478x694.png 424w, https://substackcdn.com/image/fetch/$s_!7uHy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0ecdf16-93a1-436f-993f-f6ae9b24b381_478x694.png 848w, https://substackcdn.com/image/fetch/$s_!7uHy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0ecdf16-93a1-436f-993f-f6ae9b24b381_478x694.png 1272w, https://substackcdn.com/image/fetch/$s_!7uHy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0ecdf16-93a1-436f-993f-f6ae9b24b381_478x694.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Sideways Forman</figcaption></figure></div><p></p><p>At the end of this adventure, one thing became crystal clear to me: I had completely overlooked a basic principle I use every day as a software engineer. Decomposing problems into smaller, manageable parts is second nature in my work. It&#8217;s effective; I know it works. So why didn&#8217;t I apply it here?</p><p>This realization started to take root in my mind, forming a fascinating parallel between drawing and problem-solving.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><p></p><h2>Drawing and Coding: The Art of Simplifying Complexity</h2><p>Artists and software engineers might seem worlds apart, but they share a common approach to managing complexity: breaking down the big picture into smaller, manageable parts. This similarity between figure drawing and the divide-and-conquer strategy in software engineering offers valuable lessons in both disciplines.</p><h3>Decomposing Complexity: Drawing the Basics</h3><p>When an artist begins a figure drawing, they don&#8217;t start with fine details. Instead, they decompose the figure into basic shapes an oval for the head, rectangles for the torso, cylinders for the limbs. These shapes form the foundational structure, helping the artist establish proportions and relationships between parts. Only once the foundation is correct do they add depth, texture, and detail.</p><h3>Divide and Conquer in Software Engineering</h3><p>Software engineers follow a similar strategy when tackling complex systems. Using the divide-and-conquer approach, they break down a large problem into smaller, independent components. For example, designing an e-commerce platform might involve splitting the system into modules like user authentication, product catalogs, shopping carts, and payment processing. Each module is developed and tested individually, with clearly defined boundaries ensuring the parts integrate smoothly.</p><h3>The Key Parallel: Boundaries and Integration</h3><p>Both disciplines rely on clearly defined boundaries to maintain focus and ensure integration. In drawing, boundaries between shapes prevent distortion, ensuring that the oval head connects properly to the rectangular torso. Similarly, in software, well-defined interfaces between components ensure that each module can work independently while still fitting seamlessly into the larger system.</p><h3>Iterative Refinement</h3><p>Another shared principle is iterative refinement. In drawing, rough shapes are progressively refined into detailed artwork. In software engineering, a system evolves through prototyping, testing, and continuous improvement.</p><p>By embracing these principles simplification, defined boundaries, and iterative refinement artists and engineers alike can transform overwhelming complexity into elegant results, whether on canvas (iPad for me) or in code.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ituntold.rixlabs.dev/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h3>Articles I enjoyed this week</h3><ul><li><p><strong><a href="https://sketechnews.substack.com/p/traffic-management-proxies-gateways-balancers">How Traffic Management Tools, API Testing and CI/CD Streamline Modern Software Architecture - Sketech #15</a></strong> by <strong><a href="https://substack.com/@sketech">Nina</a></strong></p></li><li><p><strong><a href="https://newsletter.techworld-with-milan.com/p/computer-science-papers-every-developer?utm_source=%2Finbox&amp;utm_medium=reader2">Computer Science Papers Every Developer Should Read</a></strong> by <strong><a href="https://substack.com/@techworldwithmilan">Milan Milanovi&#263;</a></strong></p></li><li><p><strong><a href="https://newsletter.systemdesignclassroom.com/p/event-sourcing-is-like-time-traveling?utm_source=%2Finbox&amp;utm_medium=reader2">Event Sourcing is like Time traveling</a> </strong>by<strong> <a href="https://substack.com/@rauljuncov">Raul Junco</a></strong></p></li><li><p><strong><a href="https://newsletter.francofernando.com/p/a-comprehensive-guide-to-database?utm_source=%2Finbox&amp;utm_medium=reader2">A Comprehensive Guide to Database Sharding</a> </strong>by<strong> <a href="https://substack.com/@francofernando">Franco Fernando</a></strong></p></li></ul><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ituntold.rixlabs.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading IT Untold! If you like this article please share it with your friends and colleagues</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item></channel></rss>