<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Manish Shivanandhan - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Manish Shivanandhan - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Wed, 14 Oct 2026 18:33:26 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/manishshivanandhan/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Healthcare AI Won't Work Until You Fix Your Data ]]>
                </title>
                <description>
                    <![CDATA[ Building AI for clinical settings is harder than it looks. It takes more than picking a good model or tuning the right parameters. When engineers enter a hospital ecosystem, they quickly discover that ]]>
                </description>
                <link>https://www.freecodecamp.org/news/healthcare-ai-won-t-work-until-you-fix-your-data/</link>
                <guid isPermaLink="false">6abdfdcf1585eb815aed0e73</guid>
                
                    <category>
                        <![CDATA[ healthcare ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Thu, 01 Oct 2026 06:29:35 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/3306532c-8aae-4b82-8529-77387b8dba04.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Building AI for clinical settings is harder than it looks. It takes more than picking a good model or tuning the right parameters.</p>
<p>When engineers enter a hospital ecosystem, they quickly discover that the tools they rely on in other industries often break down. Clinical data is messy, sensitive, and spread across many systems. Handling it well isn't a nice-to-have. It's the foundation everything else rests on.</p>
<p>Clinical data comes in many forms. Some of it is structured, like lab results stored in a table. Some of it is not, like a doctor's handwritten note scanned into a PDF. All of it is subject to strict privacy rules. And all of it can affect a real patient's care.</p>
<p>Unlike e-commerce or advertising, where a bad model just costs money, a bad clinical AI can cost someone their health. That is why rethinking your data pipeline is the most important thing you can do before writing a single line of model code.</p>
<p>In this article, we'll cover why standard data pipelines break in hospital environments, how data quality shapes model performance far more than architecture does, and where the gap between engineers and clinicians leads to real-world failures. We'll also look at the challenges of working across clinical text, images, and telemetry simultaneously, and what it takes to build systems that stay reliable as data, populations, and documentation practices shift over time.</p>
<h3 id="heading-what-well-cover">What We'll Cover:</h3>
<ul>
<li><p><a href="#heading-why-standard-data-pipelines-break-in-hospitals">Why Standard Data Pipelines Break in Hospitals</a></p>
</li>
<li><p><a href="#heading-data-quality-matters-more-than-model-choice">Data Quality Matters More Than Model Choice</a></p>
</li>
<li><p><a href="#heading-the-gap-between-engineers-and-clinicians">The Gap Between Engineers and Clinicians</a></p>
</li>
<li><p><a href="#heading-working-with-multiple-data-types-at-once">Working With Multiple Data Types at Once</a></p>
</li>
<li><p><a href="#heading-building-systems-that-hold-up-over-time">Building Systems That Hold Up Over Time</a></p>
</li>
</ul>
<h2 id="heading-why-standard-data-pipelines-break-in-hospitals">Why Standard Data Pipelines Break in Hospitals</h2>
<p>Most software pipelines are built for stability. They expect clean schemas and predictable inputs.</p>
<p>Hospitals are the opposite. A single patient record may touch an Electronic Health Record (EHR) system, a radiology archive, a bedside monitor, a lab information system, and several pages of free-text clinical notes, all at the same time.</p>
<p>If you're exploring this field, the <a href="https://research.com/online-degrees/artificial-intelligence/best-ai-masters-degrees-for-ai-in-healthcare-careers">Research.com comparison of AI master's programs for healthcare careers</a> is a useful starting point for understanding what interdisciplinary skills the work requires. It's a career guide, not a regulatory standard, but it shows how broad the field is.</p>
<p>The data that flows through hospital systems is inconsistent by nature. Different labs use different names for the same test. Standards like LOINC exist to fix this, but mapping everything takes real effort. Notes that are neatly coded at one hospital may show up as free text at another. And records often have gaps. Sometimes a test was never ordered. Sometimes a patient missed an appointment.</p>
<p>When engineers try to run standard extract, transform, and load (ETL) pipelines on clinical data, three problems appear again and again.</p>
<p>First, the formats are completely different from each other. Narrative physician notes, DICOM medical images, and continuous vital sign streams all need different preprocessing steps, and a single relational query can't handle all three.</p>
<p>Second, the timing is irregular. Clinical observations are collected when care happens, not on a fixed schedule, which means longitudinal records have gaps and uneven intervals that need to be handled carefully rather than filled in.</p>
<p>Third, the terminology keeps changing. ICD-10, SNOMED CT, and LOINC are all updated regularly, and old records shouldn't be overwritten to match a new version. They need versioning and careful mapping so their original meaning is preserved.</p>
<p>The only way to handle this reliably is with ingestion pipelines that are version-aware and flexible enough to represent many source systems, not just one clean schema.</p>
<h2 id="heading-data-quality-matters-more-than-model-choice">Data Quality Matters More Than Model Choice</h2>
<p>In clinical AI, the model is only part of the equation. Training data quality, how well it represents the target population, how labels were assigned, and what the data actually means clinically all shape whether a model works in the real world. A large model trained on biased or incomplete records will reproduce those problems at scale.</p>
<p>This is why the field is shifting from a model-centric approach to a data-centric one. The transformer architecture that underpins <a href="https://www.freecodecamp.org/news/the-paper-that-created-modern-ai-the-story-behind-the-transformer/">modern AI</a> brought enormous gains in language understanding. But better architecture alone doesn't fix bad labels, missing demographics, or training sets that don't reflect the patients a model will actually see.</p>
<p>For high-stakes clinical work, data can't be treated as a static input. It needs to be managed throughout the entire system lifecycle.</p>
<h3 id="heading-how-to-modernize-clinical-data-processing">How to Modernize Clinical Data Processing</h3>
<p>Three practices help most.</p>
<p>First, use healthcare interoperability standards like <a href="https://www.hl7.org/training/fhir-fundamentals.cfm">HL7 FHIR</a> where they fit the use case. FHIR gives you a standardized way to exchange health records across systems.</p>
<p>It does not, however, solve terminology mapping or data quality on its own. Those still take dedicated engineering work.</p>
<p>Second, establish privacy and de-identification processes that match the actual intended use. Not every record needs all protected health information stripped out before it enters a training environment. Under the U.S. HIPAA Privacy Rule, protected health information can be used or disclosed in certain ways, including for some research purposes.</p>
<p>When de-identification is required, HIPAA recognizes two methods: Expert Determination and Safe Harbor. Automated NLP can help flag identifiers in text, but a rule-based NLP system alone doesn't guarantee HIPAA compliance.</p>
<p>Third, check whether your training data actually represents the patients you're trying to serve. A large dataset isn't automatically representative. Look at missingness patterns, site-level differences, measurement practices, and whether key subgroups are present in meaningful numbers.</p>
<h2 id="heading-the-gap-between-engineers-and-clinicians">The Gap Between Engineers and Clinicians</h2>
<p>Clinical AI doesn't succeed through engineering alone. Clinical context shapes everything: what a model should predict, when that prediction is useful, who will read it, and what they'll do with it. A technically strong model that doesn't fit the clinical workflow will simply not be used.</p>
<p>A number in a medical record isn't just a number. It's a measurement taken from a real person in a busy hospital, often under time pressure. Missing that context leads to models that work on paper but fail in practice.</p>
<p>Research has consistently shown that clinician acceptance and workflow fit are among the biggest barriers to AI adoption in healthcare. That's why intended users should be involved in design and evaluation from the start, not brought in at the end for sign-off.</p>
<p><a href="https://www.freecodecamp.org/news/how-to-stop-letting-ai-agents-fake-their-own-tests/">AI agents</a> are taking on more clinical administrative tasks. This makes human-in-the-loop verification even more important, not less. A model output needs a human check at the right point in the workflow, not as a formality, but as a real safety layer.</p>
<p>This is easy to get wrong in subtle ways. Imagine a team builds a strong model for predicting hospital readmission. But the model uses diagnosis codes that are only finalized after a patient is discharged. At the moment the prediction is supposed to help, those codes don't exist yet. The model can't run in real time.</p>
<p>That's temporal leakage, and it only reveals itself when you think carefully about when data is actually available in the clinical workflow.</p>
<h3 id="heading-three-operational-insights-worth-knowing">Three Operational Insights Worth Knowing</h3>
<p>Missing data in clinical records is often meaningful, not random. Differences in healthcare access, documentation habits, and care patterns can all determine what shows up and what does not.</p>
<p>The <a href="https://www.nist.gov/itl/ai-risk-management-framework">NIST AI Risk Management Framework</a> offers voluntary guidance on managing AI risks, including bias, but it doesn't prescribe how healthcare developers should interpret record completeness.</p>
<p>Synthetic data can help with rare conditions where real examples are scarce. But it should be used carefully. Before using synthetic samples in training, teams should evaluate clinical plausibility, potential bias amplification, and whether the generated examples preserve meaningful medical relationships. Synthetic data isn't a drop-in substitute for real patient records.</p>
<p>Finally, including clinical domain experts in labeling, requirements gathering, and usability testing isn't a soft nice-to-have. It's the practical step that keeps model inputs and outputs aligned with what clinicians actually need.</p>
<h2 id="heading-working-with-multiple-data-types-at-once">Working With Multiple Data Types at Once</h2>
<p>Healthcare AI often has to work across very different types of data at the same time. A CT or MRI study requires a completely different pipeline from a set of physician notes or a real-time ICU telemetry stream. These formats don't share processing logic. They can't.</p>
<p>When building a workflow for a <a href="https://www.freecodecamp.org/news/what-happens-to-a-medical-image-before-and-after-a-model-sees-it/">medical image</a> processing pipeline, engineers need to handle DICOM metadata, pixel spacing, image orientation, intensity conventions, and spatial alignment before the model ever sees the data. The right preprocessing steps depend on the imaging type and the task at hand.</p>
<p>Text from physician notes is its own challenge. Clinical NLP has to handle negation ("no fever"), abbreviations, local acronyms, temporal references, and specialized terminology that general-purpose language models may not understand well.</p>
<p>As <a href="https://www.freecodecamp.org/news/what-is-agentic-ai-from-chatbot-to-co-worker/">agentic AI</a> takes on more complex, multi-step clinical workflows, the underlying systems also need to preserve and reconcile context across all of these modalities, not just handle each one in isolation. Failing to preprocess or harmonize a data type correctly degrades model performance. Sometimes it makes the inputs incompatible with the model entirely.</p>
<h2 id="heading-building-systems-that-hold-up-over-time">Building Systems That Hold Up Over Time</h2>
<p>Security, privacy, data quality, and regulatory requirements aren't afterthoughts in clinical AI. They're structural requirements. And they vary depending on jurisdiction, data type, and what the system actually does. Not every healthcare AI product is regulated the same way.</p>
<p>Every system should maintain clear records of data provenance, software versions, and model versions. This supports reproducibility, troubleshooting, and whatever compliance obligations apply. It doesn't mean every prediction needs a cryptographic signature, but it does mean you need enough information to trace a result back to its source.</p>
<p>Scalability in clinical AI means more than handling high request volume. It also means asking whether model performance holds up when the patient population shifts, when documentation practices change, or when a hospital replaces its lab equipment or imaging scanners.</p>
<p>These changes affect model inputs. They need to be detected, assessed, and tested before the system goes live with the new setup. Regulated AI-enabled medical devices may also be subject to formal change-control requirements, adding another layer to consider.</p>
<p>General-purpose <a href="https://www.freecodecamp.org/news/build-ai-applications-that-switch-models-automatically/">AI applications</a> can route work between models dynamically based on cost or task type. Clinical systems can explore similar ideas, but they require validation, governance, and safety controls that go well beyond what a general software system needs.</p>
<h3 id="heading-engineering-steps-for-better-governance">Engineering Steps for Better Governance</h3>
<p>Set up monitoring for data and model drift from the beginning. Track changes in model inputs, patient populations, acquisition systems, and documentation practices. When something changes, investigate whether it affects model performance. The right monitoring thresholds depend on the system's risk level and intended use, not a one-size-fits-all rule.</p>
<p>Maintain auditable data lineage and integrity controls. Keep records of where data came from, how it was transformed, who accessed it, and what the system did with it. Cryptographic techniques can help in some architectures, but they're not a universal HIPAA requirement for every record.</p>
<p>Design clear mechanisms for human oversight from day one. Where clinicians are expected to review AI recommendations, the interface should make it easy to understand the basis for a recommendation, its limitations, and what information it used. The right override or escalation path depends on what the system does and how it's regulated. That isn't something you can bolt on later.</p>
<h3 id="heading-the-real-work-starts-with-the-data">The Real Work Starts With the Data</h3>
<p>Most teams building healthcare AI spend the bulk of their time on models. The architecture, the training loop, the evaluation metrics. These things matter. But they are not where most clinical AI projects fail.</p>
<p>Projects fail because the data was never truly understood. Records had gaps that no one investigated. Labels were applied by people who did not know the clinical context. Training sets did not reflect the patients the system would eventually serve. And by the time any of this became clear, the model was already built.</p>
<p>Getting clinical AI right means treating data as the core engineering problem, not a preprocessing step. It means building pipelines that handle messy, multimodal, and constantly changing inputs. It means working with clinicians early, not late. And it means putting governance, monitoring, and human oversight in place before you need them, not after something goes wrong.</p>
<p>The clinical setting is unforgiving. The stakes are high. But teams that invest in the data foundation first are the ones that ship systems clinicians actually trust and use.</p>
<p>Hope you enjoyed this article. You can <a href="https://linkedin.com/in/manishmshiva">connect with me on LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The 7 Essential Parts of Your Online Presence ]]>
                </title>
                <description>
                    <![CDATA[ Your online presence often gives potential employers, clients, partners, and recruiters their first impression of you. It's likely what they see before they ever meet you. They search your name, read  ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-7-essential-parts-of-your-online-presence/</link>
                <guid isPermaLink="false">6aa9b393e892e731e337e0e3</guid>
                
                    <category>
                        <![CDATA[ portfolio ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Open Source ]]>
                    </category>
                
                    <category>
                        <![CDATA[ social media ]]>
                    </category>
                
                    <category>
                        <![CDATA[ job search ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Tue, 15 Sep 2026 21:07:31 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/1858aeea-9446-48d3-abeb-225f14aae371.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Your online presence often gives potential employers, clients, partners, and recruiters their first impression of you. It's likely what they see before they ever meet you.</p>
<p>They search your name, read your posts, and look at your profiles. All of this happens before the first call.</p>
<p>A strong online presence doesn't mean joining every social network. It means that the places people find you tell one clear, credible story about what you do.</p>
<p>Here are the seven parts that matter most:</p>
<ul>
<li><p><a href="#heading-1-a-strong-professional-profile">1. A Strong Professional Profile</a></p>
</li>
<li><p><a href="#heading-2-a-personal-website">2. A Personal Website</a></p>
</li>
<li><p><a href="#heading-3-a-portfolio-of-real-work">3. A Portfolio of Real Work</a></p>
</li>
<li><p><a href="#heading-4-a-content-trail">4. A Content Trail</a></p>
</li>
<li><p><a href="#heading-5-one-identity-across-platforms">5. One Identity Across Platforms</a></p>
</li>
<li><p><a href="#heading-6-an-obvious-way-to-reach-you">6. An Obvious Way to Reach You</a></p>
</li>
<li><p><a href="#heading-7-upkeep-and-reputation-checks">7. Upkeep and Reputation Checks</a></p>
</li>
<li><p><a href="#heading-making-it-actually-work">Making It Actually Work</a></p>
</li>
</ul>
<h2 id="heading-1-a-strong-professional-profile">1. A Strong Professional Profile</h2>
<p>After finding your name, most people check your profile next. For many, that means <a href="https://www.linkedin.com/">LinkedIn</a>.</p>
<p>Treat it as more than a résumé. Your headline should explain your focus, not just your job title. Your summary should say what problems you solve and what work you want more of.</p>
<p>Your experience section should show outcomes. Don't write that you "managed a team." Write what the team achieved. Don't write that you "worked on a product." Write the problem you solved and what changed because of it.</p>
<p>Keep it consistent: your name, title, history, and photo should match your website. A recruiter should never wonder if they found the right person.</p>
<p><a href="https://www.linkedin.com/pulse/9-examples-great-linkedin-profiles-andrea-vahl/">Here are a few LinkedIn profiles</a> that will show you how to build a profile that stands out from the rest.</p>
<h2 id="heading-2-a-personal-website">2. A Personal Website</h2>
<p>Your website is the base of everything else. It's the one place you fully control.</p>
<p>Social profiles are useful, but they belong to platforms. Designs, algorithms, and rules change. Your own site does not.</p>
<p>More importantly, your website and your LinkedIn profile aren't just the same thing in a different wrapper.</p>
<p>LinkedIn is structured around employment history. It lists your roles in chronological order, inside a template you share with hundreds of millions of people.</p>
<p>Your website is structured around <em>you</em>. It can lead with the specific problem you solve, put your best work front and center, and give visitors a feel for how you think, none of which a profile page can do well.</p>
<p>A consultant, for example, might open their site with a one-line summary of the outcome they deliver ("I help fintech startups reduce churn in their first year"), followed by two or three case studies, and a short essay about their approach. That combination would be invisible on LinkedIn and is exactly what a website is for.</p>
<p>It doesn't need to be complex. One page is often enough. Include your name, your role, a short intro, your experience, a few work samples, and how to reach you.</p>
<p>Clarity beats polish. A visitor should know in five seconds who you are and why it matters.</p>
<p>If you don't want to code, Onepage is an AI-powered website and landing page builder that lets you turn a simple prompt into a professional website within minutes. The AI can generate the initial layout, content, images, and individual sections, while everything remains fully editable through OnePage's visual no-code editor.</p>
<p>You can refine the design and content, add forms and other elements, connect your own domain, and publish the finished site with built-in hosting, without needing a developer or managing a complicated technical setup.</p>
<p>Prefer open source? <a href="https://docs.github.com/en/pages/quickstart">GitHub Pages</a> hosts a site, blog, or résumé for free. <a href="https://jekyllrb.com/docs/">Jekyll</a> works with it out of the box. <a href="https://gohugo.io/getting-started/quick-start/">Hugo</a> is faster and gives you more control, and both have large theme libraries so you can skip the design work.</p>
<p>The goal isn't the most impressive site. It's a reliable home that represents you well.</p>
<h2 id="heading-3-a-portfolio-of-real-work">3. A Portfolio of Real Work</h2>
<p>Credentials say what you did, while a portfolio shows it.</p>
<p>This matters most for designers, developers, writers, marketers, consultants, and researchers. If your work can be shown, show it.</p>
<p>A long project list isn't a portfolio. Each piece needs context. Explain the problem, your role, what you did, and the result.</p>
<p>An engineer can walk through the technical problem, the architecture choices, and the outcome. A marketer can cover the strategy, audience, and numbers. A designer can show how research shaped the final screens.</p>
<p>The most useful projects to include are ones where you can clearly explain the problem, your specific contribution, and a measurable result.</p>
<p>A developer might show a tool they built to automate something tedious, explaining the technical tradeoffs and the time it saved. A product manager might walk through a prioritization call , why they chose one feature over three others, what data drove it, and what shipped as a result.</p>
<p>A UX researcher might document a usability study: the questions, the findings, and how the design changed because of them. These are more convincing than a list of company names because they let someone evaluate <em>how</em> you think, not just <em>where</em> you've been.</p>
<p>Is your work confidential? You can still prove skill. Use anonymized case studies, technical articles, talks, or written lessons.</p>
<p>For developers, open source work is one of the strongest portfolio signals available. A public repository shows real code, real decisions, and (if it has contributors or stars) real adoption.</p>
<p>If you've contributed to an existing project, link to specific pull requests and explain the problem you solved. If you've built your own tool or library, make sure the README reads like a case study, what does it do, why did you build it, and who is it for?</p>
<p>If you're looking for inspiration on how to present your portfolio site itself, the <a href="https://github.com/topics/portfolio-website">portfolio-website topic</a> on GitHub is a useful starting point: developers have tagged thousands of live portfolio sites there, covering a wide range of tech stacks and layouts, and you can browse them to find patterns that work or fork one as a foundation.</p>
<p>The rule is simple: show evidence, not claims.</p>
<h2 id="heading-4-a-content-trail">4. A Content Trail</h2>
<p>Your presence gets much stronger when you publish useful ideas.</p>
<p>You don't need to post daily. A few solid articles a year beat a hundred empty ones.</p>
<p>Write about what you know. Explain a hard concept. Share a project lesson. Break down a trend. Document something you built. Describe a mistake and what it taught you.</p>
<p>Over time this becomes a searchable record of your expertise.</p>
<p>It also does something a résumé can't. A résumé lists what you did, while your writing shows how you think.</p>
<p>You can publish anywhere. A hosted platform like <a href="https://substack.com/">Substack</a> needs zero setup. A blog on your own domain gives you full ownership. Developers can also write in their repo docs or on a community site.</p>
<p>Stay focused. You want your name tied to two or three areas, not twenty.</p>
<h2 id="heading-5-one-identity-across-platforms">5. One Identity Across Platforms</h2>
<p>Your presence has many pieces. They should feel like one person.</p>
<p>Use the same name everywhere. Keep your photo roughly consistent. Link your site from your profiles, and your profiles from your site.</p>
<p>Picture someone finding your website, then LinkedIn, then GitHub. Each stop should add something. None should confuse.</p>
<p>This doesn't mean posting the same thing everywhere. Each platform has a job. Your site is the hub, LinkedIn carries your history, GitHub shows your code, and a social account or blog shows your thinking.</p>
<p>Think of them as different windows into the same room.</p>
<h2 id="heading-6-an-obvious-way-to-reach-you">6. An Obvious Way to Reach You</h2>
<p>A lot of professional sites make contact hard. That's a costly mistake.</p>
<p>If someone wants to hire you, work with you, or invite you to speak, they shouldn't have to hunt. Give them one clear next step.</p>
<p>That could be an email address. It could be a contact form, a LinkedIn link, or a booking page like <a href="https://cal.com/">Cal.com</a>.</p>
<p>You don't need to share personal details. A separate work email keeps things clean.</p>
<p>What matters is that the method is visible, current, and actually checked.</p>
<h2 id="heading-7-upkeep-and-reputation-checks">7. Upkeep and Reputation Checks</h2>
<p>An online presence isn't a one-time build.</p>
<p>A stale site can hurt as much as no site. Old titles, dead links, dropped projects, and expired domains all signal neglect.</p>
<p>Every few months, set aside an hour. Check that your site loads. Update your current role and recent wins. Cut what's out of date. Then search your own name and see what shows up.</p>
<p>That last step is the most useful one. Search engines surface old profiles, forum comments, conference pages, and accounts you forgot. <a href="https://www.google.com/alerts">Google Alerts</a> can flag new mentions for you, and Google's <a href="https://myactivity.google.com/results-about-you">results about you</a> tool lets you request removal of sensitive listings.</p>
<p>You can't control everything online, but you should know what's there.</p>
<h2 id="heading-making-it-actually-work">Making It Actually Work</h2>
<p>A good online presence isn't a pile of profiles or a fancy website. It's a clear digital identity that makes your skills easy to grasp and your work easy to check.</p>
<p>Start small: build a simple personal website. Sharpen one professional profile. Add two or three real work examples. Publish a few useful pieces. Then make your contact details obvious.</p>
<p>Use a no-code tool if you want speed. Use GitHub Pages with Jekyll or Hugo if you want control. Either path works.</p>
<p>The best presence isn't the one with the most features. It's the one that answers three questions fast. Who are you? What can you do? And why should anyone trust you?</p>
<p>Answer those clearly and your presence stops being a digital résumé. It becomes an asset that brings you opportunities, even when you aren't looking.</p>
<p>Hope you enjoyed this article. You can <a href="https://linkedin.com/in/manishmshiva">connect with me on LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How AI Is Changing Malware Detection: From Traditional Antivirus to Next-Gen Protection ]]>
                </title>
                <description>
                    <![CDATA[ Malware used to be simple to describe. A virus attached itself to a file, and antivirus software removed it. That world is gone. Today, a single attack can steal your passwords, lock up your photos, w ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-ai-is-changing-malware-detection/</link>
                <guid isPermaLink="false">6aa41cc6739dc5dd502bad21</guid>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Malware ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ai agents ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Fri, 11 Sep 2026 15:22:46 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/891dc84b-49d3-4823-bf82-fc5acac84c43.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Malware used to be simple to describe. A virus attached itself to a file, and antivirus software removed it.</p>
<p>That world is gone. Today, a single attack can steal your passwords, lock up your photos, watch what you type, and hide inside software you trust.</p>
<p>The bigger problem is volume. The <a href="https://www.av-test.org/en/statistics/malware/">AV-TEST Institute records over 450,000 new malicious programs</a> every single day. No security team can review that many files by hand. So the job has moved to machines, and antivirus software's decision-making has changed with it.</p>
<p>In this article, we'll look at how signature scanning worked and why it started to fail. We'll also cover what machine learning adds, how behaviour tracking catches ransomware while it runs, how cloud threat data turns every device into a sensor, and where AI still gets things wrong.</p>
<h3 id="heading-what-well-cover">What We'll Cover:</h3>
<ul>
<li><p><a href="#heading-signature-scanning-worked-until-malware-learned-to-change">Signature Scanning Worked Until Malware Learned to Change</a></p>
</li>
<li><p><a href="#heading-why-todays-malware-is-so-hard-to-spot">Why Today's Malware is So Hard to Spot</a></p>
</li>
<li><p><a href="#heading-what-machine-learning-adds-to-the-picture">What Machine Learning Adds to the Picture</a></p>
</li>
<li><p><a href="#heading-watching-what-software-does-not-just-what-it-looks-like">Watching What Software Does, Not Just What it Looks Like</a></p>
</li>
<li><p><a href="#heading-stopping-ransomware-while-its-still-running">Stopping Ransomware While it's Still Running</a></p>
</li>
<li><p><a href="#heading-the-cloud-turns-every-device-into-a-sensor">The Cloud Turns Every Device into a Sensor</a></p>
</li>
<li><p><a href="#heading-catching-the-attack-before-malware-ever-lands">Catching the Attack Before Malware Ever Lands</a></p>
</li>
<li><p><a href="#heading-where-ai-still-gets-it-wrong">Where AI Still Gets it Wrong</a></p>
</li>
<li><p><a href="#heading-layers-beat-any-single-trick">Layers Beat Any Single Trick</a></p>
</li>
<li><p><a href="#heading-what-this-means-for-you">What This Means For You</a></p>
</li>
</ul>
<h2 id="heading-signature-scanning-worked-until-malware-learned-to-change">Signature Scanning Worked Until Malware Learned to Change</h2>
<p>Early antivirus software used signatures. A signature is a small pattern taken from a known bad file, a bit like a fingerprint.</p>
<p>Researchers found a piece of malware, pulled out its pattern, and added it to a database. Your antivirus downloaded that database and compared it against every file on your disk. A match meant the file was blocked.</p>
<p>This was fast, cheap, and easy to trust. It also had one big weakness.</p>
<p>Attackers figured out that they only had to change the file a little. A new name, some padding, a different way of packing the code, and the fingerprint no longer matched. The old signature was suddenly useless.</p>
<p>That created a gap. A new threat would spread for hours or days before anyone wrote a signature for it. Attackers now build thousands of tiny variations of the same program on purpose, making it a losing race to write one signature per version.</p>
<p>Signatures are still worth keeping. They catch known threats in milliseconds. They just can't be the only thing standing between you and an attack.</p>
<h2 id="heading-why-todays-malware-is-so-hard-to-spot">Why Today's Malware is So Hard to Spot</h2>
<p>Modern malware tries hard to look boring.</p>
<p>It may sit quiet for days before doing anything. It may arrive as a harmless-looking script and download the real payload later. Some of it never writes a file to disk at all, which is why Microsoft groups these as <a href="https://learn.microsoft.com/en-us/defender-endpoint/malware/fileless-threats">fileless threats</a>.</p>
<p>Worse, plenty of attacks use tools that are already on your computer. An attacker who gets access can run commands through <a href="https://attack.mitre.org/techniques/T1059/001/">PowerShell</a>, a normal Windows administration tool. The <a href="https://lolbas-project.github.io/">LOLBAS project</a> catalogues hundreds of trusted Windows programs that can be abused this way.</p>
<p>Nothing malicious is being installed here. A trusted tool is simply being used for the wrong reason. A file scanner has almost nothing to grab onto.</p>
<p>So the question security software asks has changed. It's no longer just "have I seen this file before?" It's "what is this program actually doing?"</p>
<h2 id="heading-what-machine-learning-adds-to-the-picture">What Machine Learning Adds to the Picture</h2>
<p>Machine learning doesn't give software a sixth sense. It gives it a way to make a judgment call from evidence.</p>
<p>A model is trained on huge sets of files, both safe and harmful. Over time, it learns which traits tend to show up in each group. It learns about file structure, how the code is packed, which system calls it makes, what it talks to over the network, and how it interacts with other programs.</p>
<p>When something new arrives, the model weighs those traits and estimates the risk. It never saw this exact file, but it has seen the shape of the problem before.</p>
<p>This matters most for variants. Attackers often rewrite the surface of their code and keep the guts the same. Signatures miss the family resemblance. A model trained on behaviour and structure often catches it.</p>
<h2 id="heading-watching-what-software-does-not-just-what-it-looks-like">Watching What Software Does, Not Just What it Looks Like</h2>
<p>The biggest shift in antivirus protection is the move from scanning files to watching actions.</p>
<p>Picture an unknown program starting up on a laptop. Within seconds, it opens hundreds of documents, rewrites each one, changes their file extensions, deletes the recovery copies, and calls out to a server nobody recognises.</p>
<p>There may be no signature for it anywhere. But that pattern is ransomware, and it's unmistakable.</p>
<p>Microsoft describes this approach in its documentation on <a href="https://learn.microsoft.com/en-us/defender-endpoint/behavioral-blocking-containment">behavioral blocking and containment</a>, where machine learning models score a chain of actions rather than a single file. Individual steps can look innocent. Read together, they tell a story.</p>
<p>The advantage is timing. The software doesn't need to have met this exact malware before. It only needs to notice the shape of the attack early enough to cut it off.</p>
<h2 id="heading-stopping-ransomware-while-its-still-running">Stopping Ransomware While it's Still Running</h2>
<p>Ransomware shows why this matters more than any other threat type.</p>
<p>Known ransomware families get caught by signatures without trouble. But a brand new variant will often slip straight past them. That's the whole point of building a new variant.</p>
<p>Behavior monitoring gives you a second chance. The software watches for rapid file changes across many folders, attempts to delete backups or shadow copies, and processes trying to shut off security tools. Federal guidance on the <a href="https://www.cisa.gov/stopransomware">CISA StopRansomware hub</a> leans on the same signals, alongside offline backups you can actually restore from.</p>
<p>Once enough warning signs stack up, the software can kill the process or pull the device off the network. Even a partial save matters here. Stopping an attack after fifty encrypted files is a very different day than stopping it after fifty thousand.</p>
<p>Products aimed at everyday users are moving the same way. The <a href="https://nordvpn.com/next-gen-antivirus/">next-gen antivirus from NordVPN</a> blocks malicious downloads and scam pages before they reach the device, which shows how consumer tools have widened past plain file matching.</p>
<h2 id="heading-the-cloud-turns-every-device-into-a-sensor">The Cloud Turns Every Device into a Sensor</h2>
<p>Everything so far has been about <em>what</em> security software examines: files first, then behaviour. The other big change is <em>where</em> that examination happens.</p>
<p>Signature scanning ran start to finish on your machine. Your antivirus pulled down a database, compared files against it locally, and that was the entire decision.</p>
<p>Modern protection splits the work instead. Cheap checks stay on the device so they're instant, and the harder calls get handed to the vendor's cloud, which can see far more than any one laptop ever will.</p>
<p>Here's the actual sequence: First, the agent installed on your device records security-relevant events: process launches, parent-child process relationships, registry edits, outbound connections, file hashes. When it meets something it can't classify on its own, it sends metadata about it (typically the hash, the file's structural traits, and the surrounding activity, rather than the whole document) to the vendor's backend over an encrypted channel.</p>
<p>Microsoft documents this handoff for Defender in its notes on <a href="https://learn.microsoft.com/en-us/defender-endpoint/cloud-protection-microsoft-defender-antivirus">cloud protection</a>, where the local client queries the cloud service for a verdict and briefly holds the file while it waits for an answer.</p>
<p>The backend does two jobs at once. Automated systems compare the submission against what millions of other devices have reported and score it with models far too large to ship to a laptop.</p>
<p>If the picture is clear, a verdict comes back in under a second with no human involved. If it isn't, the case escalates to the vendor's threat research and security operations teams, the analysts employed specifically to hunt for clusters like this.</p>
<p>That's what makes the "few thousand devices" signal worth something. If the same unfamiliar binary, or the same odd process chain, appears across thousands of unrelated organisations inside an hour, no single one of them would notice. The backend sees the cluster immediately and flags it for a human to open up. Analysts pull samples, detonate them in a sandbox, confirm what the code does, and write a detection for it.</p>
<p>Then the loop closes. Confirmed cases become labelled training data, which is exactly what the next generation of models needs. The output goes out in two speeds: new indicators like hashes, domains and behavioural rules reach every protected device within minutes, while retrained models follow on a slower cycle of days or weeks.</p>
<p>Either way, the person targeted next is protected by what your device reported, and nobody had to wait for the next big database download.</p>
<h2 id="heading-catching-the-attack-before-malware-ever-lands">Catching the Attack Before Malware Ever Lands</h2>
<p>Not every threat arrives as a program. Most start with a message.</p>
<p>Phishing is still the front door. The APWG counted <a href="https://apwg.org/trendsreports/">more than one million phishing attacks in a single quarter</a>, and the fake pages are getting harder to eyeball. Attackers copy bank branding, login screens, and delivery notices closely enough to fool careful people.</p>
<p>AI helps by checking the things humans skip: how old the domain is, whether the link redirects somewhere odd, and whether the page matches a known scam kit.</p>
<p>Blocking a page like that stops the attack one step earlier. No download, no file to scan, and no cleanup.</p>
<h2 id="heading-where-ai-still-gets-it-wrong">Where AI Still Gets it Wrong</h2>
<p>AI brings real problems along with the benefits, and it's worth being clear about them.</p>
<p>False positives are the everyday one. Unusual isn't the same as malicious, and software that blocks a legitimate app because it looked odd trains people to switch protection off.</p>
<p>Speed is another. All this analysis has to happen without making the machine feel slow.</p>
<p>Then there's the arms race. Attackers study these models too. NIST's report on <a href="https://csrc.nist.gov/pubs/ai/100/2/e2025/final">adversarial machine learning</a> lays out how models get poisoned during training or fooled at the moment of decision. A model is a target, not a fortress.</p>
<p>Privacy deserves a mention as well. Cloud analysis means some information about your files and connections leaves your device. It's fair to ask any vendor what they collect and how long they keep it.</p>
<h2 id="heading-layers-beat-any-single-trick">Layers Beat Any Single Trick</h2>
<p>None of this replaces what came before. The strongest setups stack methods on purpose.</p>
<p>Signatures handle known malware instantly. Reputation checks block bad sites and untrusted programs. Behaviour monitoring catches suspicious activity as it happens. Machine learning fills the gap for threats nobody has named yet.</p>
<p>The <a href="https://attack.mitre.org/">MITRE ATT&amp;CK framework</a> is useful here because it maps out attacker techniques so teams can see which layer covers which step.</p>
<p>Layers also give the software context. A file with a clean history that starts acting strangely deserves a closer look. A file already known to be malware doesn't need any analysis at all.</p>
<h2 id="heading-what-this-means-for-you">What This Means For You</h2>
<p>Antivirus software has moved a long way from matching files against a list.</p>
<p>Signatures still earn their place, but they only answer one question. AI and behaviour monitoring answer a better one: what is this software doing right now, and does it make sense?</p>
<p>The practical takeaway is short. Good protection today is less about recognizing bad files and more about noticing bad behavior quickly. If you're choosing security software, ask whether it watches activity or only scans files, and check whether it blocks dangerous sites and downloads before they arrive.</p>
<p>Attacks keep getting faster and more automated. The defenses have to work the same way, and that's the real reason AI ended up at the centre of malware detection.</p>
<p>Hope you enjoyed this article. You can <a href="https://linkedin.com/in/manishmshiva">connect with me on LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Deployment Checklist That Actually Prevents Production Incidents ]]>
                </title>
                <description>
                    <![CDATA[ Count the items on your deployment checklist. If there are more than a handful, the length is worth a second look. Part of it is likely your team being careful. Part of it may be a record of how much  ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-deployment-checklist-that-actually-prevents-production-incidents/</link>
                <guid isPermaLink="false">6aa1a7edf42d135b6e7c6de3</guid>
                
                    <category>
                        <![CDATA[ deployment ]]>
                    </category>
                
                    <category>
                        <![CDATA[ production ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ automation ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Wed, 09 Sep 2026 18:39:41 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/b2e654b3-dbd0-40af-a21b-c4b63cda4fcb.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Count the items on your deployment checklist. If there are more than a handful, the length is worth a second look.</p>
<p>Part of it is likely your team being careful. Part of it may be a record of how much infrastructure your product team is still checking by hand.</p>
<p>A deployment checklist grows based on application risk: how your own code, data, and rollout can hurt users. Every other item, like certificates, load balancers, image provenance, autoscaling, and connection draining, is a piece of plumbing you're verifying by hand because nothing else verifies it for you.</p>
<p>Those items don't need better wording. They need an owner, and it's worth asking whether that owner should be your product team. This assumes you're already running applications in production, with a pipeline, a rollback story of some kind, and an incident history worth reading.</p>
<p>The question isn't how to start deploying safely. It's which of the risks you currently carry actually need a human carrying them.</p>
<p>In this article, I argue that a deployment checklist should be as long as your application risk requires, and no longer. Most of the extra length is infrastructure work that a person is still checking by hand.</p>
<p>So we'll start by sorting the list into two columns: application risk and infrastructure risk. Then we'll treat each column differently.</p>
<p>Build the application half from your own incidents. Then add the checks that catch even strong teams: background workers, cached data, schema changes, and rollback triggers.</p>
<p>For the infrastructure half, each item still definitely matters. The question is just why a person is the one confirming it, and what it costs you to keep answering that by hand.</p>
<h3 id="heading-what-well-cover">What We'll Cover:</h3>
<ul>
<li><p><a href="#heading-two-kinds-of-risk-in-one-list">Two Kinds Of Risk In One List</a></p>
</li>
<li><p><a href="#heading-column-one-build-it-from-your-own-incidents">Column One: Build It From Your Own Incidents</a></p>
</li>
<li><p><a href="#heading-the-application-questions-worth-asking">The Application Questions Worth Asking</a></p>
</li>
<li><p><a href="#heading-three-application-risks-that-are-rarely-on-the-list">Three Application Risks That Are Rarely On The List</a></p>
</li>
<li><p><a href="#heading-database-migrations-are-where-rollbacks-go-to-die">Database Migrations Are Where Rollbacks Go To Die</a></p>
</li>
<li><p><a href="#heading-separate-deploying-from-releasing">Separate Deploying From Releasing</a></p>
</li>
<li><p><a href="#heading-decide-your-rollback-trigger-before-you-ship">Decide Your Rollback Trigger Before You Ship</a></p>
</li>
<li><p><a href="#heading-column-two-take-it-off-the-list">Column Two: Take It Off The List</a></p>
</li>
<li><p><a href="#heading-keep-it-short-keep-it-in-the-repo">Keep It Short, Keep It In The Repo</a></p>
</li>
</ul>
<h2 id="heading-two-kinds-of-risk-in-one-list">Two Kinds Of Risk In One List</h2>
<p>Open your current checklist and sort every item into two columns.</p>
<p>The first column is application risk. Can this schema change be undone? Will the old consumer understand the new job payload? What happens to sessions already in the cache?</p>
<p>These come out of decisions your team made in a pull request. Nobody outside the team can answer them, because nobody else knows what your code means.</p>
<p>The second column is infrastructure risk. Is the certificate valid? Did the image come from the right commit? Are autoscaling rules correct? Are logs shipping? Is the previous version still around?</p>
<p>These are recurring platform responsibilities, not application-specific judgment calls. Every production team faces them, which is why they should be enforced consistently instead of rechecked by hand.</p>
<p>Here is what that split looks like on a real list. Say your wiki page currently holds eleven items in one flat run. Sorted, it reads like this:</p>
<table>
<thead>
<tr>
<th>Application risk (changes every deploy)</th>
<th>Infrastructure risk (identical every deploy)</th>
</tr>
</thead>
<tbody><tr>
<td>Is the <code>full_name</code> migration reversible?</td>
<td>Is the TLS certificate valid for another 30 days?</td>
</tr>
<tr>
<td>Will the old invoice worker read the new job payload?</td>
<td>Did the image build from the commit we're deploying?</td>
</tr>
<tr>
<td>What happens to sessions already in Redis?</td>
<td>Are autoscaling rules right for this instance size?</td>
</tr>
<tr>
<td>Is <code>PAYMENT_TIMEOUT_MS</code> set in production?</td>
<td>Are logs and metrics shipping from the new instances?</td>
</tr>
<tr>
<td>Has rollback been tested on this service this week?</td>
<td>Is the previous release still there to roll back to?</td>
</tr>
<tr>
<td></td>
<td>Did old instances drain connections before shutdown?</td>
</tr>
</tbody></table>
<p>Read the two columns and the difference jumps out. The left column mentions your column names, your worker, your config keys. It would be meaningless at another company.</p>
<p>The right column would read the same at any company shipping a web app. That's the tell. Anything you could copy into a stranger's wiki without editing it isn't really your team's judgment call.</p>
<p>The first column is a checklist. The second is a list of things that should be answering themselves. Most teams write both into the same document, then wonder why it's too long to use.</p>
<h2 id="heading-column-one-build-it-from-your-own-incidents">Column One: Build It From Your Own Incidents</h2>
<p>Pull your last ten incidents. For each one, ask what single check, run before the deploy, would have caught it. A pattern should appear fast.</p>
<p>Most teams find that three or four causes explain the bulk of their outages: bad config, an unsafe schema change, a dependency that wasn't ready, or a rollback that didn't work.</p>
<p>Four items you use beat forty you ignore. Google's SRE team makes a related point in its chapter on <a href="https://sre.google/sre-book/release-engineering/">release engineering</a>, where the goal is releases that are boring and repeatable rather than careful and heroic.</p>
<p>A working <a href="https://sre.google/sre-book/postmortem-culture/">postmortem practice</a> keeps the list current, since every incident should add an item or delete one. One structural warning. Any item that depends on a human remembering will eventually fail, because people get tired and pipelines do not.</p>
<p>Each item should be automated, or explain why it can't be. The ones that can't be automated are usually judgement calls about your data model, which is exactly what belongs in column one.</p>
<h2 id="heading-the-application-questions-worth-asking">The Application Questions Worth Asking</h2>
<p>Add these to whatever your incidents produced. They cover the failure modes that hit nearly every team, and all of them are about your code rather than your plumbing.</p>
<ul>
<li><p><strong>Can I undo this in under two minutes?</strong> Not whether a rollback plan exists on paper. Whether it has been tested this week, on this service. An untested rollback is a hope, not a control.</p>
</li>
<li><p><strong>Is the config this code needs already in place?</strong> A new variable must be set before the code that reads it arrives, not after. The <a href="https://12factor.net/config">twelve-factor approach</a> keeps config in the environment rather than the code, which makes the ordering explicit.</p>
</li>
<li><p><strong>Is the database change safe on its own?</strong> That one gets its own section below.</p>
</li>
<li><p><strong>Does the app report its own health honestly?</strong> A running process isn't a working app, so the health endpoint has to check what the app actually depends on. Kubernetes formalises the distinction with <a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/">readiness and liveness probes</a>: readiness decides whether traffic reaches the instance, while liveness decides whether it gets restarted. Confusing the two turns a slow start into an endless restart loop. Writing an honest health check is application work. Checking by hand that the rollout waited for it is not.</p>
</li>
<li><p><strong>How many users see it first?</strong> Shipping to everyone at once turns every mistake into a full outage. Shipping to five percent turns most mistakes into a blip. None of these ask whether the code is correct. That's what review and tests are for. A deployment checklist asks a narrower question: can delivering correct code still hurt you?</p>
</li>
</ul>
<h2 id="heading-three-application-risks-that-are-rarely-on-the-list">Three Application Risks That Are Rarely On The List</h2>
<p>These catch experienced teams, because nothing in the pull request hints at them.</p>
<p><strong>Background workers are the first.</strong> Web processes and queue consumers ship from the same codebase but not always at the same moment. For a few minutes, a new producer may write payloads an old consumer can't read.</p>
<p>Here's the change that causes it. A developer tidies up a job payload:</p>
<pre><code class="language-python"># NEW producer code. Looks harmless in review.
enqueue("send_invoice", {
    "customer": {"id": 42, "email": "ada@example.com"},
})
</code></pre>
<p>The consumer still running in production is the old one, and it reads a key that no longer exists:</p>
<pre><code class="language-python"># OLD consumer, still live for the next few minutes
def send_invoice(payload):
    customer = db.get_customer(payload["customer_id"])  # KeyError
</code></pre>
<p>Those jobs fail quietly into a dead letter queue and get found hours later.</p>
<p>The fix is to send both shapes for one release, so either version of the consumer can read the message:</p>
<pre><code class="language-python"># Safe producer: old key stays until every consumer is new
enqueue("send_invoice", {
    "customer_id": 42,                                   # old consumers read this
    "customer": {"id": 42, "email": "ada@example.com"},  # new consumers read this
})
</code></pre>
<p>Then deploy the new consumer, let the queue drain, and drop <code>customer_id</code> in a later release. Same rule as a database column: add, migrate, and remove, never all at once.</p>
<p><strong>Serialised data is the second.</strong> Payloads need the same backward compatibility rule as database columns. Anything written into a cache, a session store, or a message body is effectively a schema.</p>
<p>The trap is that no migration file exists, so nothing warns you:</p>
<pre><code class="language-python"># Yesterday's code wrote this shape, and it's still sitting in Redis
cache.set(f"user:{user.id}", {"name": "Ada Lovelace"}, ex=86400)

# Today's code reads it
profile = cache.get(f"user:{user.id}")
first = profile["first_name"]   # KeyError on every object cached before the deploy
</code></pre>
<p>Change the shape of a cached object and old readers break, even though no database was touched. Use a new cache key instead:</p>
<pre><code class="language-python">CACHE_VERSION = "v2"   # bump this whenever the stored shape changes

def cache_key(user_id):
    return f"user:{CACHE_VERSION}:{user_id}"

cache.set(cache_key(user.id), {"first_name": "Ada", "last_name": "Lovelace"}, ex=86400)
</code></pre>
<p>New code misses on the new key, rebuilds from the database, and moves on. The old <code>user:*</code> entries expire on their own. One line of version bump replaces an outage.</p>
<p><strong>Cold-start capacity is the third,</strong> and it sits on the boundary. A rolling deploy briefly serves normal traffic with fewer warm instances.</p>
<p>If your app needs forty seconds to warm its connection pool and the grace period is thirty, you find out at the worst time. This config is the version that bites:</p>
<pre><code class="language-yaml">readinessProbe:
  httpGet: { path: /ready, port: 8080 }
  periodSeconds: 5
  failureThreshold: 6      # gives up after ~30s. The app needs 40.
</code></pre>
<p>The instance is killed and restarted right as it was about to be ready, so the rollout loops while traffic piles onto the old instances. Split the two jobs apart instead:</p>
<pre><code class="language-yaml"># Generous window for the first boot only
startupProbe:
  httpGet: { path: /ready, port: 8080 }
  periodSeconds: 5
  failureThreshold: 18     # allows 90s to warm the pool

# Tight window once the app is up
readinessProbe:
  httpGet: { path: /ready, port: 8080 }
  periodSeconds: 5
  failureThreshold: 3
</code></pre>
<p>Knowing the warm-up time is application work. Enforcing it on every deploy is a configuration you should set once, not a line you reread each time.</p>
<h2 id="heading-database-migrations-are-where-rollbacks-go-to-die">Database Migrations Are Where Rollbacks Go To Die</h2>
<p>You can roll back code in seconds, but you can't roll back a dropped column.</p>
<p>No tooling anywhere will make this someone else's problem, which is why it's the strictest item on the list.</p>
<p>Never ship a schema change and the code that depends on it in the same deploy. Split it. Add the new column and leave the old one alone, then deploy. Ship code that writes to both. Then ship code that reads the new one. Only much later, once nothing references it, should you drop the old column.</p>
<p>The pattern is called expand and contract. Renaming <code>users.name</code> to <code>users.full_name</code> looks like one line of work. Done safely, it's four deploys.</p>
<p>Deploy one adds the column and nothing else:</p>
<pre><code class="language-sql">-- Nullable, no default, so there is no table rewrite and no long lock
ALTER TABLE users ADD COLUMN full_name varchar(255);
</code></pre>
<p>Deploy two writes both columns and still reads the old one. Nothing user-facing changes yet:</p>
<pre><code class="language-python">def save_user(user, name):
    user.name = name          # still the source of truth
    user.full_name = name     # new column starts filling
</code></pre>
<p>Then backfill the rows that existed before deploy two (in batches so you never hold a lock for long):</p>
<pre><code class="language-sql">-- Repeat until it reports 0 rows
UPDATE users SET full_name = name
WHERE full_name IS NULL
LIMIT 5000;
</code></pre>
<p>Deploy three reads the new column, with a fallback so a rollback to deploy two is still safe:</p>
<pre><code class="language-python">display_name = user.full_name or user.name
</code></pre>
<p>Deploy four is the contract step, and it comes weeks later once nothing in the codebase mentions <code>name</code> and you're sure you won't roll back that far:</p>
<pre><code class="language-sql">ALTER TABLE users DROP COLUMN name;
</code></pre>
<p>It's more work. It also means that at every step, old code and new code can both still run, and that property is what makes fast rollback possible at all.</p>
<p><a href="https://martinfowler.com/bliki/BlueGreenDeployment.html">Blue-green deployment</a> keeps two full environments and switches traffic between them, which only works if your data layer serves both versions. Migration discipline is the foundation. The deploy strategy sits on top.</p>
<p>One more rule: never run a long migration inside the deploy. A change that locks a large table takes your app down while the pipeline reports success. Run it ahead of time and let the deploy be a fast swap of code.</p>
<h2 id="heading-separate-deploying-from-releasing">Separate Deploying From Releasing</h2>
<p>Deploying means the code is on the server, while releasing means users can reach the behaviour. Most teams treat these as one event, which is why every deploy feels risky.</p>
<p>Put new behaviour behind a flag and the two come apart. In the code, that's one branch and one place that decides:</p>
<pre><code class="language-python">def checkout(request, user):
    if flags.enabled("new_checkout", user=user):
        return new_checkout(request, user)
    return legacy_checkout(request, user)
</code></pre>
<p>Deploy with the flag off. The new path is on the server and reachable by nobody:</p>
<pre><code class="language-yaml"># flags.yaml — deploy 1: code is live, behaviour is not
new_checkout:
  enabled: false
</code></pre>
<p>Confirm the app is healthy, then turn it on for your own team:</p>
<pre><code class="language-yaml">new_checkout:
  enabled: true
  audience: internal      # your staff accounts only
</code></pre>
<p>Then one percent of real users, and watch your error rate and latency at that slice:</p>
<pre><code class="language-yaml">new_checkout:
  enabled: true
  audience: percentage
  percentage: 1
</code></pre>
<p>Then everyone, with the cleanup date written down at the same time:</p>
<pre><code class="language-yaml">new_checkout:
  enabled: true
  audience: percentage
  percentage: 100
  remove_by: 2026-11-01   # delete the flag and legacy_checkout by this date
</code></pre>
<p>If something looks wrong at any step, you set <code>enabled: false</code> instead of redeploying, and recovery takes seconds.</p>
<p>This also shortens the list. A change behind a default-off flag really is low risk, so it can skip most items, and the checks move to the flag flip where the risk lives.</p>
<p>Just keep in mind that flags cost something too, since old ones become dead code. So make sure you set a removal date when you add one. That <code>remove_by</code> field is the whole reason it's in the config rather than in someone's head.</p>
<h2 id="heading-decide-your-rollback-trigger-before-you-ship">Decide Your Rollback Trigger Before You Ship</h2>
<p>Rollbacks happen late mostly because nobody agreed in advance on what "bad" looks like. Under pressure, people negotiate and wait one more minute to see if the errors settle.</p>
<p>Write the trigger down before the deploy. Pick two or three numbers, each with a threshold and a window: for example</p>
<ol>
<li><p>an error rate above one percent for two minutes</p>
</li>
<li><p>latency at the ninety-fifth percentile above double its normal value</p>
</li>
<li><p>queue depth climbing without recovery</p>
</li>
</ol>
<p>Roll back when any one is crossed, with no discussion. Watch percentiles, not averages. If one request in twenty now takes eight seconds, the average barely moves while a real share of users suffer.</p>
<p>Then be honest about detection. How long would it take you to notice each signal today? If that's longer than your watch window, the problem isn't your checklist. It's your monitoring.</p>
<h2 id="heading-column-two-take-it-off-the-list">Column Two: Take It Off The List</h2>
<p>Now go back to the infrastructure column and ask a different question of each item. Not "is this worth checking". It is. Instead, ask "why is a person checking it?"</p>
<p>The obvious answer is to automate. Certificate renewal becomes automatic. Image provenance becomes a pipeline control that refuses to promote an unverified build. Config drift becomes a deployment-time check.</p>
<p>Each line you convert genuinely leaves the list, and a team that does this for a quarter will have a visibly shorter document.</p>
<p>Then look at what's left after the easy passes, because the remainder is where the argument actually is. You'll have items like health-gated rollout, where traffic shifts only after new instances pass their checks. Or zero-downtime replacement: draining connections, waiting for in-flight requests, sequencing instance turnover, and honouring readiness before moving traffic.</p>
<p>Keeping the previous release built and warm enough to return to in seconds. A preview environment per pull request, built the way production is built, so that "it worked in staging" stops being a category of incident.</p>
<p>These don't respond to a scripting afternoon. Each is a distributed systems problem with edge cases you discover in production, and each stays on the list as a human verification step until it's fully solved.</p>
<p>Teams that commit to solving these issues properly aren't writing scripts anymore. They're building and staffing an internal delivery platform, which is a real product with a roadmap, an on-call rotation, and a maintenance cost that doesn't end.</p>
<p>The work is legitimate. It's also the same work, done once per company, that a <a href="https://www.freecodecamp.org/news/my-team-s-experience-moving-from-aws-to-a-paas/">platform as a service</a> has already amortised across everyone using it, with the edge cases found by someone else's outages.</p>
<p>Rollback shows the gap most clearly. Owned in-house, it's a procedure a person performs under pressure, and the only thing that makes it trustworthy is rehearsing it often enough that the rehearsal itself becomes a standing cost.</p>
<p>Owned by the platform, the checklist item collapses to confirming that the previous release exists, which the platform also guarantees. The reliability difference isn't a matter of how well the runbook is written.</p>
<p>There's a real limit to this. Opinionated platforms constrain unusual networking, specialised hardware, and fine-grained tuning of the layers they abstract. So teams with those requirements will hit the edges and should stay where they are. It's worth checking whether that describes you, because most teams shipping web applications and APIs assume it does long before it's true.</p>
<h2 id="heading-keep-it-short-keep-it-in-the-repo">Keep It Short, Keep It In The Repo</h2>
<p>What survives is a list about your application, and it fits in a pull request template. Six tick boxes in front of the reviewer beat a wiki page every time.</p>
<p>A workable version reads like this:</p>
<ul>
<li><p>Confirm the change is backwards compatible with the running version, including job payloads and cached data.</p>
</li>
<li><p>Confirm any schema change ships in an earlier deploy.</p>
</li>
<li><p>Confirm new config already exists in the target environment.</p>
</li>
<li><p>Name the rollback trigger.</p>
</li>
<li><p>Say how the change reaches users.</p>
</li>
<li><p>Name who watches for the first fifteen minutes.</p>
</li>
</ul>
<p>That last item is underrated. A deploy nobody is watching is a bet, which is also why shipping at the end of the day hurts so often. The deploy is fine. The empty room is the problem.</p>
<p>Then measure whether the list works. The four <a href="https://dora.dev/guides/dora-metrics/">DORA metrics</a> give you the read you need. Change failure rate says whether your checks catch real problems. Recovery time says whether your rollback story is honest. And deployment frequency says whether the process has grown too heavy to use.</p>
<p>The teams that deploy most often break production least often, because speed and safety both come from a delivery path so automated that little is left for a human to get wrong.</p>
<p>So treat the checklist as a running record of risks a human is still absorbing on the system's behalf. Automate what automation can reach, and for the rest, be clear-eyed that keeping the item means keeping the infrastructure that produced it. A shrinking checklist is a maturing system. A list that stays long is a decision, not an accident.</p>
<p>Hope you enjoyed this article. You can <a href="https://linkedin.com/in/manishmshiva">connect with me on LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How AI Receptionists Work: The Architecture Behind AI Phone Agents ]]>
                </title>
                <description>
                    <![CDATA[ An AI receptionist may sound simple from the outside: a caller speaks, the system responds, and the conversation continues until the caller gets an answer or reaches a person. Behind that conversation ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-ai-receptionists-work-the-architecture-behind-ai-phone-agents/</link>
                <guid isPermaLink="false">6a9b251247b584b8b59d4b97</guid>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ai agents ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Fri, 04 Sep 2026 20:07:46 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/b902c73d-3593-4fe6-8f64-8180636cb58b.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>An AI receptionist may sound simple from the outside: a caller speaks, the system responds, and the conversation continues until the caller gets an answer or reaches a person.</p>
<p>Behind that conversation sits a pipeline of telephony infrastructure, speech recognition, language models, application logic, APIs, databases, and call routing.</p>
<p>The interesting part isn't just the AI model. It's how these components work together to turn an audio stream into useful business actions.</p>
<p>Businesses that want these capabilities have two paths.</p>
<p>They can buy a finished product. The market now includes dedicated AI receptionists such as <a href="https://www.nextiva.com/products/xbert">XBert from Nextiva</a>, along with tools from <a href="https://www.goodcall.com/">Goodcall</a>, <a href="https://dialzara.com/">Dialzara</a>, and others.</p>
<p>Or they can build one, which is what this article walks you through. Understanding the architecture helps either way: it shows what a commercial product is doing under the hood, and what a custom build needs to assemble.</p>
<p>A typical architecture looks something like this:</p>
<img src="https://cdn.hashnode.com/uploads/covers/66c6d8f04fa7fe6a6e337edd/cf8e4995-77b2-4d23-bcc6-639e1379d69b.png" alt="AI Receptionist architecture" style="display: block;" width="600" height="400" loading="lazy">

<p>In this article, we'll walk through the architecture behind an AI phone agent, from the moment a caller dials a business number to what happens after the call ends.</p>
<p>You'll see how telephony systems connect calls, how speech becomes text, how AI identifies intent and maintains conversation context, and how function calls connect the agent to calendars, CRMs, and other business systems. We'll also look at how agents decide when to hand a call to a human and what information can be passed along during that handoff.</p>
<h3 id="heading-what-well-cover">What We'll Cover:</h3>
<ul>
<li><p><a href="#heading-a-phone-call-enters-the-system">A Phone Call Enters the System</a></p>
</li>
<li><p><a href="#heading-speech-becomes-text">Speech Becomes Text</a></p>
</li>
<li><p><a href="#heading-the-system-determines-what-the-caller-wants">The System Determines What the Caller Wants</a></p>
</li>
<li><p><a href="#heading-the-conversation-runs-as-a-loop">The Conversation Runs as a Loop</a></p>
</li>
<li><p><a href="#heading-the-ai-calls-business-systems">The AI Calls Business Systems</a></p>
</li>
<li><p><a href="#heading-booking-an-appointment">Booking an Appointment</a></p>
</li>
<li><p><a href="#heading-capturing-lead-information">Capturing Lead Information</a></p>
</li>
<li><p><a href="#heading-knowing-when-to-involve-a-human">Knowing When to Involve a Human</a></p>
</li>
<li><p><a href="#heading-what-happens-after-the-call">What Happens After the Call</a></p>
</li>
<li><p><a href="#heading-what-the-business-sees">What the Business Sees</a></p>
</li>
</ul>
<h2 id="heading-a-phone-call-enters-the-system">A Phone Call Enters the System</h2>
<p>The process starts like a regular phone call. A customer dials a business number, and the telecommunications provider receives the call.</p>
<p>The provider then needs to connect that call to an application capable of handling it.</p>
<p>One common approach is a webhook. The telephony provider sends an HTTP request to an application when an incoming call arrives. The application can then return instructions describing how the call should be handled.</p>
<p>The call itself needs carrier connectivity. Production systems typically use SIP trunking, which connects a voice application or phone system to the public telephone network over the internet.</p>
<p>Providers such as Nextiva, Twilio, and Bandwidth offer SIP trunking that supplies the numbers and call capacity an AI voice system runs on. From there, the application layer takes over.</p>
<p>For example, <a href="https://www.twilio.com/docs/voice/twiml">Twilio</a> sends an HTTP request to a configured application when an incoming voice call arrives. The application can respond with TwiML instructions that control the call.</p>
<p>A simplified Node.js endpoint might look like this:</p>
<pre><code class="language-js">app.post("/incoming-call", (req, res) =&gt; {
  const response = new VoiceResponse();

  response.say("Hello. How can I help you today?");

  res.type("text/xml");
  res.send(response.toString());
});
</code></pre>
<p>This example doesn't contain any AI yet. It simply shows the first architectural boundary.</p>
<p>The phone network handles the call. The application receives an event and decides what happens next.</p>
<p>From here, the application needs to process the caller's audio.</p>
<h2 id="heading-speech-becomes-text">Speech Becomes Text</h2>
<p>People communicate with the system through audio, but most application logic works with structured data and text.</p>
<p>An <a href="https://huggingface.co/tasks/automatic-speech-recognition">automatic speech recognition system</a>, or ASR system, converts the caller's speech into text.</p>
<p>For example, a caller might say:</p>
<blockquote>
<p>"I need to move my appointment from Friday to Monday afternoon."</p>
</blockquote>
<p>The speech recognition layer might produce:</p>
<pre><code class="language-json">{
  "text": "I need to move my appointment from Friday to Monday afternoon."
}
</code></pre>
<p>The exact response depends on the speech recognition system. Some systems can also provide timestamps, confidence information, speaker information, or partial transcripts.</p>
<p>The application can now pass the recognized text to its conversational layer.</p>
<p>This separation is useful because the AI reasoning layer doesn't need to understand raw telephone audio. It receives text and returns a decision or response.</p>
<h2 id="heading-the-system-determines-what-the-caller-wants">The System Determines What the Caller Wants</h2>
<p>The next challenge is understanding intent.</p>
<p>Suppose three callers say:</p>
<blockquote>
<p>"I want to book a consultation."</p>
</blockquote>
<blockquote>
<p>"Can I move my appointment to next week?"</p>
</blockquote>
<blockquote>
<p>"Where is your office?"</p>
</blockquote>
<p>The system needs to recognize that these requests require different workflows.</p>
<p>An application could represent the detected intent as structured data:</p>
<pre><code class="language-json">{
  "intent": "reschedule_appointment",
  "entities": {
    "current_day": "Friday",
    "requested_day": "Monday",
    "time_preference": "afternoon"
  }
}
</code></pre>
<p>The language model can produce this structure, or the application can derive it through another classification layer.</p>
<p>The important architectural point is that the application turns natural language into information that downstream systems can process.</p>
<p>The model might understand that the caller wants to reschedule an appointment, but it shouldn't directly modify a calendar simply because it generated that interpretation.</p>
<p>The application needs to control what happens next.</p>
<h2 id="heading-the-conversation-runs-as-a-loop">The Conversation Runs as a Loop</h2>
<p>An AI phone agent doesn't normally process an entire conversation in a single request.</p>
<p>Instead, it operates as a loop.</p>
<p>The caller speaks. Speech recognition converts the audio into text. The application sends the text and relevant context to the AI system. The AI determines what it needs to say or what action it needs to perform. The application generates audio and sends it back to the caller.</p>
<p>Then the caller speaks again.</p>
<p>A simplified version looks like this:</p>
<pre><code class="language-js">while (callIsActive) {
  const audio = await receiveAudio();

  const text = await speechToText(audio);

  const result = await processConversation({
    text,
    context: conversationContext
  });

  conversationContext = result.updatedContext;

  const audioResponse = await textToSpeech(result.response);

  await sendAudio(audioResponse);
}
</code></pre>
<p>This is conceptual code, not a complete phone implementation. Real systems need to handle streaming audio, interruptions, timeouts, errors, authentication, and provider-specific protocols.</p>
<p>Context is also important.</p>
<p>If the caller says:</p>
<blockquote>
<p>"I want to book an appointment."</p>
</blockquote>
<p>The system might ask:</p>
<blockquote>
<p>"What type of appointment do you need?"</p>
</blockquote>
<p>The caller then says:</p>
<blockquote>
<p>"An initial consultation."</p>
</blockquote>
<p>That second statement only makes sense because the application remembers the previous exchange.</p>
<p>Conversation state might contain information such as:</p>
<pre><code class="language-json">{
  "intent": "book_appointment",
  "appointment_type": "initial_consultation",
  "customer_name": "Jane Smith",
  "preferred_date": null
}
</code></pre>
<p>The system can add to this state as the conversation progresses.</p>
<h2 id="heading-the-ai-calls-business-systems">The AI Calls Business Systems</h2>
<p>This is where an AI receptionist becomes more than a voice chatbot.</p>
<p>Suppose a caller asks:</p>
<blockquote>
<p>"Do you have anything available tomorrow afternoon?"</p>
</blockquote>
<p>The AI can't reliably answer that from the conversation alone. It needs current information from a calendar or scheduling system.</p>
<p>This is where function calling, also called tool calling, becomes useful.</p>
<p>The application can expose a limited set of functions to the AI:</p>
<pre><code class="language-js">const tools = [
  {
    name: "check_calendar",
    description: "Find available appointment slots",
    parameters: {
      date: "string",
      appointmentType: "string"
    }
  },
  {
    name: "book_appointment",
    description: "Book an available appointment",
    parameters: {
      slotId: "string",
      customerId: "string"
    }
  }
];
</code></pre>
<p>The model can determine that it needs <code>check_calendar</code>.</p>
<p>The application then executes the function:</p>
<pre><code class="language-js">const slots = await checkCalendar({
  date: "2026-08-21",
  appointmentType: "consultation"
});
</code></pre>
<p>The result goes back into the conversation context:</p>
<pre><code class="language-json">{
  "available_slots": [
    "2026-08-21T14:00:00",
    "2026-08-21T15:30:00"
  ]
}
</code></pre>
<p>The AI can then tell the caller which options are available.</p>
<p>The important architectural boundary is that the AI decides what action may be needed, while application code controls how that action is performed.</p>
<p>That gives developers a place to enforce permissions, validate inputs, handle failures, and control access to business systems.</p>
<h2 id="heading-booking-an-appointment">Booking an Appointment</h2>
<p>Now consider the final step.</p>
<p>The caller selects one of the available times.</p>
<p>The AI can request an appointment booking:</p>
<pre><code class="language-json">{
  "tool": "book_appointment",
  "arguments": {
    "slotId": "slot_123",
    "customerId": "customer_456"
  }
}
</code></pre>
<p>The application validates those values before calling the calendar system.</p>
<p>For example:</p>
<pre><code class="language-js">async function bookAppointment(slotId, customerId) {
  const slot = await getAvailableSlot(slotId);

  if (!slot || slot.booked) {
    throw new Error("Appointment slot is no longer available");
  }

  return calendar.createEvent({
    customerId,
    start: slot.start,
    end: slot.end
  });
}
</code></pre>
<p>The application then returns the actual result to the AI.</p>
<p>This distinction matters.</p>
<p>The AI shouldn't tell the caller that an appointment has been booked merely because it decided to call <code>book_appointment</code>.</p>
<p>The calendar system needs to confirm that the operation succeeded.</p>
<p>Calendar APIs commonly expose operations for creating events. For example, <a href="https://developers.google.com/workspace/calendar/api/v3/reference/events/insert">Google Calendar</a> provides an <code>events.insert</code> method for creating an event.</p>
<p>Only after receiving a successful response should the conversational layer tell the caller that the appointment is confirmed.</p>
<h2 id="heading-capturing-lead-information">Capturing Lead Information</h2>
<p>The same architecture can capture information during a sales conversation.</p>
<p>A caller might provide a name, email address, company, phone number, service requirement, and preferred follow-up time.</p>
<p>The conversation can gradually populate a structured lead object:</p>
<pre><code class="language-json">{
  "name": "Jane Smith",
  "email": "jane@example.com",
  "company": "Example Corp",
  "interest": "enterprise consultation",
  "appointment_booked": true
}
</code></pre>
<p>The application can then send this information to a CRM.</p>
<p>This creates an important distinction between conversation data and business data.</p>
<p>The transcript represents what the caller said.</p>
<p>The CRM record represents the structured information that the business needs to act on.</p>
<p>A CRM might contain the caller's contact information, inquiry type, qualification data, appointment details, and follow-up status.</p>
<p>The exact fields depend on the company's CRM and sales process.</p>
<h2 id="heading-knowing-when-to-involve-a-human">Knowing When to Involve a Human</h2>
<p>Not every conversation should remain with an AI system.</p>
<p>A production system needs escalation rules.</p>
<p>An escalation might happen when the caller asks for a person, when the request falls outside the agent's supported workflows, or when the business has decided that a particular type of request requires human involvement.</p>
<p>The application can represent this decision explicitly:</p>
<pre><code class="language-js">if (shouldEscalate(conversation)) {
  return transferToHuman({
    callerId,
    reason,
    conversationContext
  });
}
</code></pre>
<p>The important part is what happens during the transfer.</p>
<p>A useful handoff should carry context rather than forcing the employee to start from zero.</p>
<p>The human agent might receive:</p>
<pre><code class="language-json">{
  "caller": {
    "name": "Jane Smith",
    "phone": "+1-555-0100"
  },
  "reason": "Complex billing question",
  "summary": "Caller needs help resolving an invoice discrepancy.",
  "actionsCompleted": [
    "Customer identity verified"
  ]
}
</code></pre>
<p>The exact handoff data depends on the system.</p>
<p>Telephony platforms can also support call transfers and callbacks through their voice APIs. For example, Twilio's voice documentation describes call routing and <code>&lt;Dial&gt;</code> functionality for connecting calls to another destination.</p>
<h2 id="heading-what-happens-after-the-call">What Happens After the Call</h2>
<p>The conversation doesn't necessarily end when the caller hangs up.</p>
<p>Depending on the system and its configuration, the application can retain the transcript and other call data.</p>
<p>A simplified call record might look like this:</p>
<pre><code class="language-json">{
  "callId": "call_123",
  "duration": 342,
  "customerId": "customer_456",
  "intent": "book_appointment",
  "appointmentId": "appointment_789",
  "leadCaptured": true,
  "escalated": false
}
</code></pre>
<p>The transcript can provide the detailed conversation, while structured fields provide information that downstream applications can query.</p>
<p>A call can therefore trigger several business actions.</p>
<ul>
<li><p>A sales call can create a lead.</p>
</li>
<li><p>An appointment call can update a calendar.</p>
</li>
<li><p>A support call can create a ticket.</p>
</li>
<li><p>A complex conversation can result in a human handoff.</p>
</li>
</ul>
<p>Telephony systems can also notify applications about call lifecycle events through status callbacks. Twilio, for example, sends a request to a number's StatusCallback URL when a call ends, and supports a <code>statusCallbackEvent</code> attribute for subscribing to lifecycle events such as initiated, ringing, answered, and completed on dialed legs.</p>
<h2 id="heading-what-the-business-sees">What the Business Sees</h2>
<p>From the employee's perspective, all of this infrastructure can be hidden behind a few business records.</p>
<p>An employee might see a new CRM lead with contact information and the reason for the call.</p>
<p>The calendar might contain a newly booked appointment.</p>
<p>The conversation system might contain the transcript and a summary.</p>
<p>If the call was transferred, the employee can receive the relevant context before speaking with the customer.</p>
<p>That's the main architectural idea behind AI phone agents.</p>
<p>The voice interface is only one layer. Underneath it is a collection of systems that convert speech into text, interpret the caller's request, maintain conversation state, call external services, validate business actions, and return results to the caller.</p>
<p>The language model provides the conversational reasoning. The surrounding application provides the state, tools, permissions, integrations, and business rules that turn that conversation into an actual workflow.</p>
<p>Hope you enjoyed this article. You can <a href="https://linkedin.com/in/manishmshiva">connect with me on LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Protect Your Privacy While Browsing the Web ]]>
                </title>
                <description>
                    <![CDATA[ Every time you open a web page, you leave a trail. Your browser shares your IP address, your screen size, your fonts, and dozens of other small details. Ad companies collect these details and stitch t ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-protect-your-privacy-while-browsing-the-web/</link>
                <guid isPermaLink="false">6a96f3e0541d63c1fd799f01</guid>
                
                    <category>
                        <![CDATA[ privacy ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Browsers ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Tue, 01 Sep 2026 15:48:48 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/7e2faa59-b805-4df1-be97-86c74604f35f.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Every time you open a web page, you leave a trail. Your browser shares your IP address, your screen size, your fonts, and dozens of other small details. Ad companies collect these details and stitch them together. The result is a profile of who you are, what you buy, and where you go.</p>
<p>The good news is that you don't need to be a security expert to fix this. Most of the work takes an afternoon. After that, privacy becomes a habit rather than a project. This guide walks through the steps in the order that gives you the biggest gain for the least effort.</p>
<p>In this article, you'll learn how to improve your online privacy without making browsing complicated. We'll cover the most important steps, from choosing a privacy-friendly browser and blocking trackers to using a VPN, securing your search history and DNS, and cleaning up your online accounts.</p>
<p>You'll also learn what these tools can and can't protect, so you can build a practical privacy setup that works for everyday browsing.</p>
<h3 id="heading-what-well-cover">What We'll Cover:</h3>
<ul>
<li><p><a href="#heading-start-with-your-browser">Start With Your Browser</a></p>
</li>
<li><p><a href="#heading-block-trackers-and-ads">Block Trackers and Ads</a></p>
</li>
<li><p><a href="#heading-hide-your-ip-address-with-a-vpn">Hide Your IP Address With a VPN</a></p>
</li>
<li><p><a href="#heading-fix-your-search-and-dns">Fix Your Search and DNS</a></p>
</li>
<li><p><a href="#heading-clean-up-your-accounts">Clean Up Your Accounts</a></p>
</li>
<li><p><a href="#heading-know-what-each-step-cannot-do">Know What Each Step Cannot Do</a></p>
</li>
<li><p><a href="#heading-a-simple-plan">A Simple Plan</a></p>
</li>
</ul>
<h2 id="heading-start-with-your-browser">Start With Your Browser</h2>
<p>Your browser is the front door. If it leaks, nothing else matters much.</p>
<p>Chrome is fast, but it belongs to an advertising company. Firefox and Brave block trackers by default and are built with privacy in mind. Safari also does a decent job on Apple devices.</p>
<p>If you want to switch, <a href="https://www.mozilla.org/firefox/">Firefox</a> is the easiest move. It imports your bookmarks and saved passwords in a couple of clicks.</p>
<p>If you stay with Chrome, change a few settings. Turn off third-party cookies. Turn off the ad topics feature, which lets Chrome guess your interests and share them with sites.</p>
<img src="https://cdn.hashnode.com/uploads/covers/66c6d8f04fa7fe6a6e337edd/6ff49487-14cc-4e74-9504-0e47c627c30e.png" alt="Chrome Privacy Settings" style="display: block;" width="3010" height="1606" loading="lazy">

<p>Set your browser to clear cookies when you close it. You'll sign in to sites more often, but trackers will lose their memory of you every day.</p>
<p>Also check what your browser is telling the world right now. The Electronic Frontier Foundation runs a free test called <a href="https://coveryourtracks.eff.org/">Cover Your Tracks</a>. It shows you how unique your browser looks to a tracking company.</p>
<img src="https://cdn.hashnode.com/uploads/covers/66c6d8f04fa7fe6a6e337edd/95ffa5d4-2e8e-4914-add6-5b64f7d853ba.png" alt="Cover Your Tracks" style="display: block;" width="3254" height="1830" loading="lazy">

<p>Run it before you make changes, then run it again after. The difference is a good reality check.</p>
<h2 id="heading-block-trackers-and-ads">Block Trackers and Ads</h2>
<p>Most tracking happens through scripts loaded from other companies. A page may look like one site, but it can quietly load code from ten different firms.</p>
<p>A content blocker stops those scripts before they run. <a href="https://ublockorigin.com/">uBlock Origin</a> is the best-known free option and works in Firefox. It blocks ads too, which makes pages load faster and use less data. Privacy Badger, also from the EFF, takes a different approach. It watches which companies follow you across sites and blocks the ones that do.</p>
<p>Don't install multiple blockers at once. Two is plenty. More than that causes broken pages and slow browsing, and the extra protection is small.</p>
<p>Be careful about which extensions you trust. An extension can read everything on every page you visit. Stick to well-known tools with a clear privacy policy and a long track record. If an extension is free, tiny, and asks for wide permissions, skip it.</p>
<h2 id="heading-hide-your-ip-address-with-a-vpn">Hide Your IP Address With a VPN</h2>
<p>Blocking trackers helps, but your internet provider still sees every site you visit. In many countries, providers are allowed to sell that data. Public Wi-Fi at a hotel or airport is worse, because other people on the network may be watching, too.</p>
<p>A virtual private network fixes this. It wraps your traffic in an encrypted tunnel and sends it through a server run by the VPN company. Your provider sees only that you connected to the VPN. Websites see the VPN server's address instead of yours.</p>
<p>If you want protection only inside your browser, a browser extension is the simplest route. The <a href="https://www.cyberghostvpn.com/download/chrome-vpn">CyberGhost Chrome add-on</a> is one example. It routes your Chrome traffic through an encrypted proxy, lets you pick a country, and blocks some trackers along the way. Anything outside Chrome, like a mail client or a game, still uses your normal connection. That's fine for casual privacy and it keeps your other apps fast.</p>
<p>One warning about free VPNs: running servers costs money. If a VPN is free and shows no clear business model, your data may be the product. Pick a paid service with a published no-logs audit, or use a free plan from a company you already trust.</p>
<h2 id="heading-fix-your-search-and-dns">Fix Your Search and DNS</h2>
<p>Your search history is the most personal thing you own. It holds your health worries, your money problems, and your plans.</p>
<p>Google keeps that history tied to your account unless you tell it not to. Visit <a href="https://myactivity.google.com/">My Activity</a> and set auto-delete to three months. While you're there, look at what has been saved. Most people find the amount surprising.</p>
<p>You can also switch your default search engine. DuckDuckGo and Startpage don't build a profile from your searches. Results are good enough for daily use, and you can still fall back to Google when you need it.</p>
<p>Then there's DNS, the system that turns a web address into a number your computer can reach. By default your provider handles this, so it sees every domain you visit even when the traffic itself is encrypted. Switching to an encrypted DNS service such as <a href="https://1.1.1.1/">Cloudflare's 1.1.1.1</a> takes about two minutes and closes that gap. Most browsers now have a setting for secure DNS, so you may not even need to touch your system settings.</p>
<h2 id="heading-clean-up-your-accounts">Clean Up Your Accounts</h2>
<p>Privacy isn't only about traffic. It's also about the data already sitting on other people's servers.</p>
<p>Start by finding out where your details have leaked. The free site <a href="https://haveibeenpwned.com/">Have I Been Pwned</a> tells you which breaches include your email address. If your address shows up in an old breach, change that password right away, and change it anywhere else you reused it.</p>
<p>Reused passwords are the single biggest risk most people carry. A password manager solves it. It creates a long random password for every site and remembers them all for you. Turn on two-factor authentication for your email, your bank, and any account tied to money. Email matters most, because whoever controls your email can reset everything else.</p>
<p>Finally, use different email addresses for different parts of your life. Many providers let you create aliases. One address for banking, one for shopping, and one for newsletters. When an alias starts getting spam, you know exactly who sold your data, and you can shut it off without changing your real address.</p>
<h2 id="heading-know-what-each-step-cant-do">Know What Each Step Can't Do</h2>
<p>It helps to be clear about limits, so you don't feel safer than you are.</p>
<p>A VPN hides your traffic from your provider, but it doesn't hide you from a site you log in to. If you sign in to a social network, that network knows it's you no matter which country your traffic seems to come from.</p>
<p>Blocking trackers reduces profiling, but browser fingerprinting can still identify you through your unique mix of settings. Only tools like the <a href="https://www.torproject.org/">Tor Browser</a>, which makes everyone look the same, defeat that fully. Tor is slower, so most people save it for the moments that really matter.</p>
<p>And nothing protects information you hand over yourself. If you post your holiday plans in public, no setting will pull them back.</p>
<h2 id="heading-a-simple-plan">A Simple Plan</h2>
<p>If you only do three things, do these. Install a good content blocker, turn on a password manager and two-factor authentication, and use a VPN whenever you're on a network you don't control.</p>
<p>Then set a reminder for six months from now. Check your breach report, review the extensions you've installed, and delete the accounts you no longer use. Privacy isn't a wall you build once. It's closer to housekeeping. A little attention now and then keeps the mess from piling up, and it costs far less than cleaning up after your data has already escaped.</p>
<p>Hope you enjoyed this article. You can <a href="https://linkedin.com/in/manishmshiva">connect with me on LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Hidden Risks Lurking in Your Cloud Infrastructure ]]>
                </title>
                <description>
                    <![CDATA[ Cloud computing has changed how organisations build, deploy, and scale applications. Businesses can launch new services in minutes, expand into new markets, and reduce the cost of maintaining physical ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-hidden-risks-lurking-in-your-cloud-infrastructure/</link>
                <guid isPermaLink="false">6a872fd36fe3503416ed20d8</guid>
                
                    <category>
                        <![CDATA[ Cloud Computing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Cloud infrastructure ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Thu, 20 Aug 2026 16:48:19 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/50037557-d27e-4f8c-bbb0-b9bc78582a5b.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Cloud computing has changed how organisations build, deploy, and scale applications. Businesses can launch new services in minutes, expand into new markets, and reduce the cost of maintaining physical infrastructure.</p>
<p>While these advantages have fueled rapid cloud adoption, they've also introduced new security challenges that many organisations fail to recognise until it's too late.</p>
<p>Unlike traditional data centers, cloud environments are dynamic. New virtual machines, databases, storage accounts, containers, and serverless functions can appear and disappear throughout the day.</p>
<p>As cloud infrastructure grows, so does the number of potential security gaps. Many of these vulnerabilities remain hidden because they stem from configuration errors rather than software flaws.</p>
<p>This is where cloud security posture management becomes essential. Instead of relying on periodic security reviews, organisations can continuously monitor their cloud environments, identify risks, and remediate issues before they become security incidents.</p>
<p>For each of the five risks below, I'll walk through one concrete example of how the problem actually shows up in a real environment, and the specific steps a team would take to fix it. The examples are deliberately provider-neutral, because the same patterns appear across every major cloud platform under different names.</p>
<p>Understanding these hidden risks is the first step toward building a stronger and more resilient cloud environment.</p>
<h2 id="heading-what-well-cover">What We'll Cover</h2>
<ul>
<li><p><a href="#heading-why-cloud-infrastructure-creates-new-security-challenges">Why Cloud Infrastructure Creates New Security Challenges</a></p>
</li>
<li><p><a href="#heading-hidden-risk-1-cloud-misconfigurations">Hidden Risk #1: Cloud Misconfigurations</a></p>
<ul>
<li><p><a href="#heading-what-this-looks-like-in-practice">What this looks like in practice</a></p>
</li>
<li><p><a href="#heading-how-to-mitigate-it">How to mitigate it</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-hidden-risk-2-excessive-permissions">Hidden Risk #2: Excessive Permissions</a></p>
<ul>
<li><p><a href="#heading-what-this-looks-like-in-practice">What this looks like in practice</a></p>
</li>
<li><p><a href="#heading-how-to-mitigate-it">How to mitigate it</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-hidden-risk-3-forgotten-cloud-resources">Hidden Risk #3: Forgotten Cloud Resources</a></p>
<ul>
<li><p><a href="#heading-what-this-looks-like-in-practice">What this looks like in practice</a></p>
</li>
<li><p><a href="#heading-how-to-mitigate-it">How to mitigate it</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-hidden-risk-4-compliance-drift">Hidden Risk #4: Compliance Drift</a></p>
<ul>
<li><p><a href="#heading-what-this-looks-like-in-practice">What this looks like in practice</a></p>
</li>
<li><p><a href="#heading-how-to-mitigate-it">How to mitigate it</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-hidden-risk-5-limited-visibility-across-multi-cloud-environments">Hidden Risk #5: Limited Visibility Across Multi-Cloud Environments</a></p>
<ul>
<li><p><a href="#heading-what-this-looks-like-in-practice">What this looks like in practice</a></p>
</li>
<li><p><a href="#heading-how-to-mitigate-it">How to mitigate it</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-why-manual-security-reviews-are-no-longer-enough">Why Manual Security Reviews Are No Longer Enough</a></p>
</li>
<li><p><a href="#heading-how-cloud-security-posture-management-strengthens-cloud-security">How Cloud Security Posture Management Strengthens Cloud Security</a></p>
</li>
<li><p><a href="#heading-building-a-stronger-cloud-security-strategy">Building a Stronger Cloud Security Strategy</a></p>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-why-cloud-infrastructure-creates-new-security-challenges">Why Cloud Infrastructure Creates New Security Challenges</h2>
<p>Modern cloud environments are far more complex than the on-premises infrastructure many security teams were built to protect. A single organisation may use Amazon Web Services (AWS), Microsoft Azure, and Google Cloud Platform (GCP) simultaneously. Each provider offers hundreds of services, each with its own security settings and access controls.</p>
<p>Development teams also create new cloud resources at an unprecedented pace. <a href="https://aws.amazon.com/what-is/iac/">Infrastructure as Code</a>, automated deployment pipelines, and container orchestration platforms enable provisioning entire environments in minutes. While this improves productivity, it also increases the likelihood of configuration errors.</p>
<p>The shared responsibility model adds another layer of complexity. Cloud providers secure the underlying infrastructure, but customers remain responsible for securing their applications, identities, storage, networks, and data. Many organisations mistakenly assume their cloud provider handles every aspect of security, leaving critical resources exposed.</p>
<h2 id="heading-hidden-risk-1-cloud-misconfigurations">Hidden Risk #1: Cloud Misconfigurations</h2>
<p>Misconfigurations remain one of the leading causes of cloud security incidents. A single incorrect setting can expose sensitive information to the public internet or give attackers access to critical systems.</p>
<p>Examples include publicly accessible storage buckets, databases that allow unrestricted network access, disabled encryption settings, and security groups with overly permissive firewall rules. These mistakes often occur during rapid deployments when security reviews are skipped or delayed.</p>
<p>The challenge is that cloud environments change constantly. Even if an environment is secure today, a new deployment tomorrow may introduce a vulnerability without anyone noticing.</p>
<h3 id="heading-what-this-looks-like-in-practice">What This Looks Like in Practice</h3>
<p>A product team needs to share a set of report images with an external design agency. The quickest path is to create an object storage bucket and set its access policy to allow read access from any identity, rather than setting up temporary signed URLs or a guest account. The share works, the agency delivers, and the ticket is closed.</p>
<p>Six weeks later, the same bucket is reused as the destination for a nightly export job. Nobody rechecks the access policy, because the bucket already exists and "works." The export contains customer names, email addresses, and internal order IDs, and it's now readable by anyone who can guess or enumerate the bucket name. Automated scanners that crawl for open buckets will typically find it within days.</p>
<p>Nothing was hacked here. No credential was stolen and no software was exploited. A setting that was reasonable for one purpose was silently inherited by another.</p>
<h3 id="heading-how-to-mitigate-it">How to Mitigate it</h3>
<ol>
<li><p><strong>Turn on the account-level public access block:</strong> Every major provider offers an org- or account-wide setting that overrides individual resource policies and prevents public exposure of storage. Enable it as the default, and treat any exception as a change that requires approval.</p>
</li>
<li><p><strong>Scan the infrastructure code before it's applied, not after:</strong> Add a policy-as-code check to your deployment pipeline so a template that grants public read on a bucket fails the build. This is where you catch the problem for free, before it exists in the environment.</p>
</li>
<li><p><strong>Replace public access with time-limited access:</strong> For genuine external sharing, use pre-signed URLs with an expiry measured in hours, or a scoped guest identity. This gives the same convenience without leaving a permanent hole.</p>
</li>
<li><p><strong>Alert on the change, not just the state:</strong> Configure your posture management tool to fire when a bucket's access policy changes to allow anonymous principals, and route it to the team that owns the resource. Detecting the drift within minutes is what separates a near miss from a breach notification.</p>
</li>
</ol>
<p>Cloud security posture management continuously scans cloud resources for configuration issues and alerts security teams when risks appear. Instead of waiting for a scheduled audit, organisations gain visibility into problems as they occur.</p>
<h2 id="heading-hidden-risk-2-excessive-permissions">Hidden Risk #2: Excessive Permissions</h2>
<p><a href="https://www.ibm.com/solutions/identity-access-management">Identity and Access Management (IAM)</a> is one of the most important parts of cloud security. Unfortunately, it's also one of the most common sources of risk.</p>
<p>Many organisations grant users, applications, or service accounts more permissions than they actually need. Over time, these excessive privileges accumulate as employees change roles, applications evolve, and temporary permissions become permanent.</p>
<p>If an attacker compromises an account with broad privileges, the damage can spread quickly across the cloud environment. Sensitive data, production systems, and administrative resources may all become accessible.</p>
<h3 id="heading-what-this-looks-like-in-practice">What This Looks Like in Practice</h3>
<p>A team sets up a deployment pipeline. The pipeline needs to create compute instances, update a container registry, and write to a couple of storage locations. Working out the exact permission set takes time, and the first three attempts fail with cryptic access-denied errors. Under deadline pressure, someone attaches the built-in administrator role to the pipeline's service identity "just to unblock it," with the intention of narrowing it later.</p>
<p>Later never comes. The pipeline now holds full administrative rights across the account, and its credentials live in a CI/CD system that dozens of engineers can configure. Anyone who can modify a build file, or who compromises a single developer's account on that CI system, can execute arbitrary commands with administrator privileges like read every database, create new identities, or disable logging.</p>
<p>The same pattern appears with people. An engineer moves from platform to frontend work, keeps the old production access "in case something breaks," and two years later has accumulated permissions spanning four teams they no longer belong to.</p>
<h3 id="heading-how-to-mitigate-it">How to Mitigate it</h3>
<ol>
<li><p><strong>Pull the last-accessed data before you touch anything:</strong> Every major provider records which services an identity has actually used and when. Start by listing every role with administrative privileges and check what it has genuinely called in the past 90 days. In most environments the real usage is a small fraction of what's granted.</p>
</li>
<li><p><strong>Generate a scoped policy from observed activity:</strong> Use the provider's policy-generation tooling (or your posture management platform) to produce a candidate policy based on that access history, then review it manually before applying. Applying the <a href="https://www.freecodecamp.org/news/principle-of-lease-privilege-meaning-cybersecurity/">principle of least privilege</a> is far easier when you start from evidence rather than guesswork.</p>
</li>
<li><p><strong>Roll it out in audit mode first:</strong> Apply the narrowed policy to a non-production copy of the pipeline, or run it alongside the permissive one with denial logging enabled, so you find the missing permissions without breaking deployments.</p>
</li>
<li><p><strong>Set an expiry on elevated access:</strong> Temporary administrative rights should be granted through a just-in-time mechanism that expires automatically, so the "narrow it later" step happens whether or not anyone remembers.</p>
</li>
<li><p><strong>Watch for privilege escalation paths, not just broad roles:</strong> A role that can't do much directly but can create identities, attach policies, or pass a privileged role to a new resource is effectively an administrator. Posture management tools flag these chains, which are almost impossible to spot by reading policies one at a time.</p>
</li>
</ol>
<h2 id="heading-hidden-risk-3-forgotten-cloud-resources">Hidden Risk #3: Forgotten Cloud Resources</h2>
<p>Cloud environments are rarely static. Development teams frequently create temporary virtual machines, test databases, storage accounts, and networking components while building new features. Once projects are completed, these resources are often forgotten rather than removed.</p>
<p>Although these abandoned resources may no longer serve a business purpose, they continue to consume cloud resources and may still contain sensitive information. Some may even remain connected to production networks.</p>
<p>These overlooked assets create unnecessary attack surfaces. Attackers often look for neglected systems because they're less likely to receive security updates or active monitoring.</p>
<h3 id="heading-what-this-looks-like-in-practice">What This Looks Like in Practice</h3>
<p>Ahead of a major release, a team spins up a load-testing environment: a handful of compute instances, a database restored from a production snapshot so the test data is realistic, and a permissive network rule opening administrative access from any address, because the testers are working from home and nobody wants to maintain an IP allowlist for a two-week project.</p>
<p>The release ships. The environment stays. A year on, those instances are running an operating system image that has missed four rounds of patches, the database still contains a year-old copy of real customer records, and the administrative port is still open to the internet. It doesn't appear on any architecture diagram, it isn't in the patching rota, and no alerting is configured against it, because it was never meant to exist for more than a fortnight.</p>
<p>This is one of the most attractive targets in a cloud estate: real data, no monitoring, and a known-vulnerable software version.</p>
<h3 id="heading-how-to-mitigate-it">How to Mitigate it</h3>
<ol>
<li><p><strong>Build an inventory that doesn't depend on memory:</strong> Query every region in every account for running compute, databases, storage, and snapshots, including the regions you believe you don't use, which is where forgotten resources most often hide. Deploying <a href="https://orca.security/resources/blog/open-source-application-security-tools/">application security tools</a> across both active and forgotten resources helps ensure vulnerabilities are caught before they can be exploited.</p>
</li>
<li><p><strong>Sort by last activity, then by exposure:</strong> Rank resources by how recently they saw network traffic or authentication, and cross-reference against public network reachability. A resource that's both idle and internet-facing is the highest-priority item on the list, every time.</p>
</li>
<li><p><strong>Require an owner tag at creation:</strong> Enforce a policy that rejects the creation of any resource without owner and environment tags. Untagged resources become the queue you work through, and the queue stops growing.</p>
</li>
<li><p><strong>Give non-production resources a default lifetime:</strong> Attach an expiry tag to anything created in a test or sandbox account, and run an automated job that stops resources past their date and deletes them after a grace period. Make deletion the default and continuation the thing that requires a decision.</p>
</li>
<li><p><strong>Treat production data in test environments as an incident:</strong> Restoring a production snapshot into a lower environment should trigger an alert. If realistic data is genuinely needed, mask it as part of the restore process.</p>
</li>
</ol>
<p>Continuous asset discovery is another important capability of cloud security posture management. By maintaining an up-to-date inventory of cloud resources, organisations can quickly identify unused assets and remove them before they become security liabilities.</p>
<h2 id="heading-hidden-risk-4-compliance-drift">Hidden Risk #4: Compliance Drift</h2>
<p>Meeting regulatory requirements isn't a one-time project. Standards such as ISO 27001, SOC 2, PCI DSS, HIPAA, and GDPR require organisations to maintain secure configurations over time.</p>
<p>As cloud environments evolve, once-compliant systems can gradually drift away from required security baselines. A disabled encryption setting, an open network port, or missing activity logs may create compliance violations without anyone noticing.</p>
<p>Manual compliance reviews often occur quarterly or annually, leaving long periods during which risks remain undetected.</p>
<h3 id="heading-what-this-looks-like-in-practice">What This Looks Like in Practice</h3>
<p>An organisation passes its SOC 2 audit. Part of the evidence is that API activity logging is enabled across all accounts and all regions, with logs written to a dedicated, immutable archive.</p>
<p>Four months later, an engineer investigating a surprise bill notices that log storage is one of the larger line items. Most of the volume comes from high-frequency read events in a development account. They disable logging in that account to cut costs. It's a sensible-looking decision made with incomplete context, and it's approved in a routine change ticket by someone who doesn't know the account is in the audit scope.</p>
<p>Nothing breaks and no alert fires. The gap surfaces eight months later during audit fieldwork, when the assessor asks for a continuous log record for the period and the organisation can't produce one. There's no way to backfill it. The finding stands, and the same gap means that if an incident had occurred in that account, there would be no record of who did what.</p>
<h3 id="heading-how-to-mitigate-it">How to Mitigate it</h3>
<ol>
<li><p><strong>Map each control to a machine-checkable rule:</strong> "Activity logging is enabled everywhere" becomes a specific check: a multi-region trail exists in every account, log file validation is on, and the destination has retention and object-lock configured. If a control can't be expressed as a check, it can't be monitored continuously.</p>
</li>
<li><p><strong>Make the critical controls structurally hard to disable:</strong> Deploy logging from the organisation level rather than per account, and apply a service control policy that denies the disable and delete actions to everyone except a break-glass identity. This turns a one-click mistake into a deliberate act.</p>
</li>
<li><p><strong>Run the checks continuously and alert on transitions:</strong> The valuable signal isn't the monthly compliance score, it's the moment a control moves from compliant to non-compliant. Route that event to a channel someone actually reads, with the account, the resource, and the identity that made the change.</p>
</li>
<li><p><strong>Add a compliance-scope check to your change process:</strong> Change tickets touching accounts in audit scope should surface that fact automatically, so the approver knows what they're approving.</p>
</li>
<li><p><strong>Keep the evidence as you go:</strong> Store the continuous check results with timestamps. Audit preparation then becomes an export rather than a scramble, and you find gaps months before an assessor does.</p>
</li>
</ol>
<p>Cloud security posture management continuously evaluates cloud environments against security frameworks and compliance standards. This allows organisations to detect violations early, simplify audit preparation, and reduce regulatory risk.</p>
<h2 id="heading-hidden-risk-5-limited-visibility-across-multi-cloud-environments">Hidden Risk #5: Limited Visibility Across Multi-Cloud Environments</h2>
<p>Many organisations now operate workloads across multiple cloud providers. Development teams may choose different platforms based on cost, performance, or specialised services.</p>
<p>While this approach offers flexibility, it also creates fragmented security visibility. Each cloud provider has its own monitoring tools, dashboards, and security controls. Security teams may struggle to understand the overall security posture of the organisation.</p>
<p>Without centralised visibility, important risks can easily go unnoticed. One cloud environment may enforce strong security policies while another contains exposed resources and outdated configurations.</p>
<h3 id="heading-what-this-looks-like-in-practice">What This Looks Like in Practice</h3>
<p>An organisation runs its core platform on one cloud provider, where the security team has spent two years building guardrails: preventative policies, automated scanning, and an on-call rota that responds to findings.</p>
<p>Meanwhile, the data science group adopts a second provider for its managed machine learning tooling. The account is opened on a corporate card, funded through a departmental budget, and never onboarded into the security programme. There's no reason for anyone to notice, no ticket crosses the security team's desk, because from the data team's perspective nothing about their work has changed.</p>
<p>That second environment ends up hosting training datasets derived from production records. Its storage defaults are different from the primary provider's, the equivalent of "block public access" isn't switched on, and the terminology doesn't map cleanly onto the checks the security team already wrote. The organisation's security dashboard shows a healthy posture, and it's accurate for the 70% of the estate it can see.</p>
<p>The failure isn't a weak control. It's that a whole environment is outside the boundary of the thing doing the measuring.</p>
<h3 id="heading-how-to-mitigate-it">How to Mitigate it</h3>
<ol>
<li><p><strong>Start with a billing reconciliation, not a technical scan:</strong> Ask finance for every cloud vendor the organisation pays, then compare that list against the accounts your security tooling monitors. Shadow cloud environments show up in expense reports long before they show up in a scanner.</p>
</li>
<li><p><strong>Write your baseline in terms of outcomes, not provider features:</strong> Define controls as "object storage must not be readable by anonymous principals" rather than naming a specific provider's setting. One statement then maps onto every platform, and the standard doesn't fragment.</p>
</li>
<li><p><strong>Normalise findings into a single queue:</strong> Pull results from each provider into one place with consistent severity scoring, so a critical exposure in the smallest environment ranks above a low-severity finding in the largest. Severity should reflect business impact, not which dashboard raised it.</p>
</li>
<li><p><strong>Make onboarding a condition of account creation:</strong> Require any new cloud account, on any provider, to be enrolled in central monitoring before it can hold production or production-derived data. Pair the requirement with a fast, low-friction path so teams aren't tempted to route around it.</p>
</li>
<li><p><strong>Re-run the discovery on a schedule:</strong> New accounts appear continuously. Repeat the billing reconciliation quarterly, because the environment you don't know about is by definition the one you'll never get an alert for.</p>
</li>
</ol>
<p>Cloud security posture management provides a unified view across multiple cloud providers, allowing organisations to monitor security consistently regardless of where workloads are deployed.</p>
<h2 id="heading-why-manual-security-reviews-are-no-longer-enough">Why Manual Security Reviews Are No Longer Enough</h2>
<p>Traditional security audits were designed for relatively stable infrastructure. Cloud environments operate very differently.</p>
<p>Infrastructure changes can occur hundreds or even thousands of times each day through automated deployment pipelines. New services are launched continuously, configurations are updated frequently, and development teams release software at a rapid pace.</p>
<p>Human reviewers can't keep up with this level of change. By the time a manual assessment is completed, the cloud environment may already look completely different.</p>
<p>Notice what the five examples above have in common. In every case, the environment was compliant at some point in the past, and a single reasonable-looking decision moved it out of compliance without producing an error, an outage, or a complaint. A bucket policy was reused. A role was widened to unblock a deployment. A test environment outlived its project. Logging was disabled to control cost. An account was opened outside the security boundary.</p>
<p>None of these would be caught by a quarterly review, because by the time a reviewer arrives, the change is months old and looks like part of the furniture. Automation has become essential. Continuous monitoring allows organisations to identify new risks immediately instead of discovering them weeks or months later.</p>
<h2 id="heading-how-cloud-security-posture-management-strengthens-cloud-security">How Cloud Security Posture Management Strengthens Cloud Security</h2>
<p>Cloud security posture management provides continuous visibility into cloud environments by automatically evaluating resources against security best practices and organisational policies.</p>
<p>Rather than replacing existing security tools, it complements them by focusing on configuration security, governance, compliance, and risk reduction.</p>
<p>A modern cloud security posture management platform can discover cloud assets, monitor configuration changes, identify excessive permissions, detect publicly exposed resources, validate compliance requirements, and prioritise security findings based on business impact.</p>
<p>Many platforms also support automated remediation. Instead of simply reporting an issue, they can trigger workflows that correct insecure configurations or notify the appropriate teams before vulnerabilities are exploited.</p>
<p>A word of caution on automated remediation: start it in report-only mode. A rule that automatically closes public access is exactly right for a storage bucket holding internal exports and exactly wrong for one serving a public website's static assets. Run new rules in observation mode for a few weeks, review what they would have changed, and only then let them act , beginning with the resource types where a false positive is cheap.</p>
<p>This proactive approach allows organisations to reduce risk without slowing down software development.</p>
<h2 id="heading-building-a-stronger-cloud-security-strategy">Building a Stronger Cloud Security Strategy</h2>
<p>Technology alone can't eliminate cloud security risks. Organisations must also establish strong governance processes and promote security awareness across development, operations, and security teams.</p>
<p>Security should become part of the software development lifecycle rather than an activity performed after deployment. Infrastructure templates should follow secure defaults, access permissions should be reviewed regularly, and cloud resources should be continuously monitored throughout their lifecycle.</p>
<p>If you're starting from scratch, the sequence that tends to work is: inventory first, since you can't secure what you can't see; then public exposure, because that's where the shortest path from mistake to breach runs; then identity, because over-permissioned roles determine how far an attacker gets once inside; and finally compliance mapping, which is far easier once the first three are under control.</p>
<p>Regular security training also helps reduce human error. Developers who understand cloud security best practices are less likely to introduce risky configurations during deployment. It's worth noting that in every example in this article, the person who introduced the risk was doing their job competently under normal constraints. Training works best when it's framed that way, and when the secure path is also the convenient one.</p>
<p>Combining secure development practices with cloud security posture management creates multiple layers of protection that significantly reduce the likelihood of security incidents.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Cloud infrastructure offers tremendous flexibility, but it also introduces risks that are often difficult to detect through traditional security practices. Misconfigured resources, excessive permissions, forgotten assets, compliance drift, and fragmented visibility can quietly weaken an organisation's security posture without triggering immediate alarms.</p>
<p>As cloud environments continue to grow in size and complexity, continuous monitoring has become a necessity rather than a luxury. Cloud security posture management enables organisations to identify vulnerabilities, maintain compliance, and respond to security risks before they lead to costly breaches.</p>
<p>The organisations that succeed in the cloud aren't those that eliminate every possible risk. They're the ones who continuously understand their environment, detect changes as they happen, and act quickly to maintain a secure cloud infrastructure.</p>
<p>In a landscape where new resources are created every day, maintaining visibility into your cloud security posture is one of the most effective ways to stay ahead of evolving threats.</p>
<p>Hope you enjoyed this article. You can <a href="https://linkedin.com/in/manishmshiva">connect with me on LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Add Dynamic Features to a Static Site Without a Server ]]>
                </title>
                <description>
                    <![CDATA[ Static sites are having a moment, and it makes sense. A folder of HTML, CSS, and JavaScript files is fast to load, cheap to host, and very hard to break. Tools like Astro, Eleventy, and Hugo build tha ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-add-dynamic-features-to-a-static-site-without-a-server/</link>
                <guid isPermaLink="false">6a79dc91e7c11cc73062288e</guid>
                
                    <category>
                        <![CDATA[ Static Website ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Mon, 10 Aug 2026 14:13:37 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/9796f3aa-8b5c-4bcf-804b-57725cc2c08f.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Static sites are having a moment, and it makes sense. A folder of HTML, CSS, and JavaScript files is fast to load, cheap to host, and very hard to break.</p>
<p>Tools like <a href="https://astro.build/">Astro</a>, <a href="https://www.11ty.dev/">Eleventy</a>, and <a href="https://gohugo.io/">Hugo</a> build that folder for you from Markdown files and templates. Hosts like Netlify, Vercel, and Cloudflare Pages then serve the result from a CDN, often for free.</p>
<p>Then your site needs to actually do something. A reader wants to leave a comment, or someone wants to email you. Maybe you want to show live prices, hide a page behind a login, or collect email addresses before a launch.</p>
<p>Most developers reach for a backend at this point. They spin up an Express app, add a database, and pick a hosting plan. Now they own a server, and servers need care forever.</p>
<p>The good news is that you often don't need one. Most dynamic features on a small site work fine without a server of your own, so here's how to think about the problem.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-static-does-not-mean-frozen">Static Does Not Mean Frozen</a></p>
</li>
<li><p><a href="#heading-start-with-what-the-browser-already-does">Start With What the Browser Already Does</a></p>
</li>
<li><p><a href="#heading-handling-form-submissions">Handling Form Submissions</a></p>
</li>
<li><p><a href="#heading-serverless-functions-for-the-rest">Serverless Functions for the Rest</a></p>
</li>
<li><p><a href="#heading-databases-and-logins-you-can-rent">Databases and Logins You Can Rent</a></p>
</li>
<li><p><a href="#heading-comments-search-and-payments">Comments, Search, and Payments</a></p>
</li>
<li><p><a href="#heading-know-when-you-have-outgrown-it">Know When You Have Outgrown It</a></p>
</li>
</ul>
<h2 id="heading-static-does-not-mean-frozen">Static Does Not Mean Frozen</h2>
<p>The word "static" describes how your HTML reaches the browser, not what happens after it lands. A static site can still run all the JavaScript you want. It can fetch data, rewrite the page, listen for clicks, and talk to any public API.</p>
<p>There's only one thing it can't do, which is run your code before the page is sent. That means it can't keep a secret, query a private database, or make a decision based on who is asking.</p>
<p>That single limit is the whole design problem. Once you see it clearly, the rest is just sorting. Some work belongs in the browser, some belongs in a service you rent, and a small slice needs to run somewhere private.</p>
<h2 id="heading-start-with-what-the-browser-already-does">Start With What the Browser Already Does</h2>
<p>Check the platform before you add anything to your stack, because browsers ship with more power than most of us use.</p>
<p>The <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API"><code>fetch</code> API</a> pulls JSON from any public endpoint. The <code>&lt;dialog&gt;</code> element gives you an accessible modal with no library, and <code>&lt;details&gt;</code> gives you an accordion. CSS now handles sticky headers, scroll-driven animation, and container queries, all of which used to need JavaScript.</p>
<p>A lot of features that seem to need a backend are really just a fetch call and a template string. A weather widget, a GitHub activity feed, a currency converter, a live score, or a Mastodon timeline: every one of those runs happily from the browser, because the data is public and the endpoint needs no key. Write the fetch, handle the loading and error states properly, and move on.</p>
<h2 id="heading-handling-form-submissions">Handling Form Submissions</h2>
<p>Forms are where most static sites hit their first real wall, because a submission has to go somewhere your visitors can't see. You can't put a database password in client-side code, and you can't send email straight from a browser.</p>
<p>Luckily this problem has been solved many times over, and most static hosts will handle forms for you. <a href="https://docs.netlify.com/manage/forms/setup/">Netlify Forms</a> needs one extra attribute on your form tag. After that, Netlify catches each submission at the edge, stores it in a dashboard, and either emails you or pings a webhook.</p>
<p>Sometimes you need more than that. Spam filters, file uploads, conditional logic, multi-step flows, payments inside the form, or rows that land in a spreadsheet with no glue code all point toward a dedicated tool. This roundup of the <a href="https://forms.app/en/blog/best-form-builders">best form builders</a> is a good way to compare your options, since the real differences come down to logic, integrations, and how much control you keep over the markup.</p>
<p>Either way, the choice is about ownership. Write your own form endpoint and you own the validation, the rate limits, the spam defense, the storage, the alerts, and the deletion requests that arrive under GDPR. That's a lot of work for a contact form. Build it yourself when the form is part of your product, and rent it when the form is just a way for people to reach you.</p>
<h2 id="heading-serverless-functions-for-the-rest">Serverless Functions for the Rest</h2>
<p>Sooner or later you will need to run a few lines of code in private, whether to sign a request, hide an API key, or reshape a response before the browser sees it. That is exactly what serverless functions are for, and they're the smallest possible step away from a purely static site.</p>
<p>You drop a file into a folder, and your host turns it into a URL on the next deploy. That's the entire setup, and it works the same way in <a href="https://docs.netlify.com/build/functions/overview/">Netlify Functions</a>, <a href="https://vercel.com/docs/functions">Vercel Functions</a>, and <a href="https://developers.cloudflare.com/pages/functions/">Cloudflare Pages Functions</a>. The code stays short:</p>
<pre><code class="language-js">export default async function handler(request) {
  const res = await fetch("https://api.example.com/data", {
    headers: { Authorization: `Bearer ${process.env.API_KEY}` },
  });
  const data = await res.json();
  return Response.json({ total: data.items.length });
}
</code></pre>
<p>Your key lives in an environment variable on the host, so the browser calls <code>/api/handler</code> and never sees it. There's no server to keep alive, no operating system to patch, and no bill on a quiet day.</p>
<p>This is the right home for anything that needs a credential. Use it to send email through Resend or Postmark, call an AI model, check a webhook signature, or proxy a paid API whose key would otherwise leak within a day.</p>
<h2 id="heading-databases-and-logins-you-can-rent">Databases and Logins You Can Rent</h2>
<p>State is the last piece people assume needs a server, but it does not. <a href="https://supabase.com/docs">Supabase</a> puts Postgres behind a REST API with row-level security. Those rules live in the database itself, so you can query it from the browser and still be safe. Firebase does much the same with a different data model, while Cloudflare D1 and Turso give you SQLite at the edge.</p>
<p>Logins follow the same pattern. Clerk, Auth0, and Supabase Auth all handle sessions, password resets, social logins, and two-factor codes behind a client SDK. Authentication is genuinely hard to get right, so leaning on an audited service here isn't laziness. It's sensible risk management.</p>
<h2 id="heading-comments-search-and-payments">Comments, Search, and Payments</h2>
<p>The last few common features have drop-in answers too. <a href="https://giscus.app/">Giscus</a> turns GitHub Discussions into a comment box with a script tag and no database at all. <a href="https://pagefind.app/">Pagefind</a> builds a search index while your site builds and ships it as static files, so full-text search costs you nothing at runtime.</p>
<p>Stripe covers money. Payment Links and Checkout let you sell something with a plain link, and Stripe handles the card, the tax, and the receipt. Your own site never touches card data.</p>
<h2 id="heading-know-when-you-have-outgrown-it">Know When You Have Outgrown It</h2>
<p>This model has a real ceiling, and you should be aware of it rather than fight it. Watch for a few signs: your logic is now spread across six services, your monthly SaaS bill beats the cost of a small server, cold starts are hurting real users, or you need long jobs, a queue, or a socket that stays open for hours. When that day comes, a regular application server is the simpler tool, so move.</p>
<p>Until then, this setup buys you things that matter. Your site stays fast by default, your attack surface stays small, and your time goes into the product instead of the plumbing. Start with the browser, add a function when you need a secret, and rent the hard parts.</p>
<p>Hope you enjoyed this article. You can <a href="https://linkedin.com/in/manishmshiva">connect with me on LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What Happens During a Production Deployment? A Behind-the-Scenes Guide ]]>
                </title>
                <description>
                    <![CDATA[ You push your code. A few minutes later, it is live for real users. Between those two moments runs a long chain of machinery: builds, artefacts, migrations, health checks, traffic shifts. Every produc ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-happens-during-a-production-deployment/</link>
                <guid isPermaLink="false">6a70dada6358084ff948ee0f</guid>
                
                    <category>
                        <![CDATA[ deployment ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Kubernetes ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Mon, 03 Aug 2026 18:15:54 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5fc16e412cae9c5b190b6cdd/43567dce-ecbe-412e-ab40-2ef6e07dde0e.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>You push your code. A few minutes later, it is live for real users.</p>
<p>Between those two moments runs a long chain of machinery: builds, artefacts, migrations, health checks, traffic shifts. Every production engineer depends on that chain, and many teams still build and operate it themselves.</p>
<p>Deployment infrastructure has quietly become operational overhead. It started as a technical necessity, something every team had to assemble because nothing else existed.</p>
<p>Today it is a second system your engineers maintain alongside the product, consuming on-call rotations, sprint capacity, and 2 a.m. attention that could go somewhere better.</p>
<p>In this article, we'll walk through each stage of a real production deployment: the build, the artefact it produces, database migrations, health checks, rolling updates, and rollbacks. Along the way, we'll look at why <a href="https://www.freecodecamp.org/news/my-team-s-experience-moving-from-aws-to-a-paas/">platform-as-a-service (PaaS)</a> tools handle most of these steps for you, and what it costs a team to keep handling them itself.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-the-build-turning-code-into-something-that-can-run">The Build: Turning Code into Something That Can Run</a></p>
</li>
<li><p><a href="#heading-the-artefact-one-version-frozen-in-time">The Artefact: One Version, Frozen in Time</a></p>
</li>
<li><p><a href="#heading-database-migrations-the-riskiest-step">Database Migrations: The Riskiest Step</a></p>
</li>
<li><p><a href="#heading-health-checks-proving-the-new-version-is-alive">Health Checks: Proving the New Version Is Alive</a></p>
</li>
<li><p><a href="#heading-rolling-updates-replacing-the-planes-engine-mid-flight">Rolling Updates: Replacing the Plane's Engine Mid-Flight</a></p>
</li>
<li><p><a href="#heading-rollbacks-the-escape-hatch">Rollbacks: The Escape Hatch</a></p>
</li>
<li><p><a href="#heading-when-you-dont-need-a-paas">When You Don't Need a PaaS</a></p>
</li>
<li><p><a href="#heading-should-you-still-be-running-this-yourself">Should You Still Be Running This Yourself?</a></p>
</li>
</ul>
<h2 id="heading-the-build-turning-code-into-something-that-can-run"><strong>The Build: Turning Code into Something That Can Run</strong></h2>
<p>A deployment does not ship your source code as-is. It ships the result of a build. The build stage takes your code and turns it into something a server can run.</p>
<p>What this looks like depends on your stack. A Java or Go project gets compiled into a binary. A JavaScript front end gets bundled and minified. A Python app gets its dependencies resolved and pinned. In most modern setups, all of this gets packed into a <a href="https://www.freecodecamp.org/news/an-introduction-to-docker-and-containers-for-beginners/">container image</a>, which is a frozen snapshot of your app plus everything it needs to run.</p>
<p>The build stage also runs your tests. Unit tests, linting, and security scans all happen here. If any of them fail, the deployment stops before it can touch production. This is the cheapest place to catch a bug. A failed build costs you a few minutes. A failed deployment can cost you customers.</p>
<img src="https://cdn.hashnode.com/uploads/covers/66c6d8f04fa7fe6a6e337edd/9a8b5d93-802c-4898-bd07-91a90041f93a.svg" alt="stages of code deployment" style="display: block;" width="680" height="520" loading="lazy">

<p>Teams that run their own pipelines spend real effort here. They maintain build servers, cache dependencies, and debug flaky test runners.</p>
<p>None of that work ships a feature. It is pure upkeep, and it never ends. A PaaS bakes this whole stage into the platform. You push code, and the platform detects your language, builds it the same way every time, and fails fast when something is wrong. The build still happens. Your engineers just stop paying for it in hours.</p>
<h2 id="heading-the-artefact-one-version-frozen-in-time"><strong>The Artefact: One Version, Frozen in Time</strong></h2>
<p>The output of a build is called an artefact. It might be a container image, a compiled binary, or a zipped bundle. Whatever the format, the artefact has one job: to be exact. It represents one precise version of your app, frozen at one point in time.</p>
<p>This matters more than it sounds. The artefact that passed your tests must be the exact same one that reaches production. If you rebuild between testing and shipping, you risk shipping something slightly different. A dependency may have updated. A build flag may have changed. "It worked in staging" often means "we built it twice and got two different results."</p>
<p>Good pipelines build once and promote the same artefact through every stage. Artefacts get versioned and stored in a registry, so any version can be pulled and run again later. That stored history is also what makes rollbacks possible, which we will get to soon.</p>
<p>On a PaaS, artefact handling is standard practice by default. Every deploy produces a numbered release. The platform stores it, tracks it, and can restore it. You do not have to design a registry strategy, write promotion scripts, or assign an engineer to own them. The discipline is built in.</p>
<h2 id="heading-database-migrations-the-riskiest-step"><strong>Database Migrations: The Riskiest Step</strong></h2>
<p>Before new code goes live, the database often has to change with it. Maybe the new version needs a new column or a new table. These changes are called migrations, and they are the most dangerous part of most deployments.</p>
<p>Why? Code is easy to replace. Data is not. If you deploy a bad code version, you can swap it out. If a migration corrupts or drops data, there may be no clean way back. Migrations also create a tricky window of time. For a few minutes, old code and new code may run against the same database at once. Both versions have to work with the schema during that window.</p>
<p>The safe pattern is to make migrations backwards-compatible. Add the new column first, deploy code that can handle both shapes, then clean up the old column in a later release. It takes more steps, but each step is safe on its own.</p>
<p>A PaaS cannot write your migrations for you. No tool can know what your data means. But a good platform gives migrations a defined place in the release process, runs them in order, and logs exactly what ran and when. That structure prevents the classic failure where someone runs a migration by hand and forgets to tell the team.</p>
<h2 id="heading-health-checks-proving-the-new-version-is-alive"><strong>Health Checks: Proving the New Version Is Alive</strong></h2>
<p>Once the new version starts, the platform does not just trust it. It checks. A health check is a small endpoint in your app, often just a route that returns "OK." The platform calls it over and over. If the app answers, it is considered healthy. If it does not, the platform assumes something is wrong.</p>
<p>There are usually two kinds of checks. A readiness check asks, "Are you ready to receive traffic?" A liveness check asks, "Are you still working, or should I restart you?" The difference matters. An app can be alive but not ready, such as when it is still warming up a cache.</p>
<p>Health checks are the gatekeepers of a deployment. No traffic reaches a new version until it proves it can handle requests. Without them, you would be routing real users to an app that might still be crashing on startup.</p>
<p>Every serious PaaS runs health checks automatically. You define the endpoint, and the platform handles the polling, the timeouts, and the decisions. Teams that build this themselves tune all of those settings by hand, and they usually learn the right values through painful trial and error. That tuition is paid in engineering time, on a problem the industry solved years ago.</p>
<h2 id="heading-rolling-updates-replacing-the-planes-engine-mid-flight"><strong>Rolling Updates: Replacing the Plane's Engine Mid-Flight</strong></h2>
<p>Here is the hard part. Your old version is serving live traffic right now. You need to replace it without dropping a single request. The most common answer is a <a href="https://kubernetes.io/docs/tutorials/kubernetes-basics/update/update-intro/">rolling update</a>.</p>
<p>It works like this. Say you have four copies of your app running. The platform starts one copy of the new version and waits for its health checks to pass. Then it shifts a slice of traffic to it and shuts down one old copy. It repeats this, one copy at a time, until only the new version remains. Users never notice, because at every moment there are enough healthy copies to serve everyone.</p>
<p>Some teams use variations of this idea. A blue-green deployment runs the full new version beside the old one, then flips all traffic at once. A canary release sends a tiny share of users to the new version first, watching for errors before going wider.</p>
<p>Doing this by hand means writing orchestration logic, managing load balancer rules, and handling every edge case where a step fails halfway. That is months of engineering effort to build and a permanent tax to maintain, all for behavior a PaaS ships as the default. On a platform, you get zero-downtime releases out of the box, not as a project your team has to staff.</p>
<h2 id="heading-rollbacks-the-escape-hatch"><strong>Rollbacks: The Escape Hatch</strong></h2>
<p>Sometimes the new version passes every check and still breaks something real. An error rate climbs. A page loads blank. Now speed matters more than anything, and the fastest fix is rarely a new patch. It is a rollback: redeploying the previous artefact that you already know works.</p>
<p>This is why frozen, versioned artefacts are so important. A rollback is only fast if the old version is stored, tested, and ready to run. Teams that rebuild from an old commit under pressure are gambling at the worst possible time.</p>
<p>On most PaaS platforms, a rollback is one command or one click. The platform keeps your release history and can restore any previous version in seconds. That single feature has saved more on-call engineers' nights than perhaps any other.</p>
<h2 id="heading-when-you-dont-need-a-paas">When You Don't Need a PaaS</h2>
<p>The case for handing deployment to a platform is strong, but it isn't universal. There are teams for whom owning the pipeline is not overhead; it is a deliberate and justified engineering decision.</p>
<h3 id="heading-when-compliance-demands-it">When Compliance Demands It</h3>
<p>Regulated industries like finance, healthcare, government, often operate under requirements that a standard PaaS cannot satisfy out of the box. Data residency rules may dictate exactly which physical infrastructure your builds touch. Audit requirements may demand a level of provenance and access logging that a managed platform doesn't expose.</p>
<p>Security controls may need to extend into the build environment itself, not just the runtime. In these contexts, the cost of owning the pipeline is real, but it is the cost of operating in that industry.</p>
<h3 id="heading-when-deployment-is-your-product">When Deployment is Your Product</h3>
<p>If your company sells deployment infrastructure, a CI/CD platform, a release orchestration tool, an internal developer platform, then your pipeline is not overhead at all. It is the product.</p>
<p>The engineers maintaining it are doing product work, not distraction work. The same applies to platform engineering teams at large organizations whose explicit charter is to build and own the deployment layer for dozens of other internal teams. In both cases, the question of "why are we running this ourselves" has an obvious answer: because this is what we do.</p>
<h3 id="heading-when-your-infrastructure-is-genuinely-unusual">When Your Infrastructure is Genuinely Unusual</h3>
<p>Most PaaS platforms are optimized for stateless web services and standard container workloads. If your system falls outside that envelope, GPU clusters, real-time systems with strict latency requirements, hybrid on-premise and cloud deployments, hardware-in-the-loop testing, a general-purpose platform may simply not fit.</p>
<p>Shoehorning an unusual workload into a PaaS often produces more friction than building narrow, purpose-built deployment tooling around the specific constraints you actually have.</p>
<p>The common thread across all three cases is specificity. The teams that are right to own their pipelines can usually state clearly why a platform doesn't fit. If the answer is "we've always done it this way" or "we like having control," that's worth questioning. If the answer is "our compliance requirements mandate X" or "we sell this," that's a reason.</p>
<h2 id="heading-should-you-still-be-running-this-yourself">Should You Still Be Running This Yourself?</h2>
<p>A PaaS does not make any of these steps disappear. The build still runs. Artefacts still get stored. Migrations still execute, health checks still poll, and traffic still shifts one copy at a time. Abstracting these mechanics does not eliminate them. It standardizes them, and pushes their maintenance onto a team whose entire product is deployment.</p>
<p>That is the question every product team should now ask plainly: why are we still building and operating this machinery ourselves? A decade ago, a custom pipeline was unavoidable. Today it is a choice, and for most teams it is the wrong one. Every hour spent debugging a flaky build agent, tuning a health check timeout, or patching orchestration scripts is an hour taken from the product your customers actually pay for. The pipeline does not differentiate you. It cannot. Your competitors' deploys work the same way yours do.</p>
<p>Know how the chain works, because on-call at 2 a.m. demands it. But knowing how it works is not a reason to own it. "We built our own deployment system" is not a badge of honor anymore. It is an admission that your team maintains a second product with no customers. Unless deployment infrastructure is your business, hand the machinery to a platform, and put your engineers back on the work only they can do.</p>
<p>Hope you enjoyed this article. You can <a href="https://linkedin.com/in/manishmshiva">connect with me on LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Agentic AI? How AI Is Evolving From Chatbot to Co-Worker ]]>
                </title>
                <description>
                    <![CDATA[ You ask ChatGPT a question. It answers. You ask another. It answers again. That back-and-forth has been the standard way most people experience AI: a smart, fast assistant that responds when spoken to ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-agentic-ai-from-chatbot-to-co-worker/</link>
                <guid isPermaLink="false">6a6cc10945a46b452b5bc4a1</guid>
                
                    <category>
                        <![CDATA[ agentic AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ chatbot ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Artificial Intelligence ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Fri, 31 Jul 2026 15:36:41 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5fc16e412cae9c5b190b6cdd/66ea50ee-f208-47c2-a35b-cd6823464f21.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>You ask ChatGPT a question. It answers. You ask another. It answers again. That back-and-forth has been the standard way most people experience AI: a smart, fast assistant that responds when spoken to.</p>
<p>But something big is changing. AI is no longer just responding. It is planning, deciding, and acting on its own. This new kind of AI is called <strong>agentic AI</strong>, and it is quickly becoming one of the most important shifts in technology today.</p>
<p>In this article, we'll break down what agentic AI is, how it works, where it is being used, and what risks it brings along.</p>
<h2 id="heading-what-well-cover"><strong>What We'll Cover</strong></h2>
<ul>
<li><p><a href="#what-does-agentic-even-mean">What Does "Agentic" Even Mean?</a></p>
</li>
<li><p><a href="#how-a-chatbot-works-vs-how-an-agent-works">How a Chatbot Works vs. How an Agent Works</a></p>
</li>
<li><p><a href="#a-real-example-booking-a-business-trip">A Real Example: Booking a Business Trip</a></p>
</li>
<li><p><a href="#the-building-blocks-of-an-ai-agent">The Building Blocks of an AI Agent</a></p>
</li>
<li><p><a href="#why-is-this-happening-now">Why Is This Happening Now?</a></p>
</li>
<li><p><a href="#where-agentic-ai-is-being-used-today">Where Agentic AI Is Being Used Today</a></p>
</li>
<li><p><a href="#what-are-the-risks">What Are the Risks?</a></p>
</li>
<li><p><a href="#what-this-means-for-you">What This Means for You</a></p>
</li>
</ul>
<h2 id="heading-what-does-agentic-even-mean">What Does "Agentic" Even Mean?</h2>
<p>The word comes from "agency": the ability to act independently toward a goal.</p>
<p>A regular chatbot waits for you to ask something. An agentic AI system is given a goal and then figures out the steps needed to reach it. It can use tools, browse the web, write and run code, send emails, and loop back to fix its own mistakes, without you guiding every move.</p>
<p>Think of the difference this way: A chatbot is like a very knowledgeable colleague who only speaks when spoken to. An AI agent is like giving that colleague a task and saying, "Handle this for me," then walking away.</p>
<h2 id="heading-how-a-chatbot-works-vs-how-an-agent-works">How a Chatbot Works vs. How an Agent Works</h2>
<p>To understand agentic AI, it helps to see the difference in action.</p>
<p>A chatbot follows a simple loop:</p>
<pre><code class="language-plaintext">User types message → AI reads it → AI generates a reply → Done
</code></pre>
<p>An AI agent follows a much more complex loop:</p>
<pre><code class="language-plaintext">User gives a goal
  → Agent breaks it into steps
  → Agent picks a tool (web search, code runner, email, etc.)
  → Agent takes action
  → Agent checks the result
  → If result is wrong or incomplete, agent adjusts and tries again
  → Agent moves to the next step
  → Repeats until the goal is achieved
</code></pre>
<p>That ability to plan, act, check, and retry is what makes agentic AI fundamentally different. It is not just predicting the next word in a sentence. It is running a small project.</p>
<h2 id="heading-a-real-example-booking-a-business-trip">A Real Example: Booking a Business Trip</h2>
<p>Here is a concrete example to make this tangible.</p>
<p>You tell an AI agent: <em>"Book me the cheapest flight to Mumbai next Monday, find a hotel near the conference centre, and add both to my calendar."</em></p>
<p>A chatbot would give you links or suggestions and leave the rest to you.</p>
<p>An AI agent would:</p>
<pre><code class="language-plaintext">Step 1: Search for flights to Mumbai on Monday
Step 2: Compare prices and pick the cheapest option
Step 3: Fill in your passenger details and complete the booking
Step 4: Search for hotels near the conference centre
Step 5: Cross-check availability and price
Step 6: Complete the hotel booking
Step 7: Pull the confirmation details from both bookings
Step 8: Add flight and hotel to your Google Calendar
Step 9: Send you a summary email
</code></pre>
<p>Each of those steps involves calling a different tool or service. The agent handles all of it. You just gave it the goal.</p>
<h2 id="heading-the-building-blocks-of-an-ai-agent">The Building Blocks of an AI Agent</h2>
<p>Every AI agent, no matter how complex, is built on a few core components.</p>
<p><strong>A brain (the language model).</strong> This is the reasoning engine: usually a <a href="https://en.wikipedia.org/wiki/Large_language_model">large language model</a> like <a href="https://en.wikipedia.org/wiki/GPT-4">GPT-4</a> or Claude. It reads the goal, thinks through the plan, and decides what to do next.</p>
<p><strong>Memory.</strong> Agents need to remember what they have already done. Short-term memory keeps track of the current task. Long-term memory lets the agent store information across sessions: so it remembers your preferences from last time.</p>
<p><strong>Tools.</strong> An agent without tools is just a chatbot. Tools are what give agents power. Common tools include web search, code execution, file reading, API calls, email, and calendar access. The agent decides which tool to use and when.</p>
<p><strong>A feedback loop.</strong> After taking an action, the agent checks whether it worked. If a step failed or returned a wrong result, it tries a different approach. This self-correction is what makes agents reliable for multi-step tasks.</p>
<h2 id="heading-why-is-this-happening-now">Why Is This Happening Now?</h2>
<p>Agentic AI is not a brand new idea. Researchers have explored autonomous agents for decades. So why is it suddenly everywhere in 2026?</p>
<p>Three things came together at the right time.</p>
<p>First, language models got dramatically better at reasoning. Earlier models were good at writing text but poor at logical planning. Newer models can break down complex tasks, spot errors in their own output, and change strategy mid-task.</p>
<p>Second, tool integration became much easier. Frameworks like <a href="https://www.langchain.com">LangChain</a>, <a href="https://www.microsoft.com/en-us/research/project/autogen/">AutoGen</a>, and OpenAI's function calling made it straightforward for developers to connect a language model to real-world tools. What once took months of custom engineering now takes days.</p>
<p>Third, businesses started demanding it. Copy-pasting AI suggestions into forms and emails gets old quickly. Companies want AI that completes workflows, not just assists with them.</p>
<h2 id="heading-where-agentic-ai-is-being-used-today">Where Agentic AI Is Being Used Today</h2>
<p>Agentic AI is already showing up across many industries, not just in tech companies.</p>
<p>In software development, AI agents write code, run tests, find bugs, and open pull requests: all from a single instruction like "fix the login error on the checkout page."</p>
<p>In customer support, agents handle entire conversations. They look up order history, process refunds, escalate complex cases to a human, and follow up via email: without a support agent touching the ticket.</p>
<p>In research, agents search dozens of sources, extract key data, cross-reference findings, and produce a summarized report. A task that used to take hours gets done in minutes.</p>
<p>In marketing, agents draft campaign content, schedule social posts, monitor performance metrics, and suggest adjustments based on what is working.</p>
<h2 id="heading-what-are-the-risks">What Are the Risks?</h2>
<p>Agentic AI is powerful, but it comes with real concerns that are worth knowing about.</p>
<p>The biggest one is unintended actions. An agent that misunderstands a goal can take a chain of wrong steps before anyone notices. Unlike a chatbot that gives a wrong answer you can simply ignore, an agent that makes a wrong booking or sends the wrong email has already caused a real-world consequence.</p>
<p>There is also the issue of security. Agents that can read emails, access files, and browse the web are attractive targets. A technique called "<a href="https://owasp.org/www-community/attacks/PromptInjection">prompt injection</a>" can trick an agent into following malicious instructions hidden inside a webpage or document it reads during a task.</p>
<p>Finally, there is accountability. When an AI agent makes a mistake across a ten-step workflow, it can be genuinely hard to trace exactly where things went wrong, and who or what is responsible.</p>
<p>This is why most well-designed agentic systems today include a "human in the loop": a checkpoint where a person reviews and approves key decisions before the agent acts on them.</p>
<h2 id="heading-what-this-means-for-you">What This Means for You</h2>
<p>You do not need to be a developer to feel the impact of agentic AI. These systems are already being built into the tools people use every day: email clients, project management apps, CRM systems, and more.</p>
<p>The shift worth understanding is this: AI is moving from a tool you interact with to a system that works alongside you. The chatbot answered your questions. The agent handles your tasks.</p>
<p>That is a meaningful change: not just in how AI works, but in how we work with it. The more you understand what agents can and cannot do, the better placed you are to use them well, delegate wisely, and catch mistakes before they snowball.</p>
<p>Agentic AI is not science fiction. It is already in your workplace, and it is only going to become more capable from here.</p>
<p>Understanding the technology is the first step. The next is deciding how to put it to work.</p>
<p>Hope you enjoyed this article. You can <a href="https://linkedin.com/in/manishmshiva">connect with me on LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Diagnose Production Bugs When You Can't Reproduce Them Locally ]]>
                </title>
                <description>
                    <![CDATA[ Every developer eventually encounters the same frustrating problem. A customer reports that your application is failing in production. You try the exact same workflow on your development machine, but  ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-diagnose-production-bugs-when-you-can-t-reproduce-them-locally/</link>
                <guid isPermaLink="false">6a63d10c86ddd43ae5c0036e</guid>
                
                    <category>
                        <![CDATA[ debugging ]]>
                    </category>
                
                    <category>
                        <![CDATA[ production ]]>
                    </category>
                
                    <category>
                        <![CDATA[ PaaS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Environment ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Software Engineering ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Fri, 24 Jul 2026 20:54:36 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/950ab466-32a5-43f5-a9d6-2146b145f0dc.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Every developer eventually encounters the same frustrating problem.</p>
<p>A customer reports that your application is failing in production. You try the exact same workflow on your development machine, but everything works perfectly. Your teammates can't reproduce the issue either. Automated tests pass. There are no obvious code changes that explain the failure.</p>
<p>Meanwhile, customers continue to experience the bug.</p>
<p>These issues are among the most difficult to solve because the problem often isn't the code itself. It's the environment the code is running in. Differences in configuration, infrastructure, traffic patterns, operating systems, dependencies, or production data can expose bugs that never appear during development.</p>
<p>Here's the uncomfortable truth: most of that difficulty is self-inflicted. Every server you manage, every log pipeline you wire together, and every configuration file you maintain by hand adds to an invisible infrastructure tax. And you pay that tax at the worst possible moment, when production is down and customers are waiting.</p>
<p>Fortunately, production-only bugs can be investigated systematically. In this article, you'll learn how to approach these issues using logs, metrics, distributed tracing, and environment analysis. You'll also see why applications running on a Platform as a Service (PaaS) are significantly easier to debug when things go wrong, because someone else is paying the tax for you.</p>
<h3 id="heading-what-well-cover">What We'll Cover:</h3>
<ul>
<li><p><a href="#heading-why-does-production-behave-differently">Why Does Production Behave Differently?</a></p>
</li>
<li><p><a href="#heading-start-with-evidence-not-assumptions">Start with Evidence, Not Assumptions</a></p>
</li>
<li><p><a href="#heading-logs-tell-you-what-happened">Logs Tell You What Happened</a></p>
</li>
<li><p><a href="#heading-metrics-reveal-trends">Metrics Reveal Trends</a></p>
</li>
<li><p><a href="#heading-distributed-tracing-connects-every-service">Distributed Tracing Connects Every Service</a></p>
</li>
<li><p><a href="#heading-reproduce-production-as-closely-as-possible">Reproduce Production as Closely as Possible</a></p>
</li>
<li><p><a href="#heading-isolate-environmental-variables">Isolate Environmental Variables</a></p>
</li>
<li><p><a href="#heading-a-simple-production-only-bug">A Simple Production-only Bug</a></p>
</li>
<li><p><a href="#heading-verify-the-deployment-itself">Verify the Deployment Itself</a></p>
</li>
<li><p><a href="#heading-do-you-actually-need-a-paas">Do You Actually Need a PaaS?</a></p>
</li>
<li><p><a href="#heading-why-debugging-is-easier-on-a-paas">Why Debugging is Easier on a PaaS</a></p>
</li>
<li><p><a href="#heading-build-applications-that-are-easy-to-debug">Build Applications That Are Easy to Debug</a></p>
</li>
</ul>
<h2 id="heading-why-does-production-behave-differently">Why Does Production Behave Differently?</h2>
<p>Many developers think of production as simply a larger version of their local machine.</p>
<p>In reality, production environments are often very different.</p>
<p>A production application may run across multiple servers or containers behind a <a href="https://www.cloudflare.com/learning/performance/what-is-load-balancing/">load balancer</a>. It may connect to databases containing millions of records, communicate with third-party APIs, use distributed caches, process background jobs, and serve thousands of concurrent users.</p>
<p>Even seemingly small differences can introduce unexpected failures.</p>
<p>Imagine testing an API locally using simple English names like "John Smith." Everything works perfectly. In production, a customer submits a name containing emojis or accented characters, triggering an encoding issue that was never covered by your tests.</p>
<p>Or perhaps your application assumes an environment variable always exists because it's configured on every developer machine. During deployment, that variable is accidentally omitted, causing production requests to fail.</p>
<p>The code hasn't changed. The environment has.</p>
<p>Notice what these failures have in common. None of them are business logic problems. They're environment problems, and every piece of infrastructure your team owns and configures by hand is another surface where your environment can silently drift away from what your code expects. The more infrastructure you manage yourself, the more of these surfaces exist.</p>
<p>Understanding that production behaves differently is the first step toward diagnosing these issues.</p>
<h2 id="heading-start-with-evidence-not-assumptions">Start with Evidence, Not Assumptions</h2>
<p>When production starts failing, it's tempting to immediately start editing code.</p>
<p>Resist that temptation.</p>
<p>The fastest way to solve complex bugs is to gather evidence before making changes.</p>
<p>Start by answering questions such as:</p>
<ul>
<li><p>When did the issue begin?</p>
</li>
<li><p>Did it appear immediately after a deployment?</p>
</li>
<li><p>Does it affect every customer or only a small group?</p>
</li>
<li><p>Is every application instance failing?</p>
</li>
<li><p>Did infrastructure metrics change around the same time?</p>
</li>
</ul>
<p>Every answer narrows the search space.</p>
<p>But here's what nobody tells you: how quickly you can answer these questions depends almost entirely on your infrastructure, not your debugging skills.</p>
<p>If deployment history lives in one system, logs in another, and metrics in a third, answering even the first question means logging into three tools and manually lining up timestamps. The investigation can stall before it starts, not because the bug is hard, but because your tooling is fragmented.</p>
<p>Instead of guessing what might be wrong, you're building a timeline of events that points toward the root cause.</p>
<p>Good debugging is an investigation, not an experiment. And an investigation is only as fast as your access to the evidence.</p>
<h2 id="heading-logs-tell-you-what-happened">Logs Tell You What Happened</h2>
<p>Application logs are usually the first source of information during an incident.</p>
<p>Unfortunately, many applications generate logs that provide almost no useful context.</p>
<p>A message like this offers very little value:</p>
<pre><code class="language-plaintext">Error processing request.
</code></pre>
<p>Compare that with this example:</p>
<pre><code class="language-plaintext">Timestamp: 2026-07-13T09:41:17Z
RequestId: 91df72
CustomerId: 48291
Endpoint: POST /orders
Database: OrdersDB
Duration: 3.2 seconds
Exception: TimeoutException
</code></pre>
<p>Now you know when the failure occurred, which customer experienced it, which endpoint was affected, how long the request took, and what exception caused it.</p>
<p>So where does each of these logs come from? The first one is what you get by default. It's the product of a hurried <code>catch</code> block written while the developer was focused on the happy path, something like this:</p>
<pre><code class="language-csharp">catch (Exception)
{
    logger.LogError("Error processing request.");
}
</code></pre>
<p>The exception is caught, but everything useful about it, including the exception itself, is thrown away. The log message records <em>that</em> something failed, but nothing about <em>what</em>, <em>where</em>, or <em>for whom</em>.</p>
<p>The second log doesn't come from a fancier tool. It comes from a developer deciding, at the moment they wrote the code, what a future 3 a.m. investigator would need to know.</p>
<p>In practice, useful logs come from a few deliberate habits:</p>
<ul>
<li><p><strong>Always log the exception object itself</strong>, not just a message, so the type and stack trace are preserved.</p>
</li>
<li><p><strong>Attach request context automatically.</strong> Most web frameworks let you enrich every log entry with values like a request ID or customer ID once, in middleware, instead of repeating them in every log statement. In ASP.NET Core, for example, logging scopes do exactly this.</p>
</li>
<li><p><strong>Record what the code was doing</strong>, like the endpoint, the downstream dependency being called, and how long it took, because those are the first questions an investigator asks.</p>
</li>
</ul>
<p>Here's what that looks like in code:</p>
<pre><code class="language-csharp">catch (TimeoutException ex)
{
    logger.LogError(ex,
        "Order creation failed for {CustomerId} on {Endpoint} after {Duration}s",
        customerId, "POST /orders", stopwatch.Elapsed.TotalSeconds);
}
</code></pre>
<p>A good rule of thumb: write every log message for the person debugging an outage six months from now, who has never seen this code. That person is often you.</p>
<p>Notice that the message above uses named placeholders like <code>{CustomerId}</code> instead of string interpolation. That's <strong>structured logging</strong>: instead of flattening everything into one plain-text sentence, each value is stored as a separate named field alongside the message, typically as JSON. The entry above might be stored as:</p>
<pre><code class="language-json">{
  "message": "Order creation failed for 48291 on POST /orders after 3.2s",
  "CustomerId": 48291,
  "Endpoint": "POST /orders",
  "Duration": 3.2,
  "Exception": "TimeoutException"
}
</code></pre>
<p>The payoff is searchability. With plain-text logs, finding every failure for one customer means fuzzy text matching and luck. With structured logs, your monitoring system can run a precise query like <code>CustomerId = 48291 AND Exception = TimeoutException</code> and filter millions of entries in seconds. Libraries like Serilog, or the built-in <code>ILogger</code> in .NET, support this out of the box.</p>
<p>The goal isn't simply to record errors. The goal is to provide enough context that someone investigating the issue can immediately begin asking the right questions.</p>
<p>There's a catch, though. Great logs are worthless if you can't find them.</p>
<p>In self-managed setups, logs are scattered across servers, and teams end up building and babysitting their own aggregation pipelines just to make logs searchable. That's engineering time spent on plumbing, not on the product.</p>
<p>If your team maintains its own log shipping infrastructure, it's worth asking: why are we still doing this ourselves?</p>
<h2 id="heading-metrics-reveal-trends">Metrics Reveal Trends</h2>
<p>Logs explain individual events while metrics explain overall system behavior.</p>
<p>Suppose users report that your application becomes slow every afternoon. Reading thousands of log entries may not reveal anything unusual.</p>
<p>A metrics dashboard, however, might immediately show that CPU usage spikes above 90%, memory consumption steadily increases throughout the day, database latency doubles after lunch, and HTTP error rates climb sharply during peak traffic.</p>
<p>Let's make that concrete with the most common open-source setup: <a href="https://prometheus.io/">Prometheus</a> for collecting metrics and <a href="https://grafana.com/">Grafana</a> for visualizing them.</p>
<p>The workflow has three parts. First, your application exposes its metrics. Most frameworks have a library for this. In ASP.NET Core, adding the <code>prometheus-net</code> package and one line of configuration publishes a <code>/metrics</code> endpoint that reports counters like request totals, response durations, and error counts.</p>
<p>Second, a Prometheus server scrapes that endpoint every few seconds and stores the values as time series.</p>
<p>Third, Grafana turns those time series into dashboards.</p>
<p>Once that's in place, investigating the "slow every afternoon" report stops being guesswork. You open Grafana, set the time range to the last three days, and run a query like this against Prometheus:</p>
<pre><code class="language-plaintext">rate(http_request_duration_seconds_sum[5m])
/ rate(http_request_duration_seconds_count[5m])
</code></pre>
<p>That expression plots your average request duration over time. If the graph shows latency climbing every day between 1 p.m. and 4 p.m., you've confirmed the pattern in about a minute. Adding a second panel that plots CPU usage or database connection counts on the same time axis tells you which resource degrades first, and that's your suspect.</p>
<p>Those observations immediately narrow your investigation. Instead of wondering where to start, you now know exactly when the problem begins and which component is under stress.</p>
<p>Metrics transform isolated failures into recognisable patterns.</p>
<p>But that dashboard doesn't build itself. Someone has to install the agents, configure the exporters, size the time-series database, and keep the whole monitoring stack alive.</p>
<p>In many teams, the monitoring system itself becomes another production system that fails and needs debugging. Monitoring your monitoring is the infrastructure tax at its most absurd, and it's a strong signal that your team is carrying operational weight it never needed to.</p>
<h2 id="heading-distributed-tracing-connects-every-service">Distributed Tracing Connects Every Service</h2>
<p>Modern applications rarely consist of a single application talking to a single database.</p>
<p>A customer request may travel through an API gateway, authentication service, order service, payment processor, inventory system, cache, message queue, and database before returning a response.</p>
<p>When something fails, which service caused the delay?</p>
<p>Distributed tracing answers that question. A trace records the complete lifecycle of an individual request as it moves through your architecture. Each unit of work within the trace, like one service call or one database query, is called a <strong>span</strong>, and every span records when it started and how long it took.</p>
<p>Here's what a real trace looks like when viewed in a tool like <a href="https://www.jaegertracing.io/">Jaeger</a> or Zipkin. A customer reports that checkout is timing out, you look up the trace for their request ID, and you see a waterfall like this:</p>
<pre><code class="language-plaintext">Trace 8f3ac21 — POST /checkout — total: 4.61s

api-gateway            ████                                    45ms
  auth-service         ██                                      38ms
  order-service        ████████████████████████████████████  4.51s
    inventory-db query ██████████████████████████████████    4.29s  ⚠
    payment-api        ███                                    210ms
  response             █                                       12ms
</code></pre>
<p>Reading it takes seconds. The request spent 4.29 of its 4.61 seconds inside a single inventory database query. The gateway, auth service, and payment API are all healthy. Nobody needs to investigate them, and nobody needs to guess.</p>
<p>Under the hood, this works because the first service assigns the request a unique trace ID and passes it along in a header with every downstream call. Each service records its spans against that same ID, so the tracing backend can stitch the full journey back together.</p>
<p>The open standard for all of this is <a href="https://opentelemetry.io/">OpenTelemetry</a>, which has instrumentation libraries for every major language, and in many frameworks enabling it is a few lines of setup rather than manual code changes.</p>
<p>Without tracing, engineers often investigate the wrong service for hours. With tracing, the slowest or failing component is usually visible within seconds.</p>
<p>The problem is that rolling out tracing yourself is a project, not a checkbox. Instrumenting every service, deploying collectors, and storing trace data all take real engineering effort, which is why so many teams that know they need tracing still don't have it.</p>
<p>When observability is something you assemble rather than something your platform provides, it tends to remain permanently on the roadmap while incidents keep arriving on schedule.</p>
<h2 id="heading-reproduce-production-as-closely-as-possible">Reproduce Production as Closely as Possible</h2>
<p>Sometimes logs and traces aren't enough. Eventually you'll need to recreate the production environment.</p>
<p>That doesn't necessarily mean copying your production database onto your laptop. Instead, you'll want to identify the differences between environments.</p>
<ul>
<li><p>Is production running Linux while developers use Windows or macOS?</p>
</li>
<li><p>Does production use Redis while development does not?</p>
</li>
<li><p>Are different runtime versions installed?</p>
</li>
<li><p>Are requests routed through a <a href="https://www.fortinet.com/resources/cyberglossary/reverse-proxy">reverse proxy</a>?</p>
</li>
<li><p>Does the production process handle significantly larger datasets?</p>
</li>
<li><p>Does production receive hundreds of concurrent requests while development receives only one?</p>
</li>
</ul>
<p>Each difference becomes a potential explanation for the bug.</p>
<p>How do you actually close those gaps? A few techniques cover most of them:</p>
<h3 id="heading-containerize-the-application">Containerize the Application</h3>
<p>If production runs your app in a container, run the <em>same image</em> locally and in staging. This single step eliminates operating system, runtime version, and dependency differences at once, because the container carries its environment with it.</p>
<h3 id="heading-define-infrastructure-and-configuration-as-code">Define Infrastructure and Configuration as Code</h3>
<p>Services like Redis, the reverse proxy, and their settings should come from checked-in configuration (a <code>docker-compose.yml</code>, Kubernetes manifests, or Terraform) rather than manual setup.</p>
<p>When staging and production are generated from the same files, they can't quietly disagree. When you need to know whether production sits behind a reverse proxy or what runtime it uses, you read it from the config instead of asking whoever set up the server.</p>
<h3 id="heading-make-the-data-realistic">Make the Data Realistic</h3>
<p>You rarely need real production data, and for privacy reasons you usually shouldn't use it. What you need is data with production's <em>shape</em>: similar volume, and similar messiness.</p>
<p>Seed staging with a few million generated rows, and include the awkward cases, like names with accents and emojis, null-heavy records, and very long strings.</p>
<h3 id="heading-simulate-production-traffic">Simulate Production Traffic</h3>
<p>A bug that only appears under a hundred concurrent requests will never show up when you test one request at a time. Load-testing tools like <a href="https://k6.io/">k6</a> or JMeter let you replay realistic concurrency against staging with a short script, which is often what finally reproduces race conditions and connection pool exhaustion.</p>
<p>The closer your staging environment resembles production, the more likely you are to reproduce production-only failures before customers encounter them.</p>
<p>Notice, again, where the effort goes. Keeping staging faithful to production is a permanent maintenance job when both environments are hand-built, because hand-built environments drift the moment someone applies a patch to one and forgets the other.</p>
<p>Teams that get environment parity for free, because every environment is generated from the same configuration, simply have fewer production-only bugs to chase in the first place.</p>
<h2 id="heading-isolate-environmental-variables">Isolate Environmental Variables</h2>
<p>One of the most effective debugging techniques is changing only one variable at a time.</p>
<p>Imagine your application fails only in production. Potential differences include operating system versions, database engines, container configuration, environment variables, memory limits, network latency, or infrastructure settings.</p>
<p>Instead of modifying several variables simultaneously, test each one individually.</p>
<p>Here's what that looks like in practice. Suppose an API endpoint crashes in production but works locally, and you've identified three differences: production runs PostgreSQL 16 while you develop against 15, production caps the container at 512 MB of memory, and production sets <code>ENVIRONMENT=production</code>.</p>
<p>Don't change all three at once. Test them one at a time, keeping everything else identical:</p>
<pre><code class="language-bash"># Test 1: only the database version changes
docker run -d -p 5432:5432 postgres:16
# → run the failing request. Still works? Postgres is cleared. Revert to 15.

# Test 2: only the memory limit changes
docker run --memory=512m my-app
# → run the failing request. Crashes with an OutOfMemoryError? Found it.
</code></pre>
<p>If the bug appears in test 2 and only test 2, you've found your cause, and just as importantly, you've <em>cleared</em> the other suspects. Had you changed the database version and the memory limit together and seen the crash, you'd still have to untangle which one was responsible.</p>
<p>This disciplined approach often identifies the real cause much faster than random experimentation.</p>
<p>It's also worth pausing on that list of variables. Almost every item on it exists only because your team owns the infrastructure underneath the application. The fewer knobs you personally manage, the fewer variables you'll ever need to isolate.</p>
<h2 id="heading-a-simple-production-only-bug">A Simple Production-only Bug</h2>
<p>Consider this ASP.NET Core endpoint:</p>
<pre><code class="language-csharp">app.MapGet("/discount", () =&gt;
{
    string region = Environment.GetEnvironmentVariable("REGION");

    if (region.ToLower() == "eu")
        return Results.Ok("20% discount");

    return Results.Ok("10% discount");
});
</code></pre>
<p>Everything works perfectly during development.</p>
<p>Then customers begin reporting HTTP 500 errors in production.</p>
<p>Eventually the logs reveal this exception:</p>
<pre><code class="language-plaintext">NullReferenceException
</code></pre>
<p>The issue isn't difficult once you know where to look.</p>
<p>The production deployment forgot to define the <code>REGION</code> environment variable. Calling <code>ToLower()</code> on a null value immediately crashes the request.</p>
<p>The fix is straightforward:</p>
<pre><code class="language-csharp">string region = Environment.GetEnvironmentVariable("REGION") ?? "US";

if (region.Equals("EU", StringComparison.OrdinalIgnoreCase))
    return Results.Ok("20% discount");
</code></pre>
<p>The lesson isn't just about null checking. It's about understanding that production-only bugs are frequently caused by configuration differences rather than faulty business logic.</p>
<p>Without useful logs, developers might spend hours reviewing application code while completely overlooking the deployment configuration.</p>
<p>And step back one level further: this entire class of bug exists because a human had to remember to set a variable on a machine. Configuration drift isn't a coding failure, it's an operational failure, and it's the direct product of managing deployment configuration by hand.</p>
<p>When you find yourself writing runbooks to remind people which variables to set on which servers, that's another "why are we still doing this ourselves?" moment worth taking seriously.</p>
<h2 id="heading-verify-the-deployment-itself">Verify the Deployment Itself</h2>
<p>Not every production issue originates from your source code.</p>
<p>Deployment problems are surprisingly common.</p>
<ul>
<li><p>A container image may not have been updated.</p>
</li>
<li><p>A configuration file might be missing.</p>
</li>
<li><p>A database migration may have failed.</p>
</li>
<li><p>An environment variable could contain an incorrect value.</p>
</li>
<li><p>A required secret may not have been deployed.</p>
</li>
<li><p>A rollback might have restored an older application version without anyone noticing.</p>
</li>
</ul>
<p>Before assuming your code contains a bug, confirm that production is actually running the version you intended to deploy.</p>
<p>Many incidents have been resolved simply by discovering that the wrong build was running.</p>
<p>Every single one of those production failures is a failure of infrastructure process, not of programming. They happen in homegrown deployment pipelines because homegrown pipelines have exactly as much verification as someone found time to build.</p>
<p>If your team can't answer "what version is running right now?" in one glance, your deployment system is generating bugs for you to debug later.</p>
<h2 id="heading-do-you-actually-need-a-paas">Do You Actually Need a PaaS?</h2>
<p>Before we look at how a PaaS changes debugging, an honest question deserves an honest answer: does every team need one?</p>
<p>No. A PaaS is a trade. You hand over infrastructure control and pay a platform premium, and in exchange you stop spending engineering time on servers, pipelines, and observability plumbing. Whether that trade is worth it depends on your situation, and there are legitimate reasons to stay off a platform:</p>
<ul>
<li><p><strong>You have unusual infrastructure requirements:</strong> GPU workloads, custom kernels, exotic networking, or software that needs specific hardware may simply not fit a platform's constraints.</p>
</li>
<li><p><strong>Compliance or data residency rules demand full control:</strong> Some regulated industries need to dictate exactly where and how everything runs.</p>
</li>
<li><p><strong>You operate at a scale where the economics flip:</strong> For very large workloads, the per-resource premium of a PaaS can exceed the cost of a dedicated platform team. That's why companies at massive scale build internal platforms, though note what they build: essentially their own PaaS.</p>
</li>
<li><p><strong>Infrastructure <em>is</em> your product:</strong> If you sell hosting, networking, or infrastructure tooling, operating it yourself is the business.</p>
</li>
</ul>
<p>For everyone else, the evaluation comes down to a few questions worth asking:</p>
<ul>
<li><p>When production breaks, how much of the first hour goes to <em>finding</em> information versus <em>acting</em> on it?</p>
</li>
<li><p>Is anyone on the team maintaining log pipelines, monitoring stacks, or deployment scripts as a side job on top of the product work they were hired for?</p>
</li>
<li><p>Can you say, in one glance, exactly what version is running in production right now?</p>
</li>
<li><p>When did you last lose a day to environment drift, like a bug caused by a server, config, or variable that didn't match?</p>
</li>
</ul>
<p>If those answers make you wince, and for most small-to-medium product teams they do, you're paying the infrastructure tax without getting anything for it. The signal isn't your company's size, but where your engineering hours are going. A two-person startup and a fifty-person product team both come out ahead when nobody is babysitting servers.</p>
<p>And if you're currently unsure whether you need one, you probably do. Teams with a real reason to run their own infrastructure tend to know exactly what that reason is.</p>
<h2 id="heading-why-debugging-is-easier-on-a-paas">Why Debugging is Easier on a PaaS</h2>
<p>The hardest part of diagnosing production bugs often isn't finding the root cause, it's finding the information you need to investigate.</p>
<p>In a traditional infrastructure setup, logs are scattered across multiple virtual machines, containers, load balancers, and background workers. When an application scales horizontally, a single customer request may touch several servers before it completes. Developers often spend more time SSHing into machines, locating log files, and correlating timestamps than actually debugging the problem.</p>
<p>That time is the infrastructure tax coming due. Every hour spent assembling evidence during an incident is an hour of downtime your team chose, months earlier, when it decided to own and operate all of that machinery itself.</p>
<p>A <a href="https://www.freecodecamp.org/news/my-team-s-experience-moving-from-aws-to-a-paas/">Platform as a Service (PaaS)</a> changes that experience completely.</p>
<p>Instead of treating each server as an individual machine to manage, a PaaS treats your application as a single service. Logs from every instance are automatically aggregated into one place, metrics are collected continuously, and health checks are built into the platform. Whether your application is running on one container or fifty, you view it through a single dashboard instead of dozens of terminals.</p>
<p>When a production issue occurs, you can immediately answer important questions.</p>
<ul>
<li><p>Did the problem begin after the latest deployment?</p>
</li>
<li><p>Is every application instance failing or only one?</p>
</li>
<li><p>Did CPU or memory usage spike before the application crashed?</p>
</li>
<li><p>Which release introduced the regression?</p>
</li>
</ul>
<p>Instead of collecting this information manually, the platform already has it available.</p>
<p>Many PaaS tools also maintain deployment history, making it easy to compare application behavior before and after each release. If error rates suddenly increase after version 2.8.1 is deployed, the relationship becomes obvious. Rolling back to a previous deployment often takes only a few minutes, dramatically reducing downtime.</p>
<p>Infrastructure consistency is another major advantage.</p>
<p>Applications deployed through a PaaS are created from the same deployment configuration every time. Developers don't have to wonder whether one server has an outdated runtime, a missing dependency, an incorrect operating system package, or a forgotten environment variable. Consistent environments eliminate an entire category of production-only bugs before they happen.</p>
<p>Remember the <code>REGION</code> bug from earlier? On a platform where configuration is declared once and applied everywhere, that bug never ships.</p>
<p>Perhaps the biggest benefit is faster incident response.</p>
<p>During an outage, engineering teams shouldn't waste valuable time gathering evidence from multiple systems. Centralized logging, built-in monitoring, distributed tracing, deployment history, and health checks allow them to begin investigating immediately.</p>
<p>That translates directly into a lower Mean Time to Resolution (MTTR), shorter outages, and a better experience for both developers and customers.</p>
<h2 id="heading-build-applications-that-are-easy-to-debug">Build Applications That Are Easy to Debug</h2>
<p>Production bugs are inevitable. Complex systems fail in unexpected ways, no matter how experienced the engineering team is.</p>
<p>The difference between mature engineering organizations and everyone else isn't whether bugs occur. It's how quickly they can understand and resolve them.</p>
<p>Write meaningful logs that provide context instead of generic error messages. Collect metrics continuously so performance trends are visible before users complain. Instrument your applications with distributed tracing so requests can be followed across services. Keep staging environments as close to production as possible, and treat infrastructure configuration as carefully as application code.</p>
<p>Just as importantly, choose a platform that makes debugging easier instead of harder.</p>
<p>Teams relying on manually managed servers often spend the first hour of an incident simply gathering logs and connecting to machines. Teams running on a modern PaaS begin with the evidence already in front of them. They can correlate deployments with error spikes, inspect logs from every application instance, review infrastructure metrics, and trace failing requests without leaving a single dashboard.</p>
<p>Be honest about which team yours is. If your engineers maintain log pipelines, monitoring stacks, staging parity, and deployment scripts on top of the product they were hired to build, you're paying the infrastructure tax in its most expensive currency: incident time. Unless operating infrastructure is your business, it's overhead that you can hand to a platform.</p>
<p>A PaaS won't prevent every production bug, but it removes much of the operational complexity that makes those bugs difficult to diagnose. That means less time hunting for information, faster root-cause analysis, quicker recovery during incidents, and more time focused on building software instead of managing infrastructure.</p>
<p>When the next production issue appears, and it inevitably will, you'll spend less time asking, "Why can't I reproduce this?" and more time asking the better question: "Why were we ever doing all of this ourselves?"</p>
<p>Hope you enjoyed this article. You can <a href="https://linkedin.com/in/manishmshiva">connect with me on LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The New Agency Stack: How Dev Shops Use Claude, Cursor, and Copilot in Production ]]>
                </title>
                <description>
                    <![CDATA[ Two years ago, AI coding tools were a curiosity. Agencies let junior devs experiment with them on internal tools and side projects, the kind of work where nothing broke if the code was bad. Client wor ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-new-agency-stack-how-dev-shops-use-claude-cursor-and-copilot-in-production/</link>
                <guid isPermaLink="false">6a638870a4de2a05a49152ca</guid>
                
                    <category>
                        <![CDATA[ ai-agent ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Fri, 24 Jul 2026 15:44:48 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/a02d2c69-a2af-476c-b594-4bf03671ad48.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Two years ago, AI coding tools were a curiosity. Agencies let junior devs experiment with them on internal tools and side projects, the kind of work where nothing broke if the code was bad.</p>
<p>Client work stayed handwritten. Nobody was betting a deadline on autocomplete.</p>
<p>That era is over. The same tools now sit at the centre of how software gets built. Dev shops that once quoted six months for an MVP now quote six weeks, and clients have started asking why anyone would quote more.</p>
<p>The tools changed fast. The workflow around them changed just as much: new review habits, new pricing models, and new roles for senior engineers who spend less time typing and more time judging what the machine produced.</p>
<p>This article examines how modern agencies use these tools in production. Not the marketing version, where AI writes flawless code while everyone sips coffee. The real one, with code review, guardrails, failed experiments, and humans still in charge of every line that ships.</p>
<h3 id="heading-what-well-cover">What We'll Cover:</h3>
<ul>
<li><p><a href="#heading-why-agencies-moved-first">Why Agencies Moved First</a></p>
</li>
<li><p><a href="#heading-the-three-layers-of-the-stack">The Three Layers of the Stack</a></p>
</li>
<li><p><a href="#heading-what-production-use-actually-looks-like">What Production Use Actually Looks Like</a></p>
</li>
<li><p><a href="#heading-the-numbers-behind-the-shift">The Numbers Behind the Shift</a></p>
</li>
<li><p><a href="#heading-how-to-vet-an-ai-powered-agency">How to Vet an "AI-Powered" Agency</a></p>
</li>
<li><p><a href="#heading-where-this-goes-next">Where This Goes Next</a></p>
</li>
</ul>
<h2 id="heading-why-agencies-moved-first"><strong>Why Agencies Moved First</strong></h2>
<p>Product teams inside big companies move slowly. They have legacy code, compliance rules, and long approval chains. Agencies have none of that. They start fresh projects every month. That makes them the perfect test bed for AI-assisted work.</p>
<p>There's also a business reason. Agencies bill for outcomes. If a tool cuts build time by 40 percent, that's a margin. Or it's a lower price that wins the deal. Either way, the incentive to adopt is strong.</p>
<p>The shift shows up in how agencies now describe themselves. "AI-accelerated development" has become a core service line across the industry. The pitch is simple: senior engineers use AI to move fast, and every line still gets human review. That framing is now the standard playbook.</p>
<h2 id="heading-the-three-layers-of-the-stack"><strong>The Three Layers of the Stack</strong></h2>
<p>Most agency stacks now have three layers. Each tool plays a different role.</p>
<p>The first layer is the chat assistant. This is where <a href="https://www.anthropic.com/claude">Claude</a> and ChatGPT live. Engineers use them for planning, architecture questions, and debugging. A senior dev might paste in an error log and get three likely causes in seconds. Or they might describe a feature and ask for edge cases they haven't thought of. This layer is about thinking, not typing.</p>
<p>The second layer is the AI-native editor. <a href="https://cursor.com/">Cursor</a> leads here. It wraps a full code editor around a language model. The model sees your whole codebase, not just one file. Engineers use it to write new features, refactor old code, and generate tests. Agentic modes can now take a task and work through it across many files while the engineer reviews each step.</p>
<p>The third layer is the inline assistant. <a href="https://github.com/features/copilot">GitHub Copilot</a> is the best-known. It lives inside the editor and completes code as you type. It handles the boring parts: boilerplate, repeated patterns, or standard functions. It's the least dramatic tool of the three, but it runs all day, every day, and the small savings add up.</p>
<p>Most shops use all three layers at once. The chat assistant plans, the AI editor builds, and the inline assistant fills the gaps.</p>
<h2 id="heading-what-production-use-actually-looks-like"><strong>What Production Use Actually Looks Like</strong></h2>
<p>Here's where the hype meets reality. AI writes a lot of code now, but agencies that ship to real clients don't let it ship alone.</p>
<p>The common pattern is a tight loop. An engineer breaks a feature into small tasks. The AI drafts the code for each task. The engineer reads every line, fixes what's wrong, and runs the tests. Then the code goes through normal pull request review, just like human-written code always has.</p>
<p>The teams that get burned are the ones that skip the review step. AI code often looks right and runs fine in a demo. The problems hide deeper. Weak error handling. Security holes. Database queries that fall over at scale. A demo doesn't catch these, but a senior engineer does.</p>
<p>Product companies that build in the open show the same pattern. <a href="https://posthog.com/">PostHog</a>, the open-source product analytics platform, has written publicly about how its engineers use AI tools in their daily workflow. The takeaway from teams like this is consistent: AI speeds up the draft, but a human owns the merge. Every change still lands through the same pull request process, with a named engineer accountable for it.</p>
<p>This has created a new line of work: fixing AI-built apps. <a href="https://www.empat.tech/">Empat</a>, a dev shop with offices in San Francisco, London, and Kyiv, calls its version "vibecode rescue," a service for founders who built an app with AI tools and hit a wall.</p>
<p>The app works until it doesn't. Then someone has to untangle the code, add tests, and make it stable. The rise of this service says a lot. AI makes building easy. It doesn't make building well easy.</p>
<h2 id="heading-the-numbers-behind-the-shift"><strong>The Numbers Behind the Shift</strong></h2>
<p>The cost picture explains why clients care. An agency MVP used to take four to six months. Now, agencies quote six to twelve weeks for the same scope, often starting around $30,000. Fixed-scope, fixed-price offers are back in fashion because AI makes timelines more predictable for well-defined work.</p>
<p>Speed isn't the only gain. AI tools are strong at the tasks engineers avoid: writing tests, documenting code, and updating old dependencies. Codebases built this way often ship with better test coverage than the hand-built ones from five years ago, simply because tests cost so little to produce now.</p>
<p>But the numbers cut both ways. Token costs for heavy agentic use are real. A team running AI agents all day can spend hundreds of dollars per engineer per month on model usage. For agencies, that is still a bargain against salary costs. It is, however, a new line item that didn't exist in 2023.</p>
<h2 id="heading-how-to-vet-an-ai-powered-agency"><strong>How to Vet an "AI-Powered" Agency</strong></h2>
<p>Almost every agency now claims to use AI. The claim alone tells you nothing. If you're hiring one, a few questions cut through the noise.</p>
<p>Ask who reviews the AI's output. The right answer names specific senior engineers and a real pull request process. A vague answer about "quality checks" is a warning sign.</p>
<p>Ask about testing. AI-generated code needs automated tests more than human code does, because it fails in less predictable ways. A good shop will talk about test coverage without being prompted.</p>
<p>Ask what happens when the AI gets it wrong. Every experienced team has stories here. A team with no stories has not shipped much.</p>
<p>Finally, check the track record the old-fashioned way. Review platforms like <a href="https://clutch.co/">Clutch</a> collect verified client feedback on agencies, including project budgets and outcomes. AI has changed how code gets written. It hasn't changed the fact that past client results are the best predictor of future ones.</p>
<h2 id="heading-where-this-goes-next"><strong>Where This Goes Next</strong></h2>
<p>The current stack is already shifting. Agentic tools that plan and execute full tasks are replacing simple autocomplete. Some agencies now run AI agents overnight on well-scoped tickets and review the results in the morning. The engineer's job keeps moving up the stack: less typing, more judgment.</p>
<p>The agencies that win won't be the ones with the best tools. Everyone has the same tools. They'll be the ones with the best judgment about when to trust the tools and when to override them. That judgment lives in senior engineers, and it's why the "AI replaces developers" story keeps missing the mark. In production, AI hasn't replaced the engineer. It has made the good ones faster and the careless ones more dangerous.</p>
<p>For clients, the takeaway is simple. The new agency stack is real, and the speed gains are real. But the stack is only as good as the people running it. Ask hard questions, check the reviews, and make sure a human is reading every line before it ships.</p>
<p>Hope you enjoyed this article. You can <a href="https://linkedin.com/in/manishmshiva">connect with me on LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How Programmatic Advertising Works ]]>
                </title>
                <description>
                    <![CDATA[ Most tutorials on programmatic advertising stop at the web banner. That's a shame, because the idea gets far more interesting once you follow it off the screen and into the physical world. If you've n ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-programmatic-advertising-works/</link>
                <guid isPermaLink="false">6a614617166ef0e401b18d80</guid>
                
                    <category>
                        <![CDATA[ Advertising ]]>
                    </category>
                
                    <category>
                        <![CDATA[ automation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Wed, 22 Jul 2026 22:37:11 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/ead3788a-52c2-4821-b5c9-1c626c50d375.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Most tutorials on <a href="https://advertising.amazon.com/blog/programmatic-advertising#1">programmatic advertising</a> stop at the web banner. That's a shame, because the idea gets far more interesting once you follow it off the screen and into the physical world.</p>
<p>If you've never worked in advertising, don't worry. You don't need any ad industry background to follow along. If you can read basic Python, you have everything you need.</p>
<p>The advertising part is just the setting. The real subject is a skill you'll use everywhere: taking a messy slice of the real world and turning it into data that software can act on.</p>
<p>In this article, you'll learn what programmatic advertising is and why it worked so well on the web. You'll see why bringing it to a billboard is really a data modeling problem, and you'll build small Python models for each step.</p>
<h3 id="heading-what-well-cover">What We'll Cover:</h3>
<ul>
<li><p><a href="#heading-what-is-programmatic-advertising">What Is Programmatic Advertising?</a></p>
</li>
<li><p><a href="#heading-why-the-web-made-programmatic-easy">Why the Web Made Programmatic Easy</a></p>
</li>
<li><p><a href="#heading-the-billboard-problem">The Billboard Problem</a></p>
</li>
<li><p><a href="#heading-step-1-resolve-entities">Step 1: Resolve Entities</a></p>
</li>
<li><p><a href="#heading-step-2-model-location-as-computed-context">Step 2: Model Location as Computed Context</a></p>
</li>
<li><p><a href="#heading-step-3-represent-availability-as-a-schedule-not-a-boolean">Step 3: Represent Availability as a Schedule, Not a Boolean</a></p>
</li>
<li><p><a href="#heading-step-4-express-price-as-a-function-not-a-number">Step 4: Express Price as a Function, Not a Number</a></p>
</li>
<li><p><a href="#heading-putting-it-together">Putting It Together</a></p>
</li>
<li><p><a href="#heading-an-exercise-to-build-the-intuition">An Exercise to Build the Intuition</a></p>
</li>
<li><p><a href="#heading-the-takeaway">The Takeaway</a></p>
</li>
</ul>
<h2 id="heading-what-is-programmatic-advertising">What Is Programmatic Advertising?</h2>
<p>Advertising has two sides. A publisher, such as a news site, has ad space to fill. And an advertiser, such as a shoe brand, wants to fill it. For decades, connecting the two meant phone calls, emails, and paperwork.</p>
<p>Programmatic advertising replaces that manual process with software. No human negotiates the placement. A system looks at an ad slot and decides, in milliseconds, whether to buy it and at what price.</p>
<p>Here's how it works when you open a web page. The page tells an ad exchange that a slot is open, along with some context about the page and the viewer. Advertisers' systems bid on the slot in a live auction. The winning ad appears before the page finishes loading. This process is called <a href="https://en.wikipedia.org/wiki/Real-time_bidding">real-time bidding</a>, and it happens billions of times a day.</p>
<p>Two quick terms will help. Inventory means the ad space a seller has to offer. An impression means one view of an ad by one person.</p>
<p>On the web, this model arrived fast and felt almost effortless. It's worth understanding why.</p>
<h2 id="heading-why-the-web-made-programmatic-easy">Why the Web Made Programmatic Easy</h2>
<p>The web made programmatic easy by accident. Every web ad slot came pre-structured. It had an address, meaning a URL and a position on the page. It sat inside a document with a known shape, the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model">Document Object Model</a>. And it could report back whether an ad had loaded and been seen.</p>
<p>The whole environment was machine-readable from birth, because machines were already serving it. When automated buying showed up, it had a clean surface to work against. The medium had already done the hard modeling work.</p>
<p>Keep that in mind. It's the key to the whole lesson.</p>
<h2 id="heading-the-billboard-problem">The Billboard Problem</h2>
<p>Now point the same idea at a billboard. None of that convenient structure exists.</p>
<p>A physical sign doesn't announce where it is or which way it faces. It doesn't say what it costs this week or whether it's even available. For most of its history, that information lived in rate cards and salespeople's memories, not in anything a program could query.</p>
<p>Here's the insight. Out-of-home advertising, the industry term for billboards, transit posters, and public screens, didn't lag the web because it was a weaker medium. It lagged because it had no machine-readable interface. The audience was always there. The structured data was not.</p>
<p>So the real work of bringing programmatic to the physical world isn't clever bidding logic. It's data modeling.</p>
<p>Let's make that concrete. There are four steps. Each one maps to a pattern you'll see in many other engineering problems.</p>
<h2 id="heading-step-1-resolve-entities">Step 1: Resolve Entities</h2>
<p>The same billboard often shows up in several vendors' datasets. Each vendor gives it a different name and slightly different coordinates. Before you can do anything else, one physical object has to become one record. This is known as <a href="https://en.wikipedia.org/wiki/Record_linkage">record linkage</a>, here with a geographic twist.</p>
<p>A simple approach: treat two records as the same panel if they sit close together and share a similar name. To measure the distance between two coordinates, you can use the <a href="https://en.wikipedia.org/wiki/Haversine_formula">haversine formula</a>.</p>
<pre><code class="language-python">from math import radians, sin, cos, asin, sqrt

def haversine_m(lat1, lon1, lat2, lon2):
    """Distance between two coordinates in meters."""
    lat1, lon1, lat2, lon2 = map(radians, [lat1, lon1, lat2, lon2])
    a = sin((lat2 - lat1) / 2) ** 2 + \
        cos(lat1) * cos(lat2) * sin((lon2 - lon1) / 2) ** 2
    return 6371000 * 2 * asin(sqrt(a))

def same_panel(a, b, max_distance_m=25):
    close = haversine_m(a["lat"], a["lon"], b["lat"], b["lon"]) &lt;= max_distance_m
    similar_name = a["name"].lower().split()[0] == b["name"].lower().split()[0]
    return close and similar_name

vendor_a = {"name": "I-95 North Bulletin", "lat": 25.7907, "lon": -80.1300}
vendor_b = {"name": "I-95 Bulletin #4421", "lat": 25.7908, "lon": -80.1301}

print(same_panel(vendor_a, vendor_b))  # True – one billboard, one record
</code></pre>
<p>Real systems use fuzzier matching and more signals, but the principle is the same. Entity resolution comes first, or every later step counts the same billboard twice.</p>
<h2 id="heading-step-2-model-location-as-computed-context">Step 2: Model Location as Computed Context</h2>
<p>A coordinate is not an audience. To make a panel useful to a buying system, you have to represent it as a point with an orientation. Then you estimate who actually passes it by joining it against road and traffic data.</p>
<p>The useful value is computed, not given:</p>
<pre><code class="language-python">def estimate_impressions(panel, traffic_by_road):
    """Estimate daily impressions from road traffic data."""
    daily_vehicles = traffic_by_road[panel["road_id"]]
    # Only traffic moving toward the panel's face can see it
    facing_share = 0.5
    avg_occupancy = 1.4  # people per vehicle
    return int(daily_vehicles * facing_share * avg_occupancy)

panel = {"id": "P-4421", "road_id": "I-95-N", "facing": "south"}
traffic = {"I-95-N": 120000}

print(estimate_impressions(panel, traffic))  # 84000
</code></pre>
<p>Notice what happened. The raw record was just a point on a map. It got enriched into something a buyer can reason about: 84,000 estimated daily impressions. This pattern shows up everywhere in data work. A raw record plus outside data equals a useful field.</p>
<h2 id="heading-step-3-represent-availability-as-a-schedule-not-a-boolean">Step 3: Represent Availability as a Schedule, Not a Boolean</h2>
<p>A web ad slot is either open right now or it isn't. In code, that's a boolean: a value that is simply true or false. A billboard gets booked in date ranges, and its state changes underneath you. Inventory gets held, booked, and released. You need live data, not a snapshot.</p>
<pre><code class="language-python">from datetime import date

class PanelSchedule:
    def __init__(self):
        self.bookings = []  # list of (start, end) tuples

    def book(self, start, end):
        if not self.is_available(start, end):
            raise ValueError("Panel not available for that range")
        self.bookings.append((start, end))

    def is_available(self, start, end):
        return all(end &lt; b_start or start &gt; b_end
                   for b_start, b_end in self.bookings)

schedule = PanelSchedule()
schedule.book(date(2026, 8, 1), date(2026, 8, 14))

print(schedule.is_available(date(2026, 8, 10), date(2026, 8, 20)))  # False
print(schedule.is_available(date(2026, 8, 15), date(2026, 8, 31)))  # True
</code></pre>
<p>The lesson carries over. Whenever you model the real world, ask whether a value is truly fixed. Often it's state that changes over time. Availability, stock levels, and seat maps are all schedules pretending to be booleans.</p>
<h2 id="heading-step-4-express-price-as-a-function-not-a-number">Step 4: Express Price as a Function, Not a Number</h2>
<p>The rate card says one number. Reality prices by date, demand, and how much inventory is left:</p>
<pre><code class="language-python">def price_for(base_rate, start, weeks_out, occupancy):
    """Price a booking based on lead time and demand."""
    demand_multiplier = 1 + occupancy          # busier market, higher price
    urgency_discount = 0.9 if weeks_out &gt; 8 else 1.0  # reward early booking
    return round(base_rate * demand_multiplier * urgency_discount, 2)

print(price_for(base_rate=3000, start=date(2026, 12, 1),
                weeks_out=19, occupancy=0.85))  # 4995.0
print(price_for(base_rate=3000, start=date(2026, 8, 1),
                weeks_out=2, occupancy=0.40))   # 4200.0
</code></pre>
<p>Once price is a function, software can compare thousands of panels and dates instantly. That's exactly what automated buying needs.</p>
<h2 id="heading-putting-it-together">Putting It Together</h2>
<p>You now have resolved entities, computed audience, live availability, and dynamic pricing. With that in place, <a href="https://www.adquick.com/guides/programmatic-dooh">programmatic digital out of home</a> advertising works in the physical world the same way it does online. Software can plan a campaign across physical screens, buy them automatically, adjust in near real time, and measure the result.</p>
<p>It was never really about the web. It was about whether the inventory had a schema, meaning a defined structure that tells software what each piece of data is. Once you give the physical world a schema, the automation follows.</p>
<h2 id="heading-an-exercise-to-build-the-intuition">An Exercise to Build the Intuition</h2>
<p>You don't need special access to practice this. Take any messy, location-based public dataset and rehearse the four steps. A good source is <a href="https://www.openstreetmap.org/">OpenStreetMap</a>, which offers free data on millions of real-world places.</p>
<p>First, resolve duplicates by merging records that describe the same real-world thing. Second, enrich each point with computed context instead of treating the raw record as complete. Third, model one field as state that changes over time rather than a fixed value. Fourth, wrap the result in a clean interface, such as a class or a small API, that something else could query.</p>
<p>You won't have built an ad platform, but you'll have practiced the exact skills that let automated buying reach a new field.</p>
<h2 id="heading-the-takeaway">The Takeaway</h2>
<p>A good abstraction survives contact with the real world.</p>
<p>When you first learn a concept in a tidy setting, it's easy to think the tidiness is part of the concept. It rarely is. You only find out how general an idea is when you drag it somewhere messy and watch it still work.</p>
<p>Programmatic buying, moved off the screen and onto a wall by a road, is one of the cleaner proofs of that. Keep an eye out for the same pattern elsewhere: a rich domain waiting on nothing but a schema.</p>
<p>Hope you enjoyed this article. You can <a href="https://linkedin.com/in/manishmshiva">connect with me on LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Evaluate AI Code Quality: A Practical Guide for Engineers ]]>
                </title>
                <description>
                    <![CDATA[ You asked the AI to write a function. It gave you something that looks right. It even runs. But is it actually good? Most engineers stop there. They see green and move on. That habit will quietly caus ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-evaluate-ai-code-quality-a-practical-guide-for-engineers/</link>
                <guid isPermaLink="false">6a60f285d0399316ddce21d2</guid>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Code Quality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ llm ]]>
                    </category>
                
                    <category>
                        <![CDATA[ clean code ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Wed, 22 Jul 2026 16:40:37 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/5e14329a-90ef-46e0-9ff9-a629c711c111.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>You asked the AI to write a function. It gave you something that looks right. It even runs. But is it actually good?</p>
<p>Most engineers stop there. They see green and move on. That habit will quietly cause you problems.</p>
<p>AI coding tools like <a href="https://github.com/features/copilot">GitHub Copilot</a>, <a href="https://www.cursor.com">Cursor</a>, and Claude are genuinely useful. But they're non-deterministic, meaning the same prompt can produce different outputs on different days.</p>
<p>They can produce code that's plausible-looking but subtly wrong, or code that works for the happy path but falls apart on edge cases. Without a system for evaluating what the AI gives you, you're essentially shipping untested third-party code and hoping for the best.</p>
<p>This guide walks you through a practical, beginner-friendly approach to evaluating AI-generated code, so you can use these tools with confidence instead of crossed fingers.</p>
<h3 id="heading-what-well-cover">What We'll Cover:</h3>
<ul>
<li><p><a href="#heading-why-ai-code-needs-its-own-evaluation-discipline">Why AI Code Needs Its Own Evaluation Discipline</a></p>
</li>
<li><p><a href="#heading-step-one-define-correctness-before-you-generate">Step One: Define Correctness Before You Generate</a></p>
</li>
<li><p><a href="#heading-step-two-build-a-golden-dataset">Step Two: Build a Golden Dataset</a></p>
</li>
<li><p><a href="#heading-step-three-measure-reliability-not-just-correctness">Step Three: Measure Reliability, Not Just Correctness</a></p>
</li>
<li><p><a href="#heading-step-four-review-for-what-tests-cant-catch">Step Four: Review for What Tests Can't Catch</a></p>
</li>
<li><p><a href="#heading-step-five-treat-prompt-changes-like-code-changes">Step Five: Treat Prompt Changes Like Code Changes</a></p>
</li>
<li><p><a href="#heading-the-mindset-that-makes-this-work">The Mindset That Makes This Work</a></p>
</li>
</ul>
<h2 id="heading-why-ai-code-needs-its-own-evaluation-discipline">Why AI Code Needs Its Own Evaluation Discipline</h2>
<p>When a human colleague writes code, you can ask them questions. You can read their commit history. You have context.</p>
<p>When an AI writes code, you have none of that. The output arrives fully formed, often with confident-sounding comments, and it's easy to assume competence where there may be none.</p>
<p>The other problem is that AI models are trained on vast amounts of public code, including bad public code. They can reproduce anti-patterns fluently. They can write code that passes a quick read but fails under real-world load, unusual inputs, or security scrutiny.</p>
<p>Evaluating AI code isn't about distrusting AI. It's about applying the same engineering discipline you would to any code that enters your codebase.</p>
<h2 id="heading-step-one-define-correctness-before-you-generate">Step One: Define Correctness Before You Generate</h2>
<p>The single most effective thing you can do is write your tests before you ask the AI to write the implementation. This is the spirit of test-driven development (<a href="https://martinfowler.com/bliki/TestDrivenDevelopment.html">TDD</a>), and it maps perfectly onto AI-assisted workflows.</p>
<p>When you define correctness upfront, you give yourself an objective measure the moment the code arrives. You're not eyeballing it. You're running it against a contract you wrote yourself.</p>
<p>Here's a simple example. Say you want an AI to write a function that parses a price string like <code>"$12.99"</code> and returns a float. Before prompting the AI, write this:</p>
<pre><code class="language-python">def test_parse_price():
    assert parse_price("$12.99") == 12.99
    assert parse_price("$0.00") == 0.0
    assert parse_price("$1,299.99") == 1299.99
    assert parse_price("") is None
    assert parse_price("free") is None
</code></pre>
<p>Now prompt the AI: <em>"Write a Python function called</em> <code>parse_price</code> <em>that takes a price string like</em> <code>$12.99</code> <em>or</em> <code>$1,299.99</code> <em>and returns a float. Return None for invalid input."</em></p>
<p>Run your tests immediately. The AI might pass four out of five. Now you know exactly what to fix and you didn't have to read a single line of implementation to find the gap.</p>
<h2 id="heading-step-two-build-a-golden-dataset">Step Two: Build a Golden Dataset</h2>
<p>A golden dataset is a small collection of inputs with known correct outputs. Think of it as a permanent test suite for any AI feature you build. You start with five or ten examples. You add to it whenever something breaks in production.</p>
<p>This becomes your regression set. Every time you tweak a prompt, upgrade a model, or refactor a pipeline, you run the golden dataset first. If anything breaks, you know immediately.</p>
<p>Here's what a golden dataset might look like for the price parser. A simple JSON file works fine:</p>
<pre><code class="language-json">[
  { "input": "$12.99",    "expected": 12.99,  "note": "basic case" },
  { "input": "$1,299.99", "expected": 1299.99, "note": "thousands separator" },
  { "input": "12.99",     "expected": 12.99,  "note": "missing dollar sign" },
  { "input": "$ 12.99",   "expected": 12.99,  "note": "space after symbol, from prod bug #142" },
  { "input": "€12.99",    "expected": null,   "note": "unsupported currency" },
  { "input": "free",      "expected": null,   "note": "non-numeric text" },
  { "input": "",          "expected": null,   "note": "empty string" }
]
</code></pre>
<p>Each entry is just an input, the correct output, and a short note on why it's there. A script loads the file, runs each input through your function or prompt, and compares results.</p>
<p>For a code-generation use case, the same idea scales up: a folder of input prompts paired with expected output files, diffed by a script. For data extraction, a CSV of sample inputs alongside expected parsed values.</p>
<p>So how do you decide what goes in? Three sources cover most of it.</p>
<p>First, the representative cases: the ordinary inputs your feature handles ninety percent of the time. Second, the boundary cases you can predict upfront, like empty strings, unusual formats, and inputs that should be rejected. Third, and most valuable, real failures.</p>
<p>Notice the <code>$ 12.99</code> entry above tagged with a production bug number. A user hit that input, the parser choked, and now it's in the dataset forever. That's the test: if an input broke something once, or plausibly could, it earns a permanent spot. If it's just a minor variation of a case you already cover, skip it and keep the dataset small enough to run on every change.</p>
<p>The key discipline is this: don't just fix the failing case. Add it to the golden dataset, fix it, and verify everything else still passes. This is how you stop the whack-a-mole problem where fixing one AI failure silently breaks three others.</p>
<h2 id="heading-step-three-measure-reliability-not-just-correctness">Step Three: Measure Reliability, Not Just Correctness</h2>
<p>AI outputs aren't deterministic. Correct once doesn't mean correct always. This is especially important if you're embedding AI into a product: a prompt that works 80% of the time will fail your users 20% of the time, and that's not acceptable in production.</p>
<p>The fix is to run your evaluation across multiple samples. Run the same prompt ten times and check how many outputs pass your tests. Tools like <a href="https://promptfoo.dev">promptfoo</a> make this easy to automate. You define your test cases in a config file, point it at your prompt, and it runs the evals and reports pass rates.</p>
<p>Here's what a simple promptfoo config looks like:</p>
<pre><code class="language-yaml">prompts:
  - "Parse the following price string and return only a float: {{input}}"

providers:
  - openai:gpt-4o

tests:
  - vars:
      input: "$12.99"
    assert:
      - type: equals
        value: "12.99"
  - vars:
      input: "$1,299.99"
    assert:
      - type: equals
        value: "1299.99"
  - vars:
      input: "free"
    assert:
      - type: equals
        value: "null"
</code></pre>
<p>Run this across ten iterations and you'll quickly see if your prompt is brittle. A 100% pass rate across ten runs gives you real confidence. A 70% rate tells you the prompt needs tightening before it goes anywhere near production.</p>
<h2 id="heading-step-four-review-for-what-tests-cant-catch">Step Four: Review for What Tests Can't Catch</h2>
<p>Tests tell you if code is correct. They don't tell you if it's readable, maintainable, or secure. After your automated checks pass, do a focused human review on three things.</p>
<p>The first is security. AI models can produce code with real vulnerabilities like SQL injection via string concatenation, missing input sanitization, and hardcoded credentials in examples it then forgets to flag. Run AI-generated code through a static analysis tool like <a href="https://bandit.readthedocs.io">Bandit</a> for Python or <a href="https://github.com/eslint-community/eslint-plugin-security">ESLint with a security plugin</a> for JavaScript as a baseline check.</p>
<p>The second is edge cases the AI didn't consider. Look at the test cases you wrote and ask: what did I not cover? Empty lists, null values, very large inputs, concurrent calls, and so on might not be handled by AI. You need to push it on the edges.</p>
<p>The third is over-engineering. AI sometimes produces elaborate solutions to simple problems. If you asked for a function that checks whether a number is even and got back a class with three methods and a configuration object, that's a red flag.</p>
<p>Complexity is a cost. Prefer simple code you understand over clever code you do not.</p>
<h2 id="heading-step-five-treat-prompt-changes-like-code-changes">Step Five: Treat Prompt Changes Like Code Changes</h2>
<p>If you're using AI in a repeatable way like an internal tool, a product feature, or a script you run regularly, your prompts are part of your codebase. Version control them. Review changes to them. Don't just edit a prompt and hope for the best.</p>
<p>The practical habit is to store prompts in files rather than hardcoding them inline, commit them to Git alongside your code, and re-run your golden dataset any time a prompt changes. This takes maybe ten minutes to set up and saves hours of debugging later.</p>
<p><a href="https://smith.langchain.com">LangSmith</a> and <a href="https://wandb.ai">Weights &amp; Biases</a> both offer prompt versioning and eval tracking if you want a more structured solution. For most small projects, a prompts folder in your repo and a simple test runner is enough.</p>
<h2 id="heading-the-mindset-that-makes-this-work">The Mindset That Makes This Work</h2>
<p>Every technique in this guide comes down to one shift: treat AI outputs like external inputs, not trusted code.</p>
<p>You wouldn't deploy an API response to production without validating its shape. You wouldn't accept a file upload without checking its contents. AI-generated code deserves the same skepticism, not because the AI is unreliable, but because all external inputs are unreliable, and good engineering accounts for that.</p>
<p>The engineers who get the most out of AI tools aren't the ones who trust them most. They are the ones who verify fastest. Write the tests first. Build the golden dataset. Measure reliability. Review what automation misses. Version your prompts.</p>
<p>Do those five things consistently and you'll ship AI-assisted code with the same confidence you bring to anything else in your stack.</p>
<p>Hope you enjoyed this article. You can <a href="https://linkedin.com/in/manishmshiva">connect with me on LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ From Manufacturing to Microservices: Universal Lessons About Reliability ]]>
                </title>
                <description>
                    <![CDATA[ Software engineers often think reliability is a modern challenge. We discuss uptime, distributed systems, observability, and fault tolerance as if they belong exclusively to cloud computing. In realit ]]>
                </description>
                <link>https://www.freecodecamp.org/news/from-manufacturing-to-microservices-universal-lessons-about-reliability/</link>
                <guid isPermaLink="false">6a5e283ee7616f5097f7d096</guid>
                
                    <category>
                        <![CDATA[ Microservices ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Software Engineering ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Reliability ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #manufacturing ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Mon, 20 Jul 2026 13:53:02 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/0de496b0-e02a-48c2-9631-d32a5152d766.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Software engineers often think reliability is a modern challenge.</p>
<p>We discuss uptime, distributed systems, observability, and fault tolerance as if they belong exclusively to cloud computing.</p>
<p>In reality, engineers have been solving reliability problems for centuries. Manufacturing plants, civil engineering projects, and industrial assembly lines have all faced the same fundamental question: how do you build systems that continue working even when individual components fail?</p>
<p>Whether you're assembling a bridge, manufacturing a vehicle, or deploying a microservice architecture, reliability is never accidental. It comes from thoughtful design, continuous testing, and a willingness to learn from failure.</p>
<p>The technology has changed, but the engineering principles have remained remarkably consistent.</p>
<p>In this article, we'll explore the timeless engineering principles that make systems reliable, whether they're factory assembly lines or cloud-native applications.</p>
<p>You'll see how concepts like redundancy, root cause analysis, realistic testing, and observability have guided engineers for decades, and why these lessons are just as valuable when building modern software.</p>
<p>By the end, you'll have a broader perspective on reliability and practical ideas you can apply to design more resilient systems.</p>
<h3 id="heading-what-well-cover">What We'll Cover:</h3>
<ul>
<li><p><a href="#heading-every-system-is-only-as-reliable-as-its-weakest-link">Every System Is Only as Reliable as Its Weakest Link</a></p>
</li>
<li><p><a href="#heading-small-defects-become-big-problems">Small Defects Become Big Problems</a></p>
</li>
<li><p><a href="#heading-root-cause-analysis-is-more-important-than-finding-someone-to-blame">Root Cause Analysis Is More Important Than Finding Someone to Blame</a></p>
</li>
<li><p><a href="#heading-redundancy-is-an-investment-not-a-waste">Redundancy Is an Investment, Not a Waste</a></p>
</li>
<li><p><a href="#heading-testing-should-simulate-reality">Testing Should Simulate Reality</a></p>
</li>
<li><p><a href="#heading-observability-is-better-than-guesswork">Observability Is Better Than Guesswork</a></p>
</li>
<li><p><a href="#heading-reliability-is-a-continuous-process">Reliability Is a Continuous Process</a></p>
</li>
<li><p><a href="#heading-great-engineering-is-predictable-engineering">Great Engineering Is Predictable Engineering</a></p>
</li>
</ul>
<h2 id="heading-every-system-is-only-as-reliable-as-its-weakest-link"><strong>Every System Is Only as Reliable as Its Weakest Link</strong></h2>
<p>A modern application may consist of dozens or even hundreds of services. Each service depends on databases, APIs, queues, caches, storage systems, and network infrastructure. A failure in any one of these components can ripple throughout the entire application.</p>
<p>Manufacturing systems work in much the same way. A perfectly designed product can still fail if one component is installed incorrectly or if quality checks are skipped during production.</p>
<p>This highlights an important lesson for software engineers: reliability isn't about building perfect components. It's about ensuring the entire system can tolerate imperfections.</p>
<p>Experienced engineering teams rarely assume everything will work perfectly. Instead, they ask questions like:</p>
<ul>
<li><p>What happens if this service becomes unavailable?</p>
</li>
<li><p>Can another component take over?</p>
</li>
<li><p>How quickly can the system recover?</p>
</li>
<li><p>Can users continue working while the issue is resolved?</p>
</li>
</ul>
<p>Designing around failure is often more valuable than trying to eliminate every possible failure.</p>
<h2 id="heading-small-defects-become-big-problems"><strong>Small Defects Become Big Problems</strong></h2>
<p>Many major outages begin with something surprisingly small.</p>
<p>A configuration value is incorrect. A certificate expires. A retry loop overwhelms a downstream service. A cache becomes stale. An API starts returning unexpected responses.</p>
<p>None of these issues appear catastrophic on their own. The real damage comes when multiple small problems combine into a larger system failure.</p>
<p>Manufacturing follows the same pattern. A slightly misaligned component may seem harmless during assembly, but over time it can increase wear, reduce efficiency, and eventually cause an expensive breakdown.</p>
<p>Software systems behave similarly. Small <a href="https://www.ibm.com/think/topics/technical-debt">technical debt</a> accumulates until reliability begins to suffer.</p>
<p>This is why experienced teams invest in routine maintenance. Refactoring, dependency updates, infrastructure improvements, and automated testing may not deliver visible product features, but they significantly reduce operational risk.</p>
<p>Reliability is built through consistent attention to small details.</p>
<h2 id="heading-root-cause-analysis-is-more-important-than-finding-someone-to-blame"><strong>Root Cause Analysis Is More Important Than Finding Someone to Blame</strong></h2>
<p>When production systems fail, organisations often rush to identify who made the mistake.</p>
<p>The better question is why the mistake was possible in the first place.</p>
<p>Perhaps deployment safeguards were missing. Or monitoring failed to detect unusual behaviour. Or the documentation was outdated.</p>
<p>Perhaps code reviews overlooked an important edge case.</p>
<p>Strong engineering cultures focus on improving systems rather than assigning blame.</p>
<p>This philosophy exists throughout engineering disciplines. Manufacturing companies spend significant effort studying common <a href="https://constructiondaily.news/common-failures-in-material-assembly-and-how-to-prevent-them/">failures in material assembly</a> because understanding why defects occur leads to stronger processes, better inspections, and fewer future failures.</p>
<p>Software teams benefit from the same mindset. Every production incident becomes an opportunity to improve automation, monitoring, documentation, and testing rather than simply fixing the immediate issue.</p>
<p>Blameless postmortems encourage engineers to report problems early because they know the goal is learning rather than punishment.</p>
<p>Over time, this creates systems that become progressively more reliable.</p>
<h2 id="heading-redundancy-is-an-investment-not-a-waste"><strong>Redundancy Is an Investment, Not a Waste</strong></h2>
<p>At first glance, redundancy appears inefficient.</p>
<p>Why run multiple application instances? Why maintain replica databases? Why deploy services across multiple regions? Why store multiple backups?</p>
<p>The answer becomes clear when failures occur.</p>
<p>If every critical component has only one instance, every failure becomes a complete outage.</p>
<p>Manufacturing plants frequently maintain backup equipment for exactly this reason. Downtime often costs far more than maintaining spare capacity.</p>
<p>Cloud infrastructure follows the same principle. Load balancers distribute requests across multiple servers. Database replicas reduce the impact of hardware failures. <a href="https://aws.amazon.com/message-queue/">Message queues</a> prevent temporary spikes from overwhelming downstream systems.</p>
<p>Multiple availability zones protect against regional outages.</p>
<p>Redundancy increases costs, but it dramatically improves resilience.</p>
<p>Organisations must decide whether the cost of additional infrastructure is lower than the potential cost of downtime.</p>
<p>For customer-facing applications, the answer is usually yes.</p>
<h2 id="heading-testing-should-simulate-reality"><strong>Testing Should Simulate Reality</strong></h2>
<p>Passing unit tests doesn't necessarily mean software is reliable.</p>
<p>Many production failures occur because real-world environments behave differently than development machines.</p>
<p>Networks become slow. External APIs return unexpected responses. Databases experience temporary latency. Users generate traffic patterns nobody anticipated.</p>
<p>Reliable engineering requires testing under realistic conditions.</p>
<p>Integration tests verify communication between services. Load testing evaluates system behavior under heavy traffic. Chaos engineering intentionally introduces failures to measure resilience.</p>
<p>Disaster recovery exercises ensure backup procedures actually work.</p>
<p>Manufacturing industries also perform stress testing before products reach customers. Components are exposed to extreme temperatures, vibration, pressure, and repeated use to identify weaknesses before they become field failures.</p>
<p>Software deserves the same level of scrutiny. The closer testing resembles production, the fewer surprises engineers encounter after deployment.</p>
<h2 id="heading-observability-is-better-than-guesswork"><strong>Observability Is Better Than Guesswork</strong></h2>
<p>When a production issue occurs, every minute matters. Without visibility into system behaviour, engineers are forced to make educated guesses. Guessing rarely solves outages quickly.</p>
<p>Modern observability combines logs, metrics, traces, and alerts into a complete picture of system health.</p>
<p>Logs explain what happened. Metrics reveal performance trends. Distributed tracing follows requests across multiple services. Dashboards expose unusual behavior before customers notice problems.</p>
<p>Together, these tools dramatically reduce the time required to diagnose incidents. The goal isn't collecting more data. The goal is collecting meaningful data that answers important operational questions:</p>
<ul>
<li><p>Can engineers identify the failing service?</p>
</li>
<li><p>Can they measure customer impact?</p>
</li>
<li><p>Can they determine when the problem began?</p>
</li>
<li><p>Can they verify that a fix actually resolved the issue?</p>
</li>
</ul>
<p>Observability transforms debugging from detective work into engineering.</p>
<h2 id="heading-reliability-is-a-continuous-process"><strong>Reliability Is a Continuous Process</strong></h2>
<p>Many organisations mistakenly treat reliability as a one-time project. They improve monitoring after an outage. They add automated tests after discovering a regression. They introduce deployment pipelines after a failed release.</p>
<p>These improvements help, but reliability isn't something you complete once and forget.</p>
<p>Every new feature introduces additional complexity. Every dependency update changes system behavior. Every scaling decision creates new operational challenges.</p>
<p>Reliable systems require continuous evaluation.</p>
<p>Engineering teams regularly review incidents, remove technical debt, improve automation, and update operational documentation because yesterday's reliable architecture may not meet tomorrow's demands.</p>
<p>Reliability evolves alongside the software itself.</p>
<h2 id="heading-great-engineering-is-predictable-engineering"><strong>Great Engineering Is Predictable Engineering</strong></h2>
<p>Users rarely notice reliable systems. Nobody celebrates an application that simply works every day.</p>
<p>Instead, attention often focuses on new features, product launches, and innovative technologies.</p>
<p>Yet reliability remains one of the strongest competitive advantages any engineering organisation can build.</p>
<p>Customers trust applications that remain available. Developers enjoy working on systems that behave predictably. Businesses avoid the financial and reputational costs associated with outages.</p>
<p>Manufacturing has long understood that quality is built into every stage of production rather than inspected in at the end. Software engineering follows exactly the same principle. Reliability emerges from thoughtful architecture, disciplined testing, effective monitoring, continuous learning, and a culture that treats every failure as an opportunity to improve.</p>
<p>From factory floors to cloud-native microservices, the lesson remains unchanged. Strong systems aren't defined by the absence of failure. They're defined by how well they anticipate it, absorb it, and recover from it.</p>
<p>The technologies may continue to evolve, but the fundamentals of reliable engineering are timeless.</p>
<p>Hope you enjoyed this article. You can <a href="https://linkedin.com/in/manishmshiva">connect with me on LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
