<?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[Reverse Pitch]]></title><description><![CDATA[The pitch you'll hear vs. the reality you'll build. Weekly notes on software engineering, cloud infrastructure and AI.]]></description><link>https://www.reversepitch.io</link><image><url>https://substackcdn.com/image/fetch/$s_!5Kya!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4624a9d4-8af5-4f86-a5c6-e6f3a294e61d_256x256.png</url><title>Reverse Pitch</title><link>https://www.reversepitch.io</link></image><generator>Substack</generator><lastBuildDate>Tue, 08 Sep 2026 04:06:15 GMT</lastBuildDate><atom:link href="https://www.reversepitch.io/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Yuyi Pacheco Kimura]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[reversepitch@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[reversepitch@substack.com]]></itunes:email><itunes:name><![CDATA[Yuyi Kimura]]></itunes:name></itunes:owner><itunes:author><![CDATA[Yuyi Kimura]]></itunes:author><googleplay:owner><![CDATA[reversepitch@substack.com]]></googleplay:owner><googleplay:email><![CDATA[reversepitch@substack.com]]></googleplay:email><googleplay:author><![CDATA[Yuyi Kimura]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Clean Code: One Size Doesn’t Fit All]]></title><description><![CDATA[The real essence of clean code lies in the ability to communicate the intent of the program clearly to other engineers.]]></description><link>https://www.reversepitch.io/p/clean-code-one-size-doesnt-fit-all</link><guid isPermaLink="false">https://www.reversepitch.io/p/clean-code-one-size-doesnt-fit-all</guid><dc:creator><![CDATA[Yuyi Kimura]]></dc:creator><pubDate>Fri, 26 Jul 2024 13:31:31 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Hnaj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2585d38d-abe2-4445-8a23-b5ba65c69447_800x800.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Clean code isn&#8217;t just a buzzword or some hot topic that arise now and then&#8202;&#8212;&#8202;it&#8217;s a critical element in building maintainable and scalable systems. Pairing it with thorough code reviews, it becomes an incredible asset for any development team, enhancing both the quality of the software and the efficiency of the team.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Hnaj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2585d38d-abe2-4445-8a23-b5ba65c69447_800x800.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Hnaj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2585d38d-abe2-4445-8a23-b5ba65c69447_800x800.png 424w, https://substackcdn.com/image/fetch/$s_!Hnaj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2585d38d-abe2-4445-8a23-b5ba65c69447_800x800.png 848w, https://substackcdn.com/image/fetch/$s_!Hnaj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2585d38d-abe2-4445-8a23-b5ba65c69447_800x800.png 1272w, https://substackcdn.com/image/fetch/$s_!Hnaj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2585d38d-abe2-4445-8a23-b5ba65c69447_800x800.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Hnaj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2585d38d-abe2-4445-8a23-b5ba65c69447_800x800.png" width="800" height="800" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2585d38d-abe2-4445-8a23-b5ba65c69447_800x800.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:800,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;To make a pile of code blocks represent a tower, you have to adapt some pieces. Generated by AI&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="To make a pile of code blocks represent a tower, you have to adapt some pieces. Generated by AI" title="To make a pile of code blocks represent a tower, you have to adapt some pieces. Generated by AI" srcset="https://substackcdn.com/image/fetch/$s_!Hnaj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2585d38d-abe2-4445-8a23-b5ba65c69447_800x800.png 424w, https://substackcdn.com/image/fetch/$s_!Hnaj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2585d38d-abe2-4445-8a23-b5ba65c69447_800x800.png 848w, https://substackcdn.com/image/fetch/$s_!Hnaj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2585d38d-abe2-4445-8a23-b5ba65c69447_800x800.png 1272w, https://substackcdn.com/image/fetch/$s_!Hnaj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2585d38d-abe2-4445-8a23-b5ba65c69447_800x800.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 aria-hidden="true" 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><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">To make a pile of blocks represent a tower, you may have to adapt some pieces. Generated by&nbsp;AI</figcaption></figure></div><h3>What is Clean&nbsp;Code?</h3><p>Clean code is not following a style guide or some naming convention, although these are very important aspects. At its core, clean code is about writing code that is easy to understand, maintain and extend. It emphasizes clarity, simplicity, and consistency, making it easier for developers to understand and work with.</p><p>Books like Robert C. Martin&#8217;s &#8220;Clean Code&#8221; and Steve McConnell&#8217;s &#8220;Code Complete&#8221; provide extensive guidelines on writing clean code. Both of these books offer valuable insights, but it&#8217;s essential to remember that they are guidelines, not commandments.</p><p>The real essence of clean code lies in the ability to communicate the intent of the program clearly to other engineers (yes, including your future self). However, the interpretation for it can vary depending on the project context.</p><h3>The Importance of&nbsp;Context</h3><p>To understand the importance of context, let&#8217;s consider Google, one of the world&#8217;s leading tech companies. Their approach to clean code demonstrates the importance of context when writing code.</p><p>At Google, developers often need to sacrifice certain aspects of readability for the sake of performance. Why? Because they are building tools and services that are used by millions of users concurrently, requiring every bit of performance they can squeeze.</p><p>Within this context, writing &#8220;clean code&#8221; requires you to take a different road (but you should reach the same goal). This might involve:</p><ul><li><p>Using less intuitive but more performant data structures.</p></li><li><p>Implementing complex optimizations that may reduce readability.</p></li><li><p>Favoring efficiency over conventional coding patterns.</p></li></ul><p>This doesn&#8217;t mean the code is &#8220;unclean&#8221;. Rather, it&#8217;s clean within its specific context, optimized for the constraints and requirements of large-scale, high-performance systems.</p><p>Following every fancy article or book from renown engineers may be tempting but remember that your role is not to blindly apply these suggestions (which by no means are bad), but to:</p><ol><li><p>Understand the implementation context of each project.</p></li><li><p>Identify the most critical requirements (e.g., readability, performance, security)</p></li><li><p>Apply appropriate coding guidelines and patterns that align with these requirements.</p></li><li><p>Balance different aspect of code quality to achieve the best overall result.</p></li></ol><p>This approach requires critical thinking and often involves making trade-offs. Sometimes, you might prioritize readability and simplicity. Other times, like in Google&#8217;s case, you might lean towards performance optimizations.</p><h3>The Value of Code&nbsp;Reviews</h3><p>Code reviews play a crucial role in maintaining code quality within a specific context. It serves multiple purposes:</p><ol><li><p>Ensuring that every piece of code introduced adheres to the specific coding standards (some of these can certainly be automated through linters and formatters).</p></li><li><p>Catching bugs and potential issues early.</p></li><li><p>Sharing knowledge among team members.</p></li></ol><p>Let&#8217;s include a fourth purpose, which is confirming whether or not you reached the goal of writing understandable, maintainable and extendable code.</p><p>While code reviews focus on specific requirements and constraints of the project, isn&#8217;t it the best place to consider if my fellow team members are able to work with this piece of code introduced?</p><p>Reviewers should understand the context in which the code operates and evaluate it accordingly. Only then, code reviews evolve into a crucial piece for building software.</p><h3>Conclusion</h3><p>Building great software is inherently a collaborative effort, but aligning multiple minds towards the same goal is often more challenging than it appears. Writing &#8220;clean code&#8221; is, in essence, a team endeavor. It begins with one engineer crafting code that they believe aligns with the project&#8217;s constraints and coding best practices. The process continues as another team member reviews this code, offering valuable feedback and insights.</p><p>By understanding the unique needs of each project and applying clean code principles judiciously, we can create codebases that are truly &#8220;clean&#8221; in the ways that matter most for their specific contexts. This nuanced approach to clean code and code reviews leads to more effective, efficient, and maintainable software systems.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.reversepitch.io/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://www.reversepitch.io/subscribe?"><span>Subscribe now</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Comparing Programming Languages]]></title><description><![CDATA[Get to know the tools in your belt to build efficient, scalable and maintainable software.]]></description><link>https://www.reversepitch.io/p/comparing-programming-languages</link><guid isPermaLink="false">https://www.reversepitch.io/p/comparing-programming-languages</guid><dc:creator><![CDATA[Yuyi Kimura]]></dc:creator><pubDate>Thu, 18 Jul 2024 18:08:26 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!hMsm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1983e685-5641-4a0d-9708-f74f5c32699c_800x800.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As software engineers, choosing the right programming language, to learn or for a specific project, is critical for efficient, scalable and maintainable software. Different programming languages excel in different areas, and understanding their strengths and weaknesses can significantly impact the success of your projects. Today, we will be covering some of the most popular programming languages and highlight their ideal use cases.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hMsm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1983e685-5641-4a0d-9708-f74f5c32699c_800x800.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hMsm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1983e685-5641-4a0d-9708-f74f5c32699c_800x800.jpeg 424w, https://substackcdn.com/image/fetch/$s_!hMsm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1983e685-5641-4a0d-9708-f74f5c32699c_800x800.jpeg 848w, https://substackcdn.com/image/fetch/$s_!hMsm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1983e685-5641-4a0d-9708-f74f5c32699c_800x800.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!hMsm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1983e685-5641-4a0d-9708-f74f5c32699c_800x800.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hMsm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1983e685-5641-4a0d-9708-f74f5c32699c_800x800.jpeg" width="800" height="800" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1983e685-5641-4a0d-9708-f74f5c32699c_800x800.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:800,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&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="" srcset="https://substackcdn.com/image/fetch/$s_!hMsm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1983e685-5641-4a0d-9708-f74f5c32699c_800x800.jpeg 424w, https://substackcdn.com/image/fetch/$s_!hMsm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1983e685-5641-4a0d-9708-f74f5c32699c_800x800.jpeg 848w, https://substackcdn.com/image/fetch/$s_!hMsm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1983e685-5641-4a0d-9708-f74f5c32699c_800x800.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!hMsm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1983e685-5641-4a0d-9708-f74f5c32699c_800x800.jpeg 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 aria-hidden="true" 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><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">Get to know the tools in your belt. Generate by&nbsp;AI</figcaption></figure></div><h3>Python: The Versatile Workhorse</h3><p>It is very good in Data Science, Machine Learning, Automation, Scripting and Web Development.</p><h4>Why It&#8217;s&nbsp;Good?</h4><ul><li><p><strong>Ease of use: </strong>Python&#8217;s syntax is simple and readable, making it an excellent choice for new engineers and for rapid development.</p></li><li><p><strong>Libraries and frameworks.</strong> A vast ecosystem of libraries and frameworks, such as Django and Flask for web development; NumPy, pandas and TensorFlow for data science and machine learning.</p></li><li><p><strong>Community support: </strong>A large and active community means a lot of resources and tutorials. Based on Stack Overflow statistics, the top tag from questions in the past 3 years is Python.</p></li></ul><h4>What It&nbsp;Lacks?</h4><ul><li><p><strong>Performance</strong>: Python is generally slower than compiled languages like C++ or Java due to its interpreted nature.</p></li><li><p><strong>Mobile Development</strong>: While possible, mobile app development in Python is not robust at all and choosing other languages like Swift or Kotlin are way better choices.</p></li></ul><p><em>Ranked 1 in popularity as programming language (PYPL).</em></p><h3>Java: Enterprise Staple</h3><p>Use very frequently on enterprise applications, android development and large-scale systems.</p><h4>Why It&#8217;s&nbsp;Good?</h4><ul><li><p><strong>Platform Independence: </strong>Java&#8217;s motto is &#8220;write once, run anywhere&#8221;. This is thanks to the JVM which is a major advantage for cross-platform development.</p></li><li><p><strong>Robustness and Scalability: </strong>Java&#8217;s strong memory management and scalability make it ideal for large and complex enterprise systems.</p></li><li><p><strong>Mature Ecosystem: </strong>A mature ecosystem with battle-tested frameworks like Sprint and Hibernate enable rapid development, integration and support.</p></li></ul><h4>What It&nbsp;Lacks?</h4><ul><li><p><strong>Conciseness: </strong>Java is often criticized for its verbosity, which can lead to more boilerplate code compared to languages like Python or Kotlin.</p></li><li><p><strong>Performance: </strong>Although better than interpreted languages, Java&#8217;s performance if often behind that of C++ or Go for low-level tasks.</p></li></ul><p><em>Ranked 2 in popularity as programming language (PYPL).</em></p><h3><strong>JavaScript: The King of the&nbsp;Web</strong></h3><p>Best use cases are front-end web development, back-end development (with Node.js) and mobile development (with React Native).</p><h4>Why It&#8217;s&nbsp;Good?</h4><ul><li><p><strong>Versatility: </strong>With the advent of Node.js, JavaScript can now be used for server-side development, unifying both stacks.</p></li><li><p><strong>Rich Ecosystem: </strong>Frameworks like React, Angular and Vue.js revolutionize front-end development, while Express.js, NestJS and Fastify powers back-end services.</p></li><li><p><strong>Speed:</strong> Node.js, with its event-driven, non-blocking I/O model and single-threaded event loop, can handle multiple concurrent requests efficiently, making it fast and lightweight for I/O-bound tasks.</p></li></ul><h4>What It&nbsp;Lacks?</h4><ul><li><p><strong>CPU Performance</strong>: For computation-heavy applications, JavaScript may not be as performant as languages designed for such tasks, like C++.</p></li><li><p><strong>Language Stability: </strong>JavaScript has evolved to cover all bases, and even though that provides a great benefit, it also comes with drawbacks when moving to use-cases that were not part of JavaScript initial conception. Inheritance, incompatible API updates and nested callbacks are some of the common issues that arise when moving JavaScript to the servers (through Node.js).</p></li></ul><p><em>Ranked 3 in popularity as programming language (PYPL).</em></p><h3>C++: Performance Powerhouse</h3><p>One of the best programming languages for CPU-bound tasks, game development and real-time systems.</p><h4>Why It&#8217;s&nbsp;Good?</h4><ul><li><p><strong>Performance: </strong>As a compiled language, it offers excellent performance and fine-grained control over system resources.</p></li><li><p><strong>Memory Management: </strong>Direct memory manipulation using pointers allow for system-level programming and optimizations.</p></li><li><p><strong>Game Development:</strong> Unreal Engine, a leading game development engine is built using C++ due to its high performance and control.</p></li></ul><h4>What It&nbsp;Lacks?</h4><ul><li><p><strong>Simplicity: </strong>C++ is by no means a simple language, especially when delving into more complex concepts like pointers, manual memory management and multiple inheritances.</p></li><li><p><strong>Development Speed: </strong>Writing, debugging and maintaining C++ code can be more time-consuming than higher-level languages.</p></li></ul><p><em>Ranked 5 in popularity as programming language (PYPL).</em></p><h3>PHP: Backbone of the&nbsp;Web</h3><p>It is used for server-side web development, CMS and e-commerce platforms.</p><h4>Why It&#8217;s&nbsp;Good?</h4><ul><li><p><strong>Web Focus</strong>: PHP is specifically designed for server-side web development and excels in this domain. It has been laser-focus on the same niche therefore creating a strong backbone.</p></li><li><p><strong>CMS:</strong> Many popular content management systems, such as WordPress and Joomla are built on PHP, providing a vast ecosystem of plugin and themes.</p></li></ul><h4>What It&nbsp;Lacks?</h4><ul><li><p><strong>Modern Features: </strong>It has been criticized for lacking some modern features, although recent versions may have addressed some of these.</p></li><li><p><strong>Concurrency: </strong>PHP execution model is not well-suited for handling large number of concurrent connections like Node.js.</p></li></ul><p><em>Ranked 7 in popularity as programming language (PYPL).</em></p><h3>Go: Concurrency King</h3><p>It is very good for cloud services, DevOps tools and system tools.</p><h4>Why It&#8217;s&nbsp;Good?</h4><ul><li><p><strong>Concurrency: </strong>It&#8217;s built to support concurrent programming making it ideal for network servers and other concurrent tasks.</p></li><li><p><strong>Simplicity and Efficiency: </strong>Go is designed for simplicity and efficiency, with a clean syntax and fast complication times.</p></li><li><p><strong>Scalability: </strong>Go&#8217;s performance and efficient memory management make it suitable for large-scale systems.</p></li></ul><h4>What It&nbsp;Lacks?</h4><ul><li><p><strong>Standard Library: </strong>Go&#8217;s standard library is limited and often requires manual implementations for tasks that are usually available out-of-the-box in Python or Java.</p></li><li><p><strong>Learning Curve: </strong>Go introduce some unique concepts that may take time for developers to wrap in their heads. It may take more time to adopt Go if you come from other language.</p></li></ul><p><em>Ranked 12 in popularity as programming language (PYPL).</em></p><h3>Conclusion</h3><p>Choosing the right programming language hinges on the specific requirements and constraints of your project. While Python shines in data science and machine learning, JavaScript dominates web development. Java remains a strong choice for enterprise applications, and C++ is unparalleled for performance-critical tasks.</p><p>Understanding the strengths and limitations of each language empowers software engineers to make informed decisions, leading to more effective and efficient software development.</p><h3>References</h3><ul><li><p><a href="https://stackoverflow.blog/2023/01/26/comparing-tag-trends-with-our-most-loved-programming-languages/">Comparing tag trends with our Most Loved programming languages&#8202;&#8212;&#8202;Stack Overflow</a></p></li><li><p><a href="https://pypl.github.io/PYPL.html">PYPL PopularitY of Programming Language index</a></p></li></ul><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.reversepitch.io/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://www.reversepitch.io/subscribe?"><span>Subscribe now</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.reversepitch.io/p/comparing-programming-languages?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.reversepitch.io/p/comparing-programming-languages?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Getting Started with Celery: A Comprehensive Guide]]></title><description><![CDATA[Celery is a powerful, open-source, asynchronous task queue based on distributed messaging.]]></description><link>https://www.reversepitch.io/p/getting-started-with-celery-a-comprehensive</link><guid isPermaLink="false">https://www.reversepitch.io/p/getting-started-with-celery-a-comprehensive</guid><dc:creator><![CDATA[Yuyi Kimura]]></dc:creator><pubDate>Wed, 10 Jul 2024 18:47:19 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!0Dff!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb9576ad-f3de-4859-8435-75f824aaf50f_800x800.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0Dff!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb9576ad-f3de-4859-8435-75f824aaf50f_800x800.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0Dff!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb9576ad-f3de-4859-8435-75f824aaf50f_800x800.jpeg 424w, https://substackcdn.com/image/fetch/$s_!0Dff!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb9576ad-f3de-4859-8435-75f824aaf50f_800x800.jpeg 848w, https://substackcdn.com/image/fetch/$s_!0Dff!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb9576ad-f3de-4859-8435-75f824aaf50f_800x800.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!0Dff!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb9576ad-f3de-4859-8435-75f824aaf50f_800x800.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0Dff!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb9576ad-f3de-4859-8435-75f824aaf50f_800x800.jpeg" width="800" height="800" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fb9576ad-f3de-4859-8435-75f824aaf50f_800x800.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:800,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&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="" srcset="https://substackcdn.com/image/fetch/$s_!0Dff!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb9576ad-f3de-4859-8435-75f824aaf50f_800x800.jpeg 424w, https://substackcdn.com/image/fetch/$s_!0Dff!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb9576ad-f3de-4859-8435-75f824aaf50f_800x800.jpeg 848w, https://substackcdn.com/image/fetch/$s_!0Dff!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb9576ad-f3de-4859-8435-75f824aaf50f_800x800.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!0Dff!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb9576ad-f3de-4859-8435-75f824aaf50f_800x800.jpeg 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 aria-hidden="true" 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><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">Representation of Python Celery generated by&nbsp;AI</figcaption></figure></div><p>Celery is a powerful, open-source, asynchronous task queue based on distributed messaging. It focuses on real-time operation but supports scheduling as well. It is normally paired with web frameworks like Django or Flask to handle time consuming tasks outside of the web request/response cycle.</p><p>At its core, Celery is designed to handle tasks in the background, making it ideal for uses-cases in which you need to offload tasks to run them efficiently. Celery is highly flexible and can be integrated with a couple of messaging brokers like RabbitMQ and Redis.</p><h3>Common Use&nbsp;Cases</h3><p>Let&#8217;s go over some common use cases for Celery:</p><h4>1. Sending&nbsp;Emails</h4><p>Sending emails is a time-consuming task that can slow down your server&#8217;s response time if processed synchronously (waiting for the email to be sent to return a response). Celery allows you to send emails in the background, improving the user experience by making your application more responsive.</p><h4>2. Generating Reports</h4><p>Generating large reports can take significant amount of time, from fetching all the required data to transforming it into a visually effective report. Using Celery, you can delegate the report generation process in the background and notify the users once the report is ready to download (or send it via email).</p><h3>Code Examples</h3><p>Let&#8217;s dive into some code and see how Celery works. We will implement a simple Flask application for this example.</p><h4>1. Install Celery and&nbsp;Redis</h4><p>First, you need to install Celery and your message broker (for this example we will be using Redis)</p><pre><code>pip install celery redis Flask</code></pre><h4>(Optional) Run Redis using&nbsp;Docker</h4><p>Since you will need a Redis instance to start hacking with Celery, a good option is to spin it up using Docker. If you already have Docker installed, simply run the following command:</p><pre><code>docker run -d --name redis -p 6379:6379 redis</code></pre><p>This command will:</p><ul><li><p>Download the Redis image if it&#8217;s not already present on your system.</p></li><li><p>Run the Redis server in detached mode (<code>d</code>), mapping the default Redis port 6379 from the container to your host machine.</p></li></ul><h4>2. Create Flask Application</h4><p>Let&#8217;s create a simple Flask application in <code>app.py</code>:</p><pre><code>from flask import Flask, request, jsonify
from celery import Celery

app = Flask(__name__)

# Configure Celery
app.config['CELERY_BROKER_URL'] = 'redis://localhost:6379/0'

celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)

@celery.task
def send_email(recipient):
    # Simulate email sending
    import time
    time.sleep(5)
    return f'Email sent to {recipient}'

@app.route('/send-email', methods=['POST'])
def send_email_route():
    data = request.get_json()
    recipient = data['recipient']
    task = send_email.delay(recipient)
    return jsonify({ 'task_id': task.id }), 202

@app.route('/status/&lt;task_id&gt;')
def task_status(task_id):
    task = send_email.AsyncResult(task_id)
    if task.state == 'PENDING':
        response = {'state': task.state, 'status': 'Pending...'}
    elif task.state != 'FAILURE':
        response = {'state': task.state, 'result': task.result}
    else:
        response = {'state': task.state, 'status': str(task.info)}
    return jsonify(response)

if __name__ == '__main__':
    app.run(debug=True)</code></pre><h4>3. Run Flask and Celery&nbsp;Worker</h4><p>Run your Flask application:</p><pre><code>python app.py</code></pre><p>In a new terminal, start the Celery worker:</p><pre><code>celery -A app.celery worker --loglevel=info</code></pre><p>Let&#8217;s describe the whole flow:</p><ol><li><p>A client makes a POST request to <code>/send_email </code>with a JSON body containing the recipient&#8217;s email.</p></li><li><p>The Flask application will process the request and trigger a Celery task.</p></li><li><p>The Celery worker will receive the task and start the &#8220;processing&#8221; of sending an email.</p></li><li><p>There is an extra endpoint <code>/status/&lt;task_id&gt;</code> which allows the client to check the status of the task.</p></li></ol><h3>Benefits of Using&nbsp;Celery</h3><p>The above example is an oversimplification of what you can do with Celery, but even so, we can mention a whole list of benefits from it:</p><h4>Asynchronous Processing</h4><p>Celery allows task to be executed asynchronously, which can greatly enhance the performance of your server application. In a real-world scenario, in which you have a lot of customers executing actions that requires time-consuming operations, moving those operations to the background can avoid your app to get bloated of requests, impacting the experience of your customers.</p><h4>Scalability</h4><p>Celery is designed to be highly scalable, allowing you to distribute tasks across multiple workers (even on different machines). This allows you to horizontally scale your worker pool for tasks that are more demanding without increasing your application server as a whole.</p><h4>Scheduling</h4><p>In addition to these real-time tasks, Celery supports scheduling, making it easy to run periodic tasks.</p><h3>Challenges of Using&nbsp;Celery</h3><p>There is no silver bullet in technology, therefore we can&#8217;t ignore the intrinsic challenges from adding a new tool to your stack.</p><h4>Complexity</h4><p>Setting up and managing a distributed task queue can add complexity to your application.</p><h4>Error Handling</h4><p>Proper error handling and monitoring are essential to ensure that tasks are not failing silently. Celery supports retry logic and a couple of error handling mechanism, but it&#8217;s up to you to use them correctly.</p><h4>Dependency</h4><p>Celery relies on external message broker (Redis, RabbitMQ, etc.), therefore it may include a dependency to your project.</p><h3>Conclusion</h3><p>Celery is an invaluable tool for any Python developer looking to handle asynchronous tasks and improve the performance of their applications. While it does introduce some complexity, the benefits of using Celery often outweigh the challenges, especially for applications that require efficient task management.</p><p>By following this guide, you should now have a basic understanding of how to set up and use Celery in your Python projects. Whether you&#8217;re sending emails, generating reports, or handling any other background tasks, Celery can help you manage these tasks efficiently and effectively.</p>]]></content:encoded></item><item><title><![CDATA[The role of AI in software development]]></title><description><![CDATA[Coding in the Age of AI: Opportunities and Challenges]]></description><link>https://www.reversepitch.io/p/the-role-of-ai-in-software-development</link><guid isPermaLink="false">https://www.reversepitch.io/p/the-role-of-ai-in-software-development</guid><dc:creator><![CDATA[Yuyi Kimura]]></dc:creator><pubDate>Wed, 26 Jun 2024 11:01:44 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!mrz9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd74a6c16-307e-481c-9244-fee3d3ffe8b1_800x800.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mrz9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd74a6c16-307e-481c-9244-fee3d3ffe8b1_800x800.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mrz9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd74a6c16-307e-481c-9244-fee3d3ffe8b1_800x800.jpeg 424w, https://substackcdn.com/image/fetch/$s_!mrz9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd74a6c16-307e-481c-9244-fee3d3ffe8b1_800x800.jpeg 848w, https://substackcdn.com/image/fetch/$s_!mrz9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd74a6c16-307e-481c-9244-fee3d3ffe8b1_800x800.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!mrz9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd74a6c16-307e-481c-9244-fee3d3ffe8b1_800x800.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mrz9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd74a6c16-307e-481c-9244-fee3d3ffe8b1_800x800.jpeg" width="800" height="800" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d74a6c16-307e-481c-9244-fee3d3ffe8b1_800x800.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:800,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&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="" srcset="https://substackcdn.com/image/fetch/$s_!mrz9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd74a6c16-307e-481c-9244-fee3d3ffe8b1_800x800.jpeg 424w, https://substackcdn.com/image/fetch/$s_!mrz9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd74a6c16-307e-481c-9244-fee3d3ffe8b1_800x800.jpeg 848w, https://substackcdn.com/image/fetch/$s_!mrz9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd74a6c16-307e-481c-9244-fee3d3ffe8b1_800x800.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!mrz9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd74a6c16-307e-481c-9244-fee3d3ffe8b1_800x800.jpeg 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 aria-hidden="true" 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><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">Generated using AI, because why not?</figcaption></figure></div><p>Artificial Intelligence (AI) is becoming an increasingly integral part of the software development process, bringing both exciting opportunities and significant challenges. In this evolving landscape, understanding how AI can elevate your work&#8202;&#8212;&#8202;from automating boring tasks to supercharging software development&#8202;&#8212;&#8202;is essential. However, it is equally important to remain aware of the potential pitfalls, such as the risk of reducing engineers to mere operators of AI-driven tools.</p><p>This article delves into the transformative role of AI in software development. We&#8217;ll explore how this technology is reshaping the developer&#8217;s toolkit and landscape, examine its current capabilities and limitations, and consider its implications for the future of the industry.</p><h3>AI in Development Tools</h3><p>AI tools are revolutionizing the software development process by automating repetitive tasks such as code generation, bug detection, and testing. While these tools are becoming increasingly popular, their effectiveness depends heavily on the hands that wield them. As an engineer, you need to thoroughly understand and analyze the requirements and constraints of your software project. Using AI tools can assist you with repetitive tasks and provide missing pieces of knowledge, creating a powerful synergy between human intuition and AI assistance.</p><p>However, the relationship between developers and AI tools can become toxic when engineers start relying too heavily on these digital assistants, <strong>sacrificing their critical thinking </strong>in the process. It&#8217;s important to remember that these are tools meant to aid, not replace, human creativity. In the current state of AI, and for the foreseeable future, engineers remain the essential minds behind software development, harnessing these tools to enhance their work effectively.</p><p>Think of it this way: you shouldn&#8217;t ask AI to construct an entire house; instead, you might task it with designing a door. It&#8217;s your responsibility as an engineer to ensure that the door is placed correctly and meets all necessary specifications.</p><p>To use AI tools efficiently and avoid the trap of overreliance, consider asking yourself these critical questions before accepting generated code or ideas:</p><ul><li><p><strong>Do I fully understand the requirements of what I need to create or write?</strong></p></li><li><p><strong>Can I break down this task into more specific, manageable components?</strong></p></li><li><p><strong>Am I capable of critically evaluating the AI-generated code?</strong></p></li><li><p><strong>Will this AI-generated code integrate seamlessly with our existing codebase and architecture?</strong></p></li></ul><p>By consistently reflecting on these questions, you maintain your role as the architect of your code, using AI as a powerful assistant rather than an autopilot. This approach ensures that you harness the benefits of AI while retaining control and oversight over your projects, leading to more robust and innovative software development.</p><div class="pullquote"><p>GitHub Copilot is a brilliant name. You are still the one driving the plane while being assisted by your&nbsp;copilot.</p></div><h3>AI in Talent&nbsp;Search</h3><p>AI has significantly impacted the talent search for software engineers, reshaping both sides of the coin with positive and negative implications.</p><p>On the recruitment side, AI-powered tools for candidate screening and skill assessment are becoming more prevalent. These tools can speed up the selection process, allowing recruiters to focus on candidates who match the job requirements. However, they can also exclude qualified candidates and may show biases based on the data they were trained on. Therefore, a balanced approach that combines AI with human intuition is essential.</p><p>For candidates, the environment has become more controversial due to what is called <strong>skill inflation</strong>. AI tools can help engineers produce complex code or sophisticated answers to technical questions, potentially masking their true skill levels and making them appear more proficient than they actually are. This makes the recruiter&#8217;s job more challenging, leading to a shift in the recruiting process. Recruiters are adding multiple layers of screening and interviews to delve deeper into a candidate&#8217;s thought process and problem-solving abilities.</p><p>This shift has made both job searching and talent acquisition more complex, sparking debate on whether AI benefits or detriments the recruitment process overall.</p><p>I believe that in this area, it is crucial for both parties to maintain high levels of integrity and honesty to navigate the increasing complexity in acquiring good talent or finding a suitable job.</p><h3>Conclusion</h3><p>Ultimately, the role of AI in software development is a powerful tool that, when used correctly, can greatly enhance the capabilities of engineers and the efficiency of development processes. However, it&#8217;s crucial to approach AI with a balanced perspective, leveraging its strengths while remaining vigilant about its limitations. By doing so, engineers can navigate the evolving landscape of AI in software development with integrity and innovation, ensuring a bright future for the industry.</p>]]></content:encoded></item><item><title><![CDATA[Memory Profiling and Load Testing a Python Application]]></title><description><![CDATA[Optimizing Python Applications: A Guide to Memory Profiling and Load Testing]]></description><link>https://www.reversepitch.io/p/memory-profiling-and-load-testing</link><guid isPermaLink="false">https://www.reversepitch.io/p/memory-profiling-and-load-testing</guid><dc:creator><![CDATA[Yuyi Kimura]]></dc:creator><pubDate>Wed, 19 Jun 2024 23:26:45 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49da6783-5229-40a6-ae3b-6e7e86c052fc_700x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When working on software development, it&#8217;s crucial to ensure your application is both efficient and can handle a large amount of traffic. This is where memory profiling and load testing come into play. They allow us to monitor and optimize the performance of our applications.</p><p>This guide is about profiling and testing using tools that you can run on your computer, which is very useful to detect memory leaks, bugs or under-performing code before pushing to production.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.reversepitch.io/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 Dev Whisper! 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><blockquote><p><em>These techniques are not a replacement for cloud monitoring and observability tools, they cover way more ground and provide a lot of insight about your application (but they are also expensive).</em></p></blockquote><h1><strong>Load Testing</strong></h1><p>Load testing is a technique that simulate real-world conditions to understand the behavior of an application under heavy load. It allows engineers to foresee and fix potential performance issues before they affect real users.</p><p>We&#8217;ll be using <code>locust</code> to load test a simple Flask application in order to show how we can simulate real-world scenarios through its powerful, scriptable nature.</p><p>We will need to install some dependencies:</p><pre><code>pip install flask Faker</code></pre><p>Now, let&#8217;s code a simple a Flask application (<code>app.py</code>):</p><pre><code>import random
from faker import Faker
from flask import Flask, jsonify

fake = Faker()
app = Flask(__name__)


def generate_users():
    """
    Generate a list of random users.
    """
    users = []
    for i in range(100):
        users.append(
            {
                "id": i,
                "name": fake.name(),
                "age": random.randint(18, 99),
                "email": fake.email(),
            }
        )

    return users


def generate_user(user_id: int):
    """
    Generate a random user by ID.
    """
    return {
        "id": user_id,
        "name": fake.name(),
        "age": random.randint(18, 99),
        "email": fake.email(),
    }


@app.route("/users", methods=["GET"])
def list_users():
    """
    List users endpoint.
    """
    return jsonify({"status": 200, "users": generate_users()})


@app.route("/users/&lt;int:user_id&gt;", methods=["GET"])
def get_user(user_id: int):
    """
    Get user by ID endpoint.
    """
    return jsonify({"status": 200, "user": generate_user(user_id)})


if __name__ == "__main__":
    app.run(debug=False)</code></pre><p>We can run this application by simply executing: <code>python app.py</code>.</p><p>You can perform a <code>GET /users</code> request to visualize the list of users:</p><pre><code># Using cURL
curl localhost:5000/users

# Or simply visit &lt;http://localhost:5000/users&gt; in your browser</code></pre><p>Now that we have an application to put under load test, let&#8217;s get started with <code>locust</code>. First, let&#8217;s install it:</p><pre><code>pip install locust</code></pre><p>Once installed, we&#8217;ll write a <code>locustfile.py</code> that defines the behavior of our simulated users. In the script, we&#8217;ll specify the endpoints that locust should hit and the wait time before each defined task.</p><pre><code>import random
from locust import HttpUser, task, between


class SimulatedUser(HttpUser):
    wait_time = between(1, 5)

    @task(1)
    def view_users(self):
        self.client.get("/users")

    @task(4)
    def view_user_by_id(self):
        user_id = random.randint(1, 100)
        self.client.get(f"/users/{user_id}")</code></pre><p>The above code presents an example of how to use Locust, a popular load testing tool, with a Flask application. Here is a detailed description of the key concepts involved:</p><ul><li><p><strong>HttpUser</strong>: This is a class represents a simulated user and they should mimic real world users. In the script, we define a class <code>SimulatedUser</code> that inherits from <code>HttpUser</code>.</p></li><li><p><strong>Task</strong>: The <code>task</code> decorator is used to specify methods that the <code>HttpUser</code> should execute when simulating a user.</p></li><li><p><strong>wait_time</strong>: This is a property of the <code>HttpUser</code> class that specifies how long a simulated user should wait between executing tasks.</p></li></ul><p>We can now run our Locust script by simply executing:</p><pre><code>locust -f locustfile.py</code></pre><p>This will spin up a web interface at <a href="http://localhost:8089">http://localhost:8089</a> in which you can specify your testing arguments as follow:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pDaQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d49637d-8636-4893-b6a0-0d2be440e52b_700x370.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pDaQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d49637d-8636-4893-b6a0-0d2be440e52b_700x370.png 424w, https://substackcdn.com/image/fetch/$s_!pDaQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d49637d-8636-4893-b6a0-0d2be440e52b_700x370.png 848w, https://substackcdn.com/image/fetch/$s_!pDaQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d49637d-8636-4893-b6a0-0d2be440e52b_700x370.png 1272w, https://substackcdn.com/image/fetch/$s_!pDaQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d49637d-8636-4893-b6a0-0d2be440e52b_700x370.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pDaQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d49637d-8636-4893-b6a0-0d2be440e52b_700x370.png" width="700" height="370" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5d49637d-8636-4893-b6a0-0d2be440e52b_700x370.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:370,&quot;width&quot;:700,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!pDaQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d49637d-8636-4893-b6a0-0d2be440e52b_700x370.png 424w, https://substackcdn.com/image/fetch/$s_!pDaQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d49637d-8636-4893-b6a0-0d2be440e52b_700x370.png 848w, https://substackcdn.com/image/fetch/$s_!pDaQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d49637d-8636-4893-b6a0-0d2be440e52b_700x370.png 1272w, https://substackcdn.com/image/fetch/$s_!pDaQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d49637d-8636-4893-b6a0-0d2be440e52b_700x370.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 aria-hidden="true" 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><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">Locust web interface</figcaption></figure></div><p>In this interface, we define three main arguments:</p><ul><li><p><strong>Number of users</strong>: Total number of users you want to simulate at peak concurrency.</p></li><li><p><strong>Ramp up:</strong> The number of users that will be simulated per seconds (in our example it means that 10 new users will be added to the load each second until they reach the peak which is 1000).</p></li><li><p><strong>Host:</strong> This is the host of your server application that each user will target while executing their tasks. Since our Flask application is running locally on port 5000, the value here is <a href="http://localhost:5000">http://localhost:5000</a></p></li></ul><p>Click the <code>Start</code> button, you Locust will start the load test. The first tab that you will notice is the <code>Statistics</code> one, in which you can view a table with all the requests executed and their response time and some other stats.</p><p>Let&#8217;s move to the <code>Charts</code> tab to get a more friendly representation of your application performance. Here you will get three charts:</p><ul><li><p><strong>Total Requests per Second</strong>: This is basically the number of requests your application is handling per second.</p></li><li><p><strong>Number of Users</strong>: The last chart simply indicates the number of users over time.</p></li><li><p><strong>Response Times (ms):</strong> This is how long your application is taking to response the requests. You will see two lines here:</p><ul><li><p><strong>Average Response Time</strong>: Which as the name states, is the average response time it takes.</p></li><li><p><strong>95th percentile:</strong> Which indicate the response time below which 95% of all recorded response times fall. For example, if the 95th percentile response is 50ms, it means that 95% of the requests were completed in less than 50ms, while the remaining 5% took longer.</p><p><em><br></em>It&#8217;s important that your 95th percentile isn&#8217;t significantly higher than the average response time, since it may indicate performance issues on an important subset of users.</p></li></ul></li></ul><p>There are other tabs in which you can monitor the Failures or Exceptions that may have occur during the tests. This is very important since you can debug possible failures that only happen during heavy-load scenarios.</p><p>Locust also allows you to download the report in a HTML format so you can visualize later and compare it after you have improved your application.</p><h1>Memory profiling</h1><p>Memory profiling consist in analyzing a program&#8217;s memory consumption to identify and solve issues related to unusual memory usage. It helps you understand how you application allocate resources and its very useful when sizing your cloud instances correctly.</p><p>There are multiple tools for memory profiling out there, but for today post, will be using <code>memray</code> because of its ease of use and the various reports it can generate.</p><p>Let&#8217;s install it using <code>pip</code>:</p><pre><code>pip install memray </code></pre><p>Using our Flask application built above, let&#8217;s now perform memory profiling:</p><pre><code>memray run -o result.bin app.py</code></pre><p>Once the application is running, you can perform the load test defined above to simulate a real-world scenario while <code>memray</code> tracks the memory usage.</p><p>After running the load test for a while, simply stop <code>memray</code> (<code>Ctrl + C</code> the process) and it will generate a <code>result.bin</code> file with all the tracked data.</p><p>Now we can generate a report using the following command:</p><pre><code>memray flamegraph result.bin</code></pre><p>This will generate a flame graph in HTML format for you to visualize in your browser. Flame graphs are a visualization of program resource usage that help identify which parts of your code are consuming the most memory during execution.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QMzB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2a48831-de2d-40d7-a24d-7be4012902b9_700x370.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QMzB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2a48831-de2d-40d7-a24d-7be4012902b9_700x370.png 424w, https://substackcdn.com/image/fetch/$s_!QMzB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2a48831-de2d-40d7-a24d-7be4012902b9_700x370.png 848w, https://substackcdn.com/image/fetch/$s_!QMzB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2a48831-de2d-40d7-a24d-7be4012902b9_700x370.png 1272w, https://substackcdn.com/image/fetch/$s_!QMzB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2a48831-de2d-40d7-a24d-7be4012902b9_700x370.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QMzB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2a48831-de2d-40d7-a24d-7be4012902b9_700x370.png" width="700" height="370" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f2a48831-de2d-40d7-a24d-7be4012902b9_700x370.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:370,&quot;width&quot;:700,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!QMzB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2a48831-de2d-40d7-a24d-7be4012902b9_700x370.png 424w, https://substackcdn.com/image/fetch/$s_!QMzB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2a48831-de2d-40d7-a24d-7be4012902b9_700x370.png 848w, https://substackcdn.com/image/fetch/$s_!QMzB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2a48831-de2d-40d7-a24d-7be4012902b9_700x370.png 1272w, https://substackcdn.com/image/fetch/$s_!QMzB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2a48831-de2d-40d7-a24d-7be4012902b9_700x370.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 aria-hidden="true" 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><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">Flame graph generated by memray</figcaption></figure></div><p>Each block on the x-axis represents a function in the code, with the size of the block representing the amount of memory that function uses. The y-axis represents the stack depth. <code>memray</code> actually defaults to the <code>Icicles</code> view which is basically inverting the y-axis so the root is at the top and the functions at the bottom. You can choose either view based on your preference.</p><p>However, the critical detail to note is the width of the function blocks. The wider a block is, the more memory has been allocated to that function. Therefore, if a block appears unusually wide, it could indicate that a potential memory leak is affecting your application.</p><p>Another very important graph within <code>memray</code> is the memory size over time, which you can see by clicking the header with the orange and blue lines. In this graph you can see the Resident Size and the Heap Size and how much memory is allocated over time.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Bffw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46a41f92-bfc3-4511-b2da-edc086053a07_700x370.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Bffw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46a41f92-bfc3-4511-b2da-edc086053a07_700x370.png 424w, https://substackcdn.com/image/fetch/$s_!Bffw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46a41f92-bfc3-4511-b2da-edc086053a07_700x370.png 848w, https://substackcdn.com/image/fetch/$s_!Bffw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46a41f92-bfc3-4511-b2da-edc086053a07_700x370.png 1272w, https://substackcdn.com/image/fetch/$s_!Bffw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46a41f92-bfc3-4511-b2da-edc086053a07_700x370.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Bffw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46a41f92-bfc3-4511-b2da-edc086053a07_700x370.png" width="700" height="370" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/46a41f92-bfc3-4511-b2da-edc086053a07_700x370.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:370,&quot;width&quot;:700,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Bffw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46a41f92-bfc3-4511-b2da-edc086053a07_700x370.png 424w, https://substackcdn.com/image/fetch/$s_!Bffw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46a41f92-bfc3-4511-b2da-edc086053a07_700x370.png 848w, https://substackcdn.com/image/fetch/$s_!Bffw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46a41f92-bfc3-4511-b2da-edc086053a07_700x370.png 1272w, https://substackcdn.com/image/fetch/$s_!Bffw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46a41f92-bfc3-4511-b2da-edc086053a07_700x370.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 aria-hidden="true" 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><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">Memory size over time graph</figcaption></figure></div><p>This graph is crucial because, under normal circumstances, you would expect these lines to maintain a specific range. If your application includes memory-bound endpoints, you might anticipate some spikes. However, based on how you&#8217;ve defined your load test, these lines should normalize once the memory-bound endpoints have completed their tasks. Consequently, if a line continually grows over time without ever decreasing, it&#8217;s a significant sign of a memory leak.</p><h1><strong>Bonus: Simulate memory leak</strong></h1><p>As a bonus section, let&#8217;s simulate a memory leak so we can see how both tools can help us identify it.</p><p>First, let&#8217;s update our Python code so we introduce a memory leak endpoint (something you should never do in production):</p><pre><code># Intentional memory leak: a growing list
leaked_data = []


@app.route("/leak")
def leak_memory():
    """
    Memory leak endpoint.
    """
    leaked_data.append([i for i in range(10000)])
    return jsonify({"status": "Memory leaked!"})</code></pre><p>Every time a request is made to this endpoint, a list of 10,000 integers is created and appended to a global list named <code>leaked_data</code>. Because <code>leaked_data</code> is a global list and is not cleaned up after each request, the memory it uses does not get freed up. This means every time a request is made to the <code>/leak</code> endpoint, more and more memory is used up, simulating a memory leak.</p><p>Let&#8217;s update our <code>locustfile.py</code> to include this endpoint call:</p><pre><code>import random
from locust import HttpUser, task, between


class SimulatedUser(HttpUser):
    wait_time = between(1, 3)

    @task(1)
    def view_users(self):
        self.client.get("/users")

    @task(3)
    def memory_leak(self):
        self.client.get("/leak")

    @task(4)
    def view_user_by_id(self):
        user_id = random.randint(1, 100)
        self.client.get(f"/users/{user_id}")</code></pre><p>Now, we can simply run the application using memray:</p><pre><code>memray run -o result.bin app.py</code></pre><p>And the load test using locust:</p><pre><code>locust -f locustfile.py</code></pre><p>Once you&#8217;ve set up your load test parameters and allowed it to run for some time, you should terminate the <code>memray</code> process. This will generate a <code>result.bin</code> file containing the tracked data. You can then produce a flame graph using this data:</p><pre><code>memray flamegraph result.bin</code></pre><p>Now let&#8217;s review both statistics generated by Locust and Memray:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!f2XY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffef0aff3-6c3b-4e93-bfe0-8534cb062514_700x400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!f2XY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffef0aff3-6c3b-4e93-bfe0-8534cb062514_700x400.png 424w, https://substackcdn.com/image/fetch/$s_!f2XY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffef0aff3-6c3b-4e93-bfe0-8534cb062514_700x400.png 848w, https://substackcdn.com/image/fetch/$s_!f2XY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffef0aff3-6c3b-4e93-bfe0-8534cb062514_700x400.png 1272w, https://substackcdn.com/image/fetch/$s_!f2XY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffef0aff3-6c3b-4e93-bfe0-8534cb062514_700x400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!f2XY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffef0aff3-6c3b-4e93-bfe0-8534cb062514_700x400.png" width="700" height="400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fef0aff3-6c3b-4e93-bfe0-8534cb062514_700x400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:700,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!f2XY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffef0aff3-6c3b-4e93-bfe0-8534cb062514_700x400.png 424w, https://substackcdn.com/image/fetch/$s_!f2XY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffef0aff3-6c3b-4e93-bfe0-8534cb062514_700x400.png 848w, https://substackcdn.com/image/fetch/$s_!f2XY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffef0aff3-6c3b-4e93-bfe0-8534cb062514_700x400.png 1272w, https://substackcdn.com/image/fetch/$s_!f2XY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffef0aff3-6c3b-4e93-bfe0-8534cb062514_700x400.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 aria-hidden="true" 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><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">Charts from Locust web interface</figcaption></figure></div><p>As the number of our requests increases, we observe that our response times largely remain consistent, barring a single spike. This was expected since the memory leak we introduced does not significantly affect the CPU performance of the application. Thus, we could conclude that our application has <strong>successfully passed</strong> its load test.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GfLx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26557390-775e-4496-bb8b-25e9ac9dd296_700x400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GfLx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26557390-775e-4496-bb8b-25e9ac9dd296_700x400.png 424w, https://substackcdn.com/image/fetch/$s_!GfLx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26557390-775e-4496-bb8b-25e9ac9dd296_700x400.png 848w, https://substackcdn.com/image/fetch/$s_!GfLx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26557390-775e-4496-bb8b-25e9ac9dd296_700x400.png 1272w, https://substackcdn.com/image/fetch/$s_!GfLx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26557390-775e-4496-bb8b-25e9ac9dd296_700x400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GfLx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26557390-775e-4496-bb8b-25e9ac9dd296_700x400.png" width="700" height="400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/26557390-775e-4496-bb8b-25e9ac9dd296_700x400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:700,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!GfLx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26557390-775e-4496-bb8b-25e9ac9dd296_700x400.png 424w, https://substackcdn.com/image/fetch/$s_!GfLx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26557390-775e-4496-bb8b-25e9ac9dd296_700x400.png 848w, https://substackcdn.com/image/fetch/$s_!GfLx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26557390-775e-4496-bb8b-25e9ac9dd296_700x400.png 1272w, https://substackcdn.com/image/fetch/$s_!GfLx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26557390-775e-4496-bb8b-25e9ac9dd296_700x400.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 aria-hidden="true" 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><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">Flame graph (Icicles) of our memory leaking application</figcaption></figure></div><p>Here, we can observe more alarming graphs. As explained earlier, the wider the function blocks, the higher the memory allocation. Therefore, it&#8217;s easy to identify that the <code>leaked_data.append(...)</code> block is responsible for the unusual memory consumption.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wIeS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49da6783-5229-40a6-ae3b-6e7e86c052fc_700x400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wIeS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49da6783-5229-40a6-ae3b-6e7e86c052fc_700x400.png 424w, https://substackcdn.com/image/fetch/$s_!wIeS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49da6783-5229-40a6-ae3b-6e7e86c052fc_700x400.png 848w, https://substackcdn.com/image/fetch/$s_!wIeS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49da6783-5229-40a6-ae3b-6e7e86c052fc_700x400.png 1272w, https://substackcdn.com/image/fetch/$s_!wIeS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49da6783-5229-40a6-ae3b-6e7e86c052fc_700x400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wIeS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49da6783-5229-40a6-ae3b-6e7e86c052fc_700x400.png" width="700" height="400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/49da6783-5229-40a6-ae3b-6e7e86c052fc_700x400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:700,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!wIeS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49da6783-5229-40a6-ae3b-6e7e86c052fc_700x400.png 424w, https://substackcdn.com/image/fetch/$s_!wIeS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49da6783-5229-40a6-ae3b-6e7e86c052fc_700x400.png 848w, https://substackcdn.com/image/fetch/$s_!wIeS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49da6783-5229-40a6-ae3b-6e7e86c052fc_700x400.png 1272w, https://substackcdn.com/image/fetch/$s_!wIeS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49da6783-5229-40a6-ae3b-6e7e86c052fc_700x400.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 aria-hidden="true" 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><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">Memory size over time of our memory leaking application</figcaption></figure></div><p>Examining the memory size over time, we notice that it grows but never shrinks. This indicates a memory leak, as memory is not being released. This issue arises due to the use of a global variable in our example.</p><p>As you can see, memory profiling empowers you to detect issues within your application quickly and efficiently, eliminating the need for long hours of debugging and excessive memory usage logging.</p><h1><strong>Conclusion</strong></h1><p>Ensuring that your application is both efficient and capable of handling high traffic is very important in software development. Through the use of memory profiling and load testing, developers can proactively identify and resolve performance bottlenecks and memory leaks before they affect end users.</p><p>The goal of this guide is to equip you with the tools needed to understand how your application behaves under various loads and to detect unusual memory consumption before it impacts your users. By using load testing and memory profiling, you can identify and address performance issues proactively, ensuring a smoother experience for your customers.</p><p>Feel free to experiment with these tools and adapt them to your specific needs. Happy profiling and testing!</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.reversepitch.io/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 Dev Whisper! 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[How to Handle Long Running Jobs on HTTP]]></title><description><![CDATA[Effective strategy and some best practices for managing long-running HTTP requests]]></description><link>https://www.reversepitch.io/p/how-to-handle-long-running-jobs-on</link><guid isPermaLink="false">https://www.reversepitch.io/p/how-to-handle-long-running-jobs-on</guid><dc:creator><![CDATA[Yuyi Kimura]]></dc:creator><pubDate>Fri, 14 Jun 2024 03:09:15 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!F8ub!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ea517ac-1edf-4949-8f82-3d46dfde16d8_1500x640.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There are situations where we need to perform complex or long running operations in our server while exposing it via an API. Those situations will force you to make a choice:</p><ul><li><p>Make the client wait for the response, which make takes more than a minute. (Bad choice)</p></li><li><p>Handle it using a queue and return a task/job resource from which the client can query the progress and eventually the result. (Good choice)</p></li></ul><p>These situations are very common, and turning a long running job into a resource will make your implementation more robust and gives you benefits in both client and server.</p><h2>How can we do this?</h2><p>We accomplish this using an event-based architecture. Basically, our Web API will create a task/job and publish it to an Event Broker. An Event Broker is like an administrator who listen the messages of other services and publish them to specific "spaces" (channels) where other services are waiting for new messages. Take a look to the image below to better understand 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_!F8ub!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ea517ac-1edf-4949-8f82-3d46dfde16d8_1500x640.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!F8ub!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ea517ac-1edf-4949-8f82-3d46dfde16d8_1500x640.png 424w, https://substackcdn.com/image/fetch/$s_!F8ub!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ea517ac-1edf-4949-8f82-3d46dfde16d8_1500x640.png 848w, https://substackcdn.com/image/fetch/$s_!F8ub!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ea517ac-1edf-4949-8f82-3d46dfde16d8_1500x640.png 1272w, https://substackcdn.com/image/fetch/$s_!F8ub!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ea517ac-1edf-4949-8f82-3d46dfde16d8_1500x640.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!F8ub!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ea517ac-1edf-4949-8f82-3d46dfde16d8_1500x640.png" width="1456" height="621" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5ea517ac-1edf-4949-8f82-3d46dfde16d8_1500x640.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:621,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Event Broker Diagram.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&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="Event Broker Diagram.png" title="Event Broker Diagram.png" srcset="https://substackcdn.com/image/fetch/$s_!F8ub!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ea517ac-1edf-4949-8f82-3d46dfde16d8_1500x640.png 424w, https://substackcdn.com/image/fetch/$s_!F8ub!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ea517ac-1edf-4949-8f82-3d46dfde16d8_1500x640.png 848w, https://substackcdn.com/image/fetch/$s_!F8ub!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ea517ac-1edf-4949-8f82-3d46dfde16d8_1500x640.png 1272w, https://substackcdn.com/image/fetch/$s_!F8ub!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ea517ac-1edf-4949-8f82-3d46dfde16d8_1500x640.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 aria-hidden="true" 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><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>Here we have a very simple (and summarized) diagram in which a client will be requesting the server to apply a cool filter to an image.</p><p>Let's assume this process is long (which may be depending on the filter&#129331;) and making the client wait for it could result in HTTP timeouts or making the site freeze for several seconds.</p><p>In order to tackle this, the Web API will create a Task and send the reference (a unique id) back to the client. Then, the Web API will publish a message to the Event Broker telling the Workers (Image Resizer, Image Processing and Image Upload) that there is a new job for them. These workers can subscribe to channels/topics in the Event Broker, and when a new message arrive to one of those channels it will notify everyone who is subscribed.</p><p>The Workers will start making their job and publishing messages on the Event Broker when they finish (either if the job succeeded or failed). The Web API must be subscribed to these "result" channels and will update the Task status depending on the progress made by the workers. When all Workers finish their jobs successfully, the Task status will change to completed and the URL of the filtered image will be available for the client.</p><p>But wait, how will the client receive the new URL of the filtered image&#129300;? Well, there are several ways to do this.</p><h3>HTTP Polling</h3><p>HTTP Polling is one way to solve this. It consists of repeating an HTTP request over an interval of time. Basically, we will be making a request using the Task reference to the server and if the status is not "Completed" (or "Failed") it will retry again after X seconds.</p><h3>Web Sockets</h3><p>Using Web Sockets the server can send an event to the client when the Task gets completed so the client will get the filtered image when it's ready. This is a better approach in terms of resource consumption but would require adding the complexity of web sockets to your application.</p><p>Either way, our client can now get the filtered image without having to make an HTTP request that takes over a minute to complete&#127881;.</p><h2>Side notes</h2><ul><li><p>When creating the task/job resource, the correct HTTP status code is 202 Accepted. Also, a reference of the task should be sent, like an id or an uri if you are using REST.</p></li><li><p>Cool kids allow the jobs to be deleted from the queue using the reference received on creation. Be a cool kid.</p></li><li><p>Pro kids add an expiration date to tasks, so they don't overwhelm the server. Be a pro kid, even if you are not a cool kid.</p></li></ul><h2>Conclusion</h2><p>There are several patterns and architectures that handle these cases, this is just a personal preference, and I would really like to read your approaches and recommendations in the comment section&#128513;.</p>]]></content:encoded></item></channel></rss>