<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: AK DevCraft</title>
    <description>The latest articles on DEV Community by AK DevCraft (@akdevcraft).</description>
    <link>https://dev.to/akdevcraft</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F554959%2F58372a5a-61ca-4837-9390-42e925e9d3f6.jpeg</url>
      <title>DEV Community: AK DevCraft</title>
      <link>https://dev.to/akdevcraft</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/akdevcraft"/>
    <language>en</language>
    <item>
      <title>“Skills” in Claude Aren’t About Prompts — They’re About Context Design</title>
      <dc:creator>AK DevCraft</dc:creator>
      <pubDate>Mon, 13 Apr 2026 16:58:59 +0000</pubDate>
      <link>https://dev.to/akdevcraft/skills-in-claude-arent-about-prompts-theyre-about-context-design-46hf</link>
      <guid>https://dev.to/akdevcraft/skills-in-claude-arent-about-prompts-theyre-about-context-design-46hf</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When I first came across “Skills” in Claude Code, it looked like just another abstraction over prompts. I kept repeating the same instructions to Claude — code review rules, API patterns, formatting — across multiple sessions.&lt;/p&gt;

&lt;p&gt;But after spending some time with it, the interesting part wasn’t what skills are, but what problem it's trying to solve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

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

&lt;blockquote&gt;
&lt;p&gt;In the demo above, a &lt;code&gt;code-review&lt;/code&gt; skill is defined. When I ask Claude to “review modified files”, it automatically matches the request to the skill and executes it — without needing explicit invocation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Skills GitHub Repo&lt;/strong&gt; - &lt;a href="https://github.com/an1meshk/claude-chat-cli/tree/main/.claude/skills/code-review" rel="noopener noreferrer"&gt;.claude/skills/code-review&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Context Window Challenge
&lt;/h2&gt;

&lt;p&gt;One of the biggest challenges with LLM usage in real workflows is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Context keeps growing&lt;/li&gt;
&lt;li&gt;Instructions get repeated&lt;/li&gt;
&lt;li&gt;Conversations lose focus over time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most people try to fix this by writing better prompts or adding more context. However, that approach doesn’t scale. As more context/prompt is provided, more of the context window will be consumed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Definition
&lt;/h2&gt;

&lt;p&gt;First, let’s go over the official definition of Skills.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Skills are folders of instructions and resources that Claude Code can discover and use to handle tasks more accurately. Each skill lives in a SKILL.md file with at least a name and description in its frontmatter.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  A little more about Skills
&lt;/h2&gt;

&lt;p&gt;Skills can be created in different locations based on the user's or the project's settings. At the end of the day, skill is created at &lt;code&gt;.claude/skills/code-review/SKILL.md&lt;/code&gt;. Only difference is where the &lt;code&gt;.claude&lt;/code&gt; directory is created.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User's personal skill: Create &lt;code&gt;.claude&lt;/code&gt; directory in your home directory, e.g., &lt;code&gt;~/.claude/skills/code-review/SKILL.md&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Project-specific skill: create &lt;code&gt;.claude&lt;/code&gt; directory in the root of the project, e.g., &lt;code&gt;project/.claude/skills/code-review/SKILL.md&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apart from the user and project, skills can be stored at the Enterprise and plugin levels. And if you have the same skill with the same description in all locations (not a desire approach, but hypothetically), then the skill is applied based on the following precedence order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. Enterprise — managed settings, highest priority. All users in your organization.&lt;/li&gt;
&lt;li&gt;2. Personal — your home directory (&lt;code&gt;~/.claude/skills/&amp;lt;skill-name&amp;gt;/SKILL.md&lt;/code&gt;). All your projects.&lt;/li&gt;
&lt;li&gt;3. Project — the &lt;code&gt;.claude/skills/&amp;lt;skill-name&amp;gt;/SKILL.md&lt;/code&gt; directory inside a repository. A particular project only.&lt;/li&gt;
&lt;li&gt;4. Plugins — installed plugins &lt;code&gt;&amp;lt;plugin&amp;gt;/skills/&amp;lt;skill-name&amp;gt;/SKILL.md&lt;/code&gt;, lowest priority. Where the plugin is enabled.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Skills Flow Diagram
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Request
     ↓
[Skill Description Match]
     ↓
[Skill Loaded]
     ↓
[Context Applied]
     ↓
Claude Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What Skills Actually Change
&lt;/h2&gt;

&lt;p&gt;At a surface level, skills look simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Reusable instructions that Claude can apply&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But the real shift is deeper:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Skills separate “when to use context” from “what the context is.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s a big deal, instead of loading everything up front or manually injecting instructions. You define a trigger (description) and a payload (instructions).&lt;/p&gt;

&lt;p&gt;Skills work best for specialized knowledge that applies to specific tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code review standards&lt;/li&gt;
&lt;li&gt;Commit message formats&lt;/li&gt;
&lt;li&gt;Debugging checklists for a project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Claude handles the rest.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When you find yourself repeating again and again, then most likely you need a skill.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Most Important Part: Description
&lt;/h2&gt;

&lt;p&gt;If there’s one thing that matters more than anything else:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your Skills description is the entry point to your system&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is effectively a semantic matcher and routing mechanism. In practice, this means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Two skills with similar descriptions will conflict&lt;/li&gt;
&lt;li&gt;A vague description won’t trigger&lt;/li&gt;
&lt;li&gt;An overly broad one will trigger at the wrong time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 You’re not just writing instructions — you’re designing intent matching&lt;/p&gt;

&lt;h2&gt;
  
  
  Skills as a Context Control Mechanism
&lt;/h2&gt;

&lt;p&gt;What changed my thinking was this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Skills are not a convenience feature&lt;/li&gt;
&lt;li&gt;They are a context management strategy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because they are lazy-loaded only when needed, scopes are not always present, and multiple composable components can activate together.&lt;/p&gt;

&lt;p&gt;This directly impacts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Response quality&lt;/li&gt;
&lt;li&gt;Token usage&lt;/li&gt;
&lt;li&gt;System predictability&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Designing Skills (What Actually Matters)
&lt;/h2&gt;

&lt;p&gt;Let's see how we can design the Skills to harvest the best out of it.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Skill Schema (Only Important Ones)
&lt;/h3&gt;

&lt;p&gt;The skills open standard supports many fields in the &lt;code&gt;SKILL.md&lt;/code&gt; frontmatter. However, only two fields are required:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;name (required)&lt;/strong&gt; — Identifies your skill. Use lowercase letters, numbers, and hyphens only. Maximum 64 characters. Should match your directory name.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;description (required)&lt;/strong&gt; — Tells Claude when to use the skill. Maximum 1,024 characters. This is the most important field because Claude uses it for matching.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;allowed-tools (optional)&lt;/strong&gt; — Restricts which tools Claude can use when the skill is active.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;model (optional)&lt;/strong&gt; — Specifies which Claude model to use for the skill.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Keep the core small
&lt;/h3&gt;

&lt;p&gt;Don’t treat a skill like a knowledge dump. Keep instructions focused and push details to supporting files.&lt;br&gt;
Think of this as an entry point, not an encyclopedia.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Use constraints intentionally
&lt;/h3&gt;

&lt;p&gt;Parameters like tool restrictions aren’t just configuration. They’re guardrails.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read-only analysis skills&lt;/li&gt;
&lt;li&gt;Restricted execution environments&lt;/li&gt;
&lt;li&gt;Safer automation workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Structure for scale, not just usage
&lt;/h3&gt;

&lt;p&gt;The real challenge isn’t creating a skill — it’s managing many of them.&lt;/p&gt;

&lt;p&gt;Things that start to matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Naming clarity&lt;/li&gt;
&lt;li&gt;Description uniqueness&lt;/li&gt;
&lt;li&gt;Conflict avoidance&lt;/li&gt;
&lt;li&gt;Ownership (personal vs project vs org)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This becomes closer to system design than prompt design&lt;/p&gt;

&lt;h2&gt;
  
  
  Skills vs Everything Else
&lt;/h2&gt;

&lt;p&gt;A common mistake is trying to use skills for everything. But each feature solves a different problem. Claude Code has several ways to customize behavior. Skills are unique because they're automatic and task-specific. Here's a quick comparison:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CLAUDE.md&lt;/strong&gt; file is loaded into every conversation. If you want Claude to always use a certain file formatting, that goes in CLAUDE.md.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skills&lt;/strong&gt; load on demand when they match your request. Claude only loads the name and description initially, so they don't fill up your entire context window. Your code review checklist doesn't need to be in context when you're debugging — it loads when you actually ask for a review.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subagents&lt;/strong&gt; run in isolated execution contexts — use them for delegated work. Skills add knowledge to your current conversation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hooks&lt;/strong&gt; are event-driven (fire on some event like file saves). Skills are request-driven (activate based on what you're asking Claude to act)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP servers&lt;/strong&gt; provide external tools and integrations — a different category entirely from skills&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slash commands&lt;/strong&gt; require you to explicitly type them. Skills don't. Claude applies them when it recognizes the situation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How does this shift thinking
&lt;/h2&gt;

&lt;p&gt;Without Skills, we were thinking in terms of:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“How do I write better prompts?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now it’s more like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“How do I design context that shows up at the right time?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s a different level of control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Takeaways
&lt;/h2&gt;

&lt;p&gt;If you’re starting out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don’t create many skills — create one good one&lt;/li&gt;
&lt;li&gt;Spend more time on the description than the instructions&lt;/li&gt;
&lt;li&gt;Keep skills narrow and intentional&lt;/li&gt;
&lt;li&gt;Treat conflicts as a design problem, not a bug&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And most importantly:&lt;/p&gt;

&lt;p&gt;👉 If context is growing uncontrollably, skills are probably the penetrating layer.&lt;/p&gt;

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

&lt;p&gt;👉 “Skills are not a feature. They’re a shift in how you structure AI systems.”&lt;/p&gt;

&lt;p&gt;But the idea behind them is bigger:&lt;/p&gt;

&lt;p&gt;👉 Moving from prompt writing → to context system design&lt;/p&gt;

&lt;p&gt;And that’s where LLM usage starts becoming predictable, not just powerful.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have reached here, then I have made a satisfactory effort to keep you reading. Please be kind enough to leave any comments or share any corrections.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  My Other Blogs:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/practical-tips-when-working-with-ai-coding-assistants-1pea"&gt;Practical Tips When Working with AI Coding Assistants&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/trying-mcp-for-the-first-time-what-stood-out-1451"&gt;Trying MCP for the First Time — What Stood Out&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/never-use-spring-restclient-default-implementation-in-production-100g"&gt;To Avoid Performance Impact Never Use Spring RestClient Default Implementation in Production&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/modern-devsecops-requires-more-than-one-tool-a-practical-sdlc-security-strategy-4d74"&gt;Modern DevSecOps Needs More Than One Tool: A Practical Secure SDLC Strategy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⁠&lt;a href="https://dev.to/akdevcraft/playwright-and-cucumber-are-the-best-tools-for-end-to-end-testing-a28"&gt;Supercharge Your E2E Tests with Playwright and Cucumber Integration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/when-resilience-backfires-retry-and-circuit-breaker-in-spring-boot-10m"&gt;When Resilience Backfires: Retry and Circuit Breaker in Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>machinelearning</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Trying MCP for the First Time — What Stood Out</title>
      <dc:creator>AK DevCraft</dc:creator>
      <pubDate>Mon, 30 Mar 2026 18:40:40 +0000</pubDate>
      <link>https://dev.to/akdevcraft/trying-mcp-for-the-first-time-what-stood-out-1451</link>
      <guid>https://dev.to/akdevcraft/trying-mcp-for-the-first-time-what-stood-out-1451</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I spent some time exploring the Model Context Protocol (MCP). Not a deep dive—just a hands-on attempt to understand how it actually works.&lt;/p&gt;

&lt;p&gt;So I built a minimal client + server setup:&lt;br&gt;
👉 &lt;a href="https://github.com/an1meshk/claude-chat-cli" rel="noopener noreferrer"&gt;https://github.com/an1meshk/claude-chat-cli&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In a real-world project, we will build client and server separately; however, as this was just a demo project, everything was built in the same project&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A few things stood out more than I expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

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

&lt;h2&gt;
  
  
  🧠 Context
&lt;/h2&gt;

&lt;p&gt;The goal wasn’t to learn everything about MCP. It was to answer a simpler question:&lt;br&gt;
How hard is it to actually build something with it?&lt;/p&gt;

&lt;p&gt;Before moving further, here is a quick MCP client and server architecture diagram:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdep2g2jppr883gj7e7jj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdep2g2jppr883gj7e7jj.png" alt="mcp architecture" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚙️ What I Tried
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Went through the MCP intro course - &lt;a href="https://anthropic.skilljar.com/introduction-to-model-context-protocol" rel="noopener noreferrer"&gt;course link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Built a minimal client and server in Python using the course’s startup kit&lt;/li&gt;
&lt;li&gt;Connected it to a simple CLI chat client that already came with the startup kit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nothing complex—but enough to see how things fit together.&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 What Stood Out
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Setup Is Simpler Than Expected
&lt;/h3&gt;

&lt;p&gt;I was expecting some heavy setup. But, instead:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic server setup was straightforward&lt;/li&gt;
&lt;li&gt;The Python MCP library abstracts most of the complexity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 It felt closer to:&lt;br&gt;
“Define a few handlers, and you’re up.”&lt;/p&gt;

&lt;p&gt;than:&lt;/p&gt;

&lt;p&gt;“Learn a new framework.”&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The Real Concept Is Context Flow
&lt;/h3&gt;

&lt;p&gt;The interesting part wasn’t the server setup. It was understanding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How context flows&lt;/li&gt;
&lt;li&gt;How tools are exposed&lt;/li&gt;
&lt;li&gt;Exposing resources&lt;/li&gt;
&lt;li&gt;How the model interacts with them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s where the mental shift is.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 What Helped Me Understand It
&lt;/h2&gt;

&lt;p&gt;This simple mental model made things click:&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;image credit Anthropic academy course&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Client → MCP Server → Tool → Response → Client&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Client sends a request&lt;/li&gt;
&lt;li&gt;MCP server routes it&lt;/li&gt;
&lt;li&gt;The tool executes logic&lt;/li&gt;
&lt;li&gt;Response flows back&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once this clicked, everything else made more sense&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚡ If You Want to Try It
&lt;/h2&gt;

&lt;p&gt;The setup is intentionally minimal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic MCP server using Python&lt;/li&gt;
&lt;li&gt;A simple tool&lt;/li&gt;
&lt;li&gt;CLI client to trigger it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s enough to understand the core idea&lt;/p&gt;

&lt;p&gt;Repo:&lt;br&gt;
&lt;a href="https://github.com/an1meshk/claude-chat-cli" rel="noopener noreferrer"&gt;https://github.com/an1meshk/claude-chat-cli&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You will need an Anthropic API key, as this project uses Claude&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ⚙️ One More Thing That Helped
&lt;/h2&gt;

&lt;p&gt;Project uses &lt;code&gt;uv&lt;/code&gt; for dependency management. That helps in a few ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fast installs&lt;/li&gt;
&lt;li&gt;Clean environment setup&lt;/li&gt;
&lt;li&gt;Minimal friction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It removes a lot of the usual setup overhead&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚠️ What I Haven’t Explored Yet
&lt;/h2&gt;

&lt;p&gt;This was just a first pass. Still curious about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Structuring tools cleanly&lt;/li&gt;
&lt;li&gt;Scaling MCP servers&lt;/li&gt;
&lt;li&gt;Real production use cases&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧠 Initial Take
&lt;/h2&gt;

&lt;p&gt;My early impression:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MCP isn’t hard to start with&lt;/li&gt;
&lt;li&gt;But the real value is in how you design interactions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The setup is easy.&lt;br&gt;
The thinking is where the work is.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏁 Final Thought
&lt;/h2&gt;

&lt;p&gt;Sometimes the best way to understand a new concept is:&lt;br&gt;
Build the simplest possible version of it&lt;/p&gt;

&lt;p&gt;This was one of those cases.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have reached here, then I have made a satisfactory effort to keep you reading. Please be kind enough to leave any comments or share any corrections.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  My Other Blogs:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/shift-left-performance-testing-in-spring-boot-stability-through-control-5e01"&gt;Shift-Left Performance Testing in Spring Boot: Engineering Stability Before Scale&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/practical-tips-when-working-with-ai-coding-assistants-1pea"&gt;Practical Tips When Working with AI Coding Assistants&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/never-use-spring-restclient-default-implementation-in-production-100g"&gt;To Avoid Performance Impact Never Use Spring RestClient Default Implementation in Production&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/modern-devsecops-requires-more-than-one-tool-a-practical-sdlc-security-strategy-4d74"&gt;Modern DevSecOps Needs More Than One Tool: A Practical Secure SDLC Strategy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⁠&lt;a href="https://dev.to/akdevcraft/playwright-and-cucumber-are-the-best-tools-for-end-to-end-testing-a28"&gt;Supercharge Your E2E Tests with Playwright and Cucumber Integration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/when-resilience-backfires-retry-and-circuit-breaker-in-spring-boot-10m"&gt;When Resilience Backfires: Retry and Circuit Breaker in Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>machinelearning</category>
      <category>python</category>
    </item>
    <item>
      <title>Git Commands Workflow</title>
      <dc:creator>AK DevCraft</dc:creator>
      <pubDate>Sun, 29 Mar 2026 06:11:00 +0000</pubDate>
      <link>https://dev.to/akdevcraft/git-commands-workflow-5co8</link>
      <guid>https://dev.to/akdevcraft/git-commands-workflow-5co8</guid>
      <description>&lt;h2&gt;
  
  
  ⚡ Git Commands Workflow
&lt;/h2&gt;

&lt;p&gt;When I started using Git, I tried to learn as many commands as possible.&lt;/p&gt;

&lt;p&gt;But over time, I realized something:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You don’t need to know everything.&lt;br&gt;
You need to master the workflow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most of my day-to-day work revolves around a small set of commands—used repeatedly in different contexts.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 The Real Git Workflow
&lt;/h2&gt;

&lt;p&gt;At a high level, Git revolves around three stages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Working directory → where you make changes&lt;/li&gt;
&lt;li&gt;Staging area → where you prepare changes&lt;/li&gt;
&lt;li&gt;Repository → where changes are committed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding this flow matters more than memorizing commands.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔄 1. Starting Work
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git pull
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; feature/my-feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sync latest code&lt;/li&gt;
&lt;li&gt;Create a new branch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This is usually how I start my day.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✍️ 2. Making Changes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status
git add &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git status&lt;/code&gt; → shows what changed&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git add&lt;/code&gt; → stages changes for commit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 I check the status a lot more than I expected.&lt;/p&gt;

&lt;h3&gt;
  
  
  💾 3. Saving Work
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add feature X"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Creates a snapshot of your changes&lt;/li&gt;
&lt;li&gt;Helps track history over time &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Good commit messages matter more than the command itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  🚀 4. Syncing with Remote
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push
git pull
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;push&lt;/code&gt; → sends your changes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pull&lt;/code&gt; → brings latest updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This is where most conflicts show up.&lt;/p&gt;

&lt;h3&gt;
  
  
  🌿 5. Working with Branches
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git branch
git checkout main
git merge feature/my-feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Branching helps isolate work&lt;/li&gt;
&lt;li&gt;Merging brings changes together&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Simple concept—but causes most real-world issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧰 6. Commands I Started Using Later
&lt;/h3&gt;

&lt;p&gt;These didn’t make sense early on—but became useful over time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git stash
git log
git diff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;stash&lt;/code&gt; → save work temporarily&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;log&lt;/code&gt; → view history&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;diff&lt;/code&gt; → see changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 These are workflow boosters, not essentials.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚠️ What Actually Matters (Not the Commands)
&lt;/h3&gt;

&lt;p&gt;Over time, I realized:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Git problems are rarely about commands&lt;/li&gt;
&lt;li&gt;They’re about understanding state and flow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most issues come from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not knowing what’s staged&lt;/li&gt;
&lt;li&gt;Working on the wrong branch&lt;/li&gt;
&lt;li&gt;Pulling at the wrong time&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧠 What I’d Do Differently
&lt;/h2&gt;

&lt;p&gt;If I were starting again:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Focus on workflow, not commands&lt;/li&gt;
&lt;li&gt;Learn:

&lt;ul&gt;
&lt;li&gt;status&lt;/li&gt;
&lt;li&gt;add&lt;/li&gt;
&lt;li&gt;commit&lt;/li&gt;
&lt;li&gt;branch&lt;/li&gt;
&lt;li&gt;merge&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;👉 That’s enough for most real work.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚡ Practical Takeaways
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You don’t need 50 Git commands&lt;/li&gt;
&lt;li&gt;Master the core workflow first&lt;/li&gt;
&lt;li&gt;Use advanced commands only when needed&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🏁 Final Thought
&lt;/h2&gt;

&lt;p&gt;Git feels complex when you try to learn everything.&lt;/p&gt;

&lt;p&gt;It becomes simple when you think in terms of:&lt;br&gt;
“Where are my changes right now?”&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have reached here, then I have made a satisfactory effort to keep you reading. Please be kind enough to leave any comments or share any corrections.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  My Other Blogs:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/shift-left-performance-testing-in-spring-boot-stability-through-control-5e01"&gt;Shift-Left Performance Testing in Spring Boot: Engineering Stability Before Scale&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/practical-tips-when-working-with-ai-coding-assistants-1pea"&gt;Practical Tips When Working with AI Coding Assistants&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/never-use-spring-restclient-default-implementation-in-production-100g"&gt;To Avoid Performance Impact Never Use Spring RestClient Default Implementation in Production&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/modern-devsecops-requires-more-than-one-tool-a-practical-sdlc-security-strategy-4d74"&gt;Modern DevSecOps Needs More Than One Tool: A Practical Secure SDLC Strategy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⁠&lt;a href="https://dev.to/akdevcraft/playwright-and-cucumber-are-the-best-tools-for-end-to-end-testing-a28"&gt;Supercharge Your E2E Tests with Playwright and Cucumber Integration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/when-resilience-backfires-retry-and-circuit-breaker-in-spring-boot-10m"&gt;When Resilience Backfires: Retry and Circuit Breaker in Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/setup-graphql-mock-server-32fc"&gt;Setup GraphQL Mock Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/cracking-software-engineer-interview-mp3"&gt;Cracking Software Engineering Interviews&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>JMeter vs Gatling: Comparison for Modern Performance Testing</title>
      <dc:creator>AK DevCraft</dc:creator>
      <pubDate>Sun, 22 Mar 2026 05:45:13 +0000</pubDate>
      <link>https://dev.to/akdevcraft/jmeter-vs-gatling-comparison-for-modern-performance-testing-57a1</link>
      <guid>https://dev.to/akdevcraft/jmeter-vs-gatling-comparison-for-modern-performance-testing-57a1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Performance testing has been around for a long time. And if you’ve worked in this space, chances are you’ve used &lt;a href="https://jmeter.apache.org/" rel="noopener noreferrer"&gt;Apache JMeter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It’s popular.&lt;br&gt;
It’s reliable.&lt;br&gt;
And it has served the industry well.&lt;/p&gt;

&lt;p&gt;But is it still the best way to approach performance testing today?&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 The Shift: From Tooling → Engineering
&lt;/h2&gt;

&lt;p&gt;Traditional performance testing tools like &lt;a href="https://jmeter.apache.org/" rel="noopener noreferrer"&gt;Apache JMeter&lt;/a&gt; are largely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UI-driven&lt;/li&gt;
&lt;li&gt;Configuration-heavy&lt;/li&gt;
&lt;li&gt;File-based (XML test plans)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This works… until it doesn’t.&lt;/p&gt;

&lt;p&gt;As systems become more complex and teams move toward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CI/CD&lt;/li&gt;
&lt;li&gt;Version-controlled infrastructure&lt;/li&gt;
&lt;li&gt;“Everything as Code”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Performance testing needs to evolve, too.&lt;/p&gt;

&lt;p&gt;That’s where &lt;a href="https://gatling.io/" rel="noopener noreferrer"&gt;Gatling&lt;/a&gt; starts to stand out.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚔️ JMeter vs Gatling — Key Differences
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 🧩 Configuration vs Code
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;JMeter&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test plans are GUI-driven&lt;/li&gt;
&lt;li&gt;Stored as .jmx files&lt;/li&gt;
&lt;li&gt;Harder to review in pull requests&lt;/li&gt;
&lt;li&gt;Merge conflicts are painful&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Gatling&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fully code-based (Scala/Java/Kotlin)&lt;/li&gt;
&lt;li&gt;Lives naturally in your codebase&lt;/li&gt;
&lt;li&gt;Easy to version, review, and refactor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This is the biggest shift:&lt;/p&gt;

&lt;p&gt;Gatling treats performance tests like real software, not configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. 🚀 Learning Curve &amp;amp; Developer Experience
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;JMeter&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Requires learning the tool + UI&lt;/li&gt;
&lt;li&gt;Debugging can be unintuitive&lt;/li&gt;
&lt;li&gt;Configuration becomes overhead over time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Gatling&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uses familiar programming languages&lt;/li&gt;
&lt;li&gt;Easier for developers to adopt&lt;/li&gt;
&lt;li&gt;Better IDE support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 You’re not learning a tool—you’re applying existing skills.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. 🔄 CI/CD Integration
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;JMeter&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integration is possible, but not seamless&lt;/li&gt;
&lt;li&gt;Often requires additional scripting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Gatling&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fits naturally into build pipelines&lt;/li&gt;
&lt;li&gt;Works like any other test suite&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This aligns perfectly with modern DevOps practices.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. 📊 Reporting &amp;amp; Insights
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;JMeter&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provides reports, but often requires interpretation&lt;/li&gt;
&lt;li&gt;User ramp-up behavior isn’t always obvious&lt;/li&gt;
&lt;li&gt;Some level of “guesswork” is involved&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Gatling&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rich, interactive HTML reports out of the box&lt;/li&gt;
&lt;li&gt;Clear visualization of:

&lt;ul&gt;
&lt;li&gt;Active users&lt;/li&gt;
&lt;li&gt;Ramp-up patterns&lt;/li&gt;
&lt;li&gt;Response time distribution&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;👉 Observability is significantly better.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. ⚙️ Maintainability at Scale
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;JMeter&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large test plans become difficult to manage&lt;/li&gt;
&lt;li&gt;Reusability is limited&lt;/li&gt;
&lt;li&gt;Refactoring is cumbersome&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Gatling&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modular, reusable code&lt;/li&gt;
&lt;li&gt;Easier to scale scenarios&lt;/li&gt;
&lt;li&gt;Cleaner structure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This becomes critical in large systems.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  🏁 So… Is JMeter Still Relevant?
&lt;/h2&gt;

&lt;p&gt;Absolutely.&lt;/p&gt;

&lt;p&gt;Apache JMeter is still:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mature&lt;/li&gt;
&lt;li&gt;Widely adopted&lt;/li&gt;
&lt;li&gt;Backed by a strong community&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quick testing&lt;/li&gt;
&lt;li&gt;Non-developer teams&lt;/li&gt;
&lt;li&gt;Legacy setups&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 It still does the job very well.&lt;/p&gt;

&lt;h3&gt;
  
  
  💡 My Take
&lt;/h3&gt;

&lt;p&gt;If your team is moving toward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microservices&lt;/li&gt;
&lt;li&gt;CI/CD pipelines&lt;/li&gt;
&lt;li&gt;Engineering-driven quality&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;p&gt;👉 Gatling feels like the natural next step&lt;/p&gt;

&lt;p&gt;Not because JMeter is bad…&lt;br&gt;
…but because the way we build software has changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔥 Final Thought
&lt;/h2&gt;

&lt;p&gt;We’ve already embraced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Infrastructure as Code&lt;/li&gt;
&lt;li&gt;Tests as Code&lt;/li&gt;
&lt;li&gt;Pipelines as Code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Performance testing as code is the next logical step.&lt;/p&gt;

&lt;p&gt;And in that world, &lt;a href="https://gatling.io/" rel="noopener noreferrer"&gt;Gatling&lt;/a&gt; has a clear edge.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have reached here, then I have made a satisfactory effort to keep you reading. Please be kind enough to leave any comments or share any corrections.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  My Other Blogs:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/shift-left-performance-testing-in-spring-boot-stability-through-control-5e01"&gt;Shift-Left Performance Testing in Spring Boot: Engineering Stability Before Scale&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/practical-tips-when-working-with-ai-coding-assistants-1pea"&gt;Practical Tips When Working with AI Coding Assistants&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/never-use-spring-restclient-default-implementation-in-production-100g"&gt;To Avoid Performance Impact Never Use Spring RestClient Default Implementation in Production&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/modern-devsecops-requires-more-than-one-tool-a-practical-sdlc-security-strategy-4d74"&gt;Modern DevSecOps Needs More Than One Tool: A Practical Secure SDLC Strategy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⁠&lt;a href="https://dev.to/akdevcraft/playwright-and-cucumber-are-the-best-tools-for-end-to-end-testing-a28"&gt;Supercharge Your E2E Tests with Playwright and Cucumber Integration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/when-resilience-backfires-retry-and-circuit-breaker-in-spring-boot-10m"&gt;When Resilience Backfires: Retry and Circuit Breaker in Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/setup-graphql-mock-server-32fc"&gt;Setup GraphQL Mock Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/cracking-software-engineer-interview-mp3"&gt;Cracking Software Engineering Interviews&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>performance</category>
      <category>api</category>
      <category>backend</category>
    </item>
    <item>
      <title>Practical Tips When Working with AI Coding Assistants</title>
      <dc:creator>AK DevCraft</dc:creator>
      <pubDate>Sat, 14 Mar 2026 22:22:13 +0000</pubDate>
      <link>https://dev.to/akdevcraft/practical-tips-when-working-with-ai-coding-assistants-1pea</link>
      <guid>https://dev.to/akdevcraft/practical-tips-when-working-with-ai-coding-assistants-1pea</guid>
      <description>&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;Modern AI coding assistants like Claude, GitHub Copilot, and ChatGPT can dramatically accelerate development. Recently, while working on a feature update, I had to modify an existing API to fetch data from a new system while maintaining backward compatibility.&lt;/p&gt;

&lt;p&gt;The migration was gradual. Some clients would continue using the old system for a while, while others would start using the new one. Because of that, the implementation had to support both behaviors during the transition period.&lt;/p&gt;

&lt;p&gt;Like many developers today, I used an AI coding assistant to speed up the implementation.&lt;/p&gt;

&lt;p&gt;At first, it seemed straightforward.&lt;/p&gt;

&lt;p&gt;But the process turned out to be more interesting than expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  The First Iteration Looked Correct… But Wasn't Ideal
&lt;/h2&gt;

&lt;p&gt;The AI-generated code worked functionally. It handled the new system integration, preserved backward compatibility, and integrated with the existing service.&lt;/p&gt;

&lt;p&gt;But after reviewing the code carefully, a few issues surfaced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extra conditional branches that were unnecessary&lt;/li&gt;
&lt;li&gt;Redundant logic left over from earlier iterations&lt;/li&gt;
&lt;li&gt;Code paths that technically worked but were not optimal&lt;/li&gt;
&lt;li&gt;Some defensive checks that were never needed for the actual use case&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, the code worked, but it wasn't clean.&lt;/p&gt;

&lt;p&gt;It took multiple iterations and careful review before the implementation reached a version that was both correct and maintainable.&lt;/p&gt;

&lt;p&gt;This experience reinforced something important.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Accelerates Coding — Not Thinking
&lt;/h2&gt;

&lt;p&gt;AI assistants are excellent at generating working code quickly. They help remove boilerplate, explore possible implementations, and reduce the time spent writing repetitive logic.&lt;/p&gt;

&lt;p&gt;However, they do not fully understand the context of your system.&lt;/p&gt;

&lt;p&gt;They don't know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The long-term architecture decisions&lt;/li&gt;
&lt;li&gt;The migration strategy&lt;/li&gt;
&lt;li&gt;The constraints of your system&lt;/li&gt;
&lt;li&gt;What future developers will have to maintain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because of this, AI often generates code that is technically correct but contextually imperfect.&lt;/p&gt;

&lt;p&gt;And that is where code review becomes critical.&lt;/p&gt;

&lt;h2&gt;
  
  
  In the AI Era, Code Review Becomes a Core Skill
&lt;/h2&gt;

&lt;p&gt;When development speed increases, the risk of suboptimal code entering the codebase also increases.&lt;/p&gt;

&lt;p&gt;If developers accept AI-generated code in the first iteration, teams may gradually accumulate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unnecessary abstractions&lt;/li&gt;
&lt;li&gt;Redundant logic&lt;/li&gt;
&lt;li&gt;Hidden technical debt&lt;/li&gt;
&lt;li&gt;Dead code paths&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Over time, these small issues compound, making systems harder to maintain.&lt;/p&gt;

&lt;p&gt;This means developers must become even better reviewers than before.&lt;/p&gt;

&lt;p&gt;Good code review is no longer just about catching bugs. It is about evaluating whether the code truly fits the system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions We Should Now Ask During Code Review
&lt;/h2&gt;

&lt;p&gt;When reviewing AI-assisted code, now intentionally ask a few additional questions.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Does the code solve the problem exactly, or more than necessary?
&lt;/h3&gt;

&lt;p&gt;AI often introduces extra flexibility that the use case does not require.&lt;br&gt;
Extra flexibility today can easily become unnecessary complexity tomorrow.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Is there redundant or leftover logic?
&lt;/h3&gt;

&lt;p&gt;Because AI suggestions often evolve across multiple prompts, some intermediate logic can remain even after the final version is generated.&lt;br&gt;
This can result in code paths that are never actually used.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Is the implementation optimal for the system architecture?
&lt;/h3&gt;

&lt;p&gt;AI may suggest patterns that work in general but do not align with your system's architecture.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Introducing unnecessary abstractions&lt;/li&gt;
&lt;li&gt;Overusing defensive checks&lt;/li&gt;
&lt;li&gt;Adding layers that increase complexity without real benefit&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Will the code still make sense to the next developer?
&lt;/h3&gt;

&lt;p&gt;Maintainability matters.&lt;br&gt;
Even if the code works, the question remains:&lt;/p&gt;

&lt;p&gt;Would another engineer understand this logic six months from now?&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Changes the Development Workflow
&lt;/h2&gt;

&lt;p&gt;One interesting shift I’ve noticed is that development is starting to look more like collaboration between a developer and an AI assistant.&lt;/p&gt;

&lt;p&gt;The workflow increasingly looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Developer defines the intent&lt;/li&gt;
&lt;li&gt;AI generates an implementation&lt;/li&gt;
&lt;li&gt;Developer reviews and refines&lt;/li&gt;
&lt;li&gt;AI proposes improvements&lt;/li&gt;
&lt;li&gt;Developer validates architecture and constraints&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The developer's role shifts slightly from writing every line of code to evaluating, refining, and validating generated code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Skill Shift for Engineers
&lt;/h2&gt;

&lt;p&gt;As AI becomes more capable at writing code, the value of engineers will increasingly come from their ability to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Review code critically&lt;/li&gt;
&lt;li&gt;Evaluate trade-offs&lt;/li&gt;
&lt;li&gt;Optimize implementations&lt;/li&gt;
&lt;li&gt;Ensure architectural alignment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, the skill of thinking about code becomes even more important than writing code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Development Flow Diagram
&lt;/h2&gt;

&lt;p&gt;Here is a quick comparison between Traditional and AI-Assistent development flow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Traditional Development
&lt;/h3&gt;

&lt;p&gt;Developer&lt;br&gt;
   ↓&lt;br&gt;
Write Code&lt;br&gt;
   ↓&lt;br&gt;
Code Review&lt;br&gt;
   ↓&lt;br&gt;
Merge&lt;/p&gt;

&lt;h3&gt;
  
  
  AI-Assisted Development
&lt;/h3&gt;

&lt;p&gt;Developer Idea&lt;br&gt;
      ↓&lt;br&gt;
AI Generates Code&lt;br&gt;
      ↓&lt;br&gt;
Developer Reviews &amp;amp; Refines&lt;br&gt;
      ↓&lt;br&gt;
AI Iteration&lt;br&gt;
      ↓&lt;br&gt;
Code Review&lt;br&gt;
      ↓&lt;br&gt;
   Merge&lt;/p&gt;

&lt;p&gt;AI accelerates code generation, but developers are still responsible for validating the architecture, reducing unnecessary complexity, and ensuring maintainability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;AI tools are powerful accelerators for software development. They can help teams move faster and explore solutions more quickly.&lt;/p&gt;

&lt;p&gt;But speed should not come at the cost of quality.&lt;/p&gt;

&lt;p&gt;If anything, the rise of AI in development makes strong code review practices more important than ever.&lt;/p&gt;

&lt;p&gt;Ultimately, AI can generate code, but engineers are still responsible for the systems they build.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have reached here, then I have made a satisfactory effort to keep you reading. Please be kind enough to leave any comments or share any corrections.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  My Other Blogs:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;⁠&lt;a href="https://dev.to/akdevcraft/playwright-and-cucumber-are-the-best-tools-for-end-to-end-testing-a28"&gt;Supercharge Your E2E Tests with Playwright and Cucumber Integration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/never-use-spring-restclient-default-implementation-in-production-100g"&gt;To Avoid Performance Impact Never Use Spring RestClient Default Implementation in Production&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/modern-devsecops-requires-more-than-one-tool-a-practical-sdlc-security-strategy-4d74"&gt;Modern DevSecOps Needs More Than One Tool: A Practical Secure SDLC Strategy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/shift-left-performance-testing-in-spring-boot-stability-through-control-5e01"&gt;Shift-Left Performance Testing in Spring Boot: Engineering Stability Before Scale&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/when-resilience-backfires-retry-and-circuit-breaker-in-spring-boot-10m"&gt;When Resilience Backfires: Retry and Circuit Breaker in Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/setup-graphql-mock-server-32fc"&gt;Setup GraphQL Mock Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/when-should-you-use-server-side-rendering-ssr-3a5a"&gt;When Should You Use Server-Side Rendering (SSR)?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/cracking-software-engineer-interview-mp3"&gt;Cracking Software Engineering Interviews&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>githubcopilot</category>
      <category>softwareengineering</category>
      <category>claude</category>
    </item>
    <item>
      <title>☁️ Private Cloud vs Public Cloud — still one of the most misunderstood topics in cloud computing.
Many discussions focus only on cost or control, but the real differences go deeper</title>
      <dc:creator>AK DevCraft</dc:creator>
      <pubDate>Thu, 12 Mar 2026 05:37:00 +0000</pubDate>
      <link>https://dev.to/akdevcraft/private-cloud-vs-public-cloud-still-one-of-the-most-misunderstood-topics-in-cloud-computing-21a2</link>
      <guid>https://dev.to/akdevcraft/private-cloud-vs-public-cloud-still-one-of-the-most-misunderstood-topics-in-cloud-computing-21a2</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/akdevcraft/private-vs-public-cloud-computing-5b74" class="crayons-story__hidden-navigation-link"&gt;Private vs Public Cloud: Key Differences, Architecture, and Cloud Service Models&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/akdevcraft" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F554959%2F58372a5a-61ca-4837-9390-42e925e9d3f6.jpeg" alt="akdevcraft profile" class="crayons-avatar__image" width="800" height="457"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/akdevcraft" class="crayons-story__secondary fw-medium m:hidden"&gt;
              AK DevCraft
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                AK DevCraft
                &lt;a href="/++"&gt;&lt;img alt="Subscriber" class="subscription-icon" src="https://assets.dev.to/assets/subscription-icon-805dfa7ac7dd660f07ed8d654877270825b07a92a03841aa99a1093bd00431b2.png" width="166" height="102"&gt;&lt;/a&gt;
              
              &lt;div id="story-author-preview-content-924090" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/akdevcraft" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F554959%2F58372a5a-61ca-4837-9390-42e925e9d3f6.jpeg" class="crayons-avatar__image" alt="" width="800" height="457"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;AK DevCraft&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/akdevcraft/private-vs-public-cloud-computing-5b74" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Dec 12 '21&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/akdevcraft/private-vs-public-cloud-computing-5b74" id="article-link-924090"&gt;
          Private vs Public Cloud: Key Differences, Architecture, and Cloud Service Models
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/cloud"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;cloud&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/cloudcomputing"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;cloudcomputing&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/containers"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;containers&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/docker"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;docker&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/akdevcraft/private-vs-public-cloud-computing-5b74" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;5&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/akdevcraft/private-vs-public-cloud-computing-5b74#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              1&lt;span class="hidden s:inline"&gt; comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>cloud</category>
      <category>cloudcomputing</category>
      <category>containers</category>
      <category>docker</category>
    </item>
    <item>
      <title>Do you know how to stream Kubernetes log from multiple pods concurrently?</title>
      <dc:creator>AK DevCraft</dc:creator>
      <pubDate>Fri, 27 Feb 2026 05:14:43 +0000</pubDate>
      <link>https://dev.to/akdevcraft/do-you-know-how-to-stream-kubernetes-log-from-multiple-pods-concurrently-43c8</link>
      <guid>https://dev.to/akdevcraft/do-you-know-how-to-stream-kubernetes-log-from-multiple-pods-concurrently-43c8</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/akdevcraft/streaming-logs-from-all-pods-at-once-1kh7" class="crayons-story__hidden-navigation-link"&gt;Streaming Kubernetes logs of more than one pod concurrently&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/akdevcraft" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F554959%2F58372a5a-61ca-4837-9390-42e925e9d3f6.jpeg" alt="akdevcraft profile" class="crayons-avatar__image" width="800" height="457"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/akdevcraft" class="crayons-story__secondary fw-medium m:hidden"&gt;
              AK DevCraft
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                AK DevCraft
                &lt;a href="/++"&gt;&lt;img alt="Subscriber" class="subscription-icon" src="https://assets.dev.to/assets/subscription-icon-805dfa7ac7dd660f07ed8d654877270825b07a92a03841aa99a1093bd00431b2.png" width="166" height="102"&gt;&lt;/a&gt;
              
              &lt;div id="story-author-preview-content-1316688" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/akdevcraft" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F554959%2F58372a5a-61ca-4837-9390-42e925e9d3f6.jpeg" class="crayons-avatar__image" alt="" width="800" height="457"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;AK DevCraft&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/akdevcraft/streaming-logs-from-all-pods-at-once-1kh7" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jan 3 '23&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/akdevcraft/streaming-logs-from-all-pods-at-once-1kh7" id="article-link-1316688"&gt;
          Streaming Kubernetes logs of more than one pod concurrently
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/kubernetes"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;kubernetes&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/containers"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;containers&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/docker"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;docker&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/softwareengineering"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;softwareengineering&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/akdevcraft/streaming-logs-from-all-pods-at-once-1kh7" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;4&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/akdevcraft/streaming-logs-from-all-pods-at-once-1kh7#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            2 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>kubernetes</category>
      <category>containers</category>
      <category>docker</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>From DEV in 2021 to Substack Today: Continuing the Writing Journey</title>
      <dc:creator>AK DevCraft</dc:creator>
      <pubDate>Sun, 22 Feb 2026 00:13:28 +0000</pubDate>
      <link>https://dev.to/akdevcraft/from-dev-in-2021-to-substack-today-continuing-the-writing-journey-115p</link>
      <guid>https://dev.to/akdevcraft/from-dev-in-2021-to-substack-today-continuing-the-writing-journey-115p</guid>
      <description>&lt;h2&gt;
  
  
  From DEV to Substack: Continuing the Writing Journey
&lt;/h2&gt;

&lt;p&gt;I started writing technology articles in 2021.&lt;/p&gt;

&lt;p&gt;My first blog was published on DEV on May 30, 2021. At the time, the intention was simple: document my research and findings in one place, and share what I was learning along the way.&lt;/p&gt;

&lt;p&gt;I have always believed that technical knowledge should be free and accessible. That belief is one of the reasons I chose DEV instead of Medium. DEV felt open, community-driven, and aligned with the idea that engineering insights should not sit behind paywalls.&lt;/p&gt;

&lt;p&gt;Over the years, writing has helped me in ways I didn’t initially expect.&lt;/p&gt;

&lt;p&gt;✅ It forced me to structure my thinking more clearly.&lt;br&gt;
✅ It made me revisit assumptions.&lt;br&gt;
✅ It pushed me to explain production trade-offs more deliberately.&lt;/p&gt;

&lt;p&gt;Many of my posts, on resilience patterns, distributed systems, Git workflows, and engineering discipline, started as personal notes or project reflections. Writing turned those notes into structured knowledge.&lt;/p&gt;

&lt;p&gt;And for that, I’m grateful to the DEV community.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Started Missing
&lt;/h2&gt;

&lt;p&gt;As I continued writing, I began to notice something🤔&lt;/p&gt;

&lt;p&gt;While DEV provides visibility and discovery through its feed, I rarely receive direct or ongoing feedback from readers. Conversations are often limited to comments under a post. There isn’t a consistent way to stay connected with people who genuinely want to follow deeper discussions.&lt;/p&gt;

&lt;p&gt;Publishing on DEV sometimes feels like releasing something into a stream; it flows through the feed, gets engagement for a while, and then moves on.&lt;/p&gt;

&lt;p&gt;There’s nothing wrong with that model. It works well for discovery.&lt;/p&gt;

&lt;p&gt;But for topics like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Production engineering decisions&lt;/li&gt;
&lt;li&gt;Resilience strategies&lt;/li&gt;
&lt;li&gt;Delivery discipline&lt;/li&gt;
&lt;li&gt;Architectural trade-offs&lt;/li&gt;
&lt;li&gt;The subtle choices that influence DORA metrics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I started feeling the need for a more direct and intentional channel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I’m Expanding to Substack
&lt;/h2&gt;

&lt;p&gt;Recently, I started a Substack publication. ⭐️&lt;a href="https://akdevcraft.substack.com" rel="noopener noreferrer"&gt;Substack Publication&lt;/a&gt;⭐️&lt;/p&gt;

&lt;p&gt;This is not a move away from DEV. I will continue writing here.&lt;/p&gt;

&lt;p&gt;But Substack provides something different: direct communication.&lt;/p&gt;

&lt;p&gt;When a new article is published, subscribers receive notifications or emails. That creates a consistent and intentional connection between writer and reader. Instead of depending entirely on feed algorithms or timing, there is a direct channel for ongoing dialogue.&lt;/p&gt;

&lt;p&gt;For deeper engineering discussions, that matters.&lt;/p&gt;

&lt;p&gt;I’m hoping it allows:&lt;/p&gt;

&lt;p&gt;⭐️ More thoughtful feedback&lt;br&gt;
⭐️ More structured conversations&lt;br&gt;
⭐️ A recurring audience interested in production-grade engineering topics&lt;/p&gt;

&lt;p&gt;It feels like the next natural step in this writing journey.&lt;/p&gt;

&lt;h2&gt;
  
  
  Still Believing in Free Knowledge
&lt;/h2&gt;

&lt;p&gt;My core belief hasn’t changed.&lt;/p&gt;

&lt;p&gt;Knowledge should be free.&lt;br&gt;
Engineering insights should be accessible.&lt;/p&gt;

&lt;p&gt;I will continue publishing openly. Expanding to Substack is about communication and continuity — not exclusivity.&lt;/p&gt;

&lt;p&gt;DEV remains where this journey started. And it will continue to be part of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking Ahead
&lt;/h2&gt;

&lt;p&gt;Over the past few years, my writing has increasingly focused on the invisible decisions that shape software quality:&lt;/p&gt;

&lt;p&gt;⭐️ Branching strategies that quietly impact delivery velocity&lt;br&gt;
⭐️ Default configurations that hurt production performance&lt;br&gt;
⭐️ Resilience patterns that determine system stability&lt;br&gt;
⭐️ Engineering discipline that influences long-term scalability&lt;/p&gt;

&lt;p&gt;Substack gives me room to explore these themes more deeply while building a direct connection with readers who care about production-first engineering.&lt;/p&gt;

&lt;p&gt;Starting in 2021 on DEV was the first step.&lt;/p&gt;

&lt;p&gt;Expanding to Substack feels like the next one.&lt;/p&gt;

&lt;p&gt;If you’ve been reading my posts over the years, thank you!&lt;br&gt;
And if you’d like to continue the journey in a more direct format, you’re welcome to join me there. ⭐️&lt;a href="https://akdevcraft.substack.com" rel="noopener noreferrer"&gt;Substack Publication&lt;/a&gt;⭐️&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>software</category>
      <category>devjournal</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How Poor Git Branching Practices Quietly Damage Software Quality</title>
      <dc:creator>AK DevCraft</dc:creator>
      <pubDate>Mon, 16 Feb 2026 23:27:30 +0000</pubDate>
      <link>https://dev.to/akdevcraft/how-poor-git-branching-practices-quietly-damage-software-quality-nf7</link>
      <guid>https://dev.to/akdevcraft/how-poor-git-branching-practices-quietly-damage-software-quality-nf7</guid>
      <description>&lt;h2&gt;
  
  
  Your QA Didn’t Miss It — Your Branching Strategy Did
&lt;/h2&gt;

&lt;p&gt;A production bug that never appeared in QA is one of the most frustrating experiences in software engineering. Or a code commit that was never released in production.&lt;/p&gt;

&lt;p&gt;QA validated the feature.&lt;br&gt;
Staging looked stable.&lt;br&gt;
The release was approved.&lt;/p&gt;

&lt;p&gt;And yet, production behaved differently.&lt;/p&gt;

&lt;p&gt;The immediate reaction is predictable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;QA/Dev missed it.&lt;/li&gt;
&lt;li&gt;We need more regression coverage.&lt;/li&gt;
&lt;li&gt;Testing wasn’t thorough enough.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But in many enterprise systems, the real issue isn’t testing.&lt;/p&gt;

&lt;p&gt;It’s a branching strategy.&lt;/p&gt;

&lt;p&gt;I’ve seen cases where QA tested one version of the code, staging had subtle differences, and production ran yet another variation; all because environment-specific long-running branches quietly drifted apart over time.&lt;/p&gt;

&lt;p&gt;The result?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Production-only bugs&lt;/li&gt;
&lt;li&gt;Patch-on-patch hotfix chaos&lt;/li&gt;
&lt;li&gt;Loss of release confidence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn’t a test coverage problem.&lt;br&gt;
It’s a version control discipline problem.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Hidden Anti-Pattern: Environment-Based Branching
&lt;/h2&gt;

&lt;p&gt;In many enterprise setups, the repository looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;main
qa
staging
prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or worse&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feature → qa branch
feature → staging branch
feature → prod branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each environment maintains its own long-running branch.&lt;/p&gt;

&lt;p&gt;On paper, it sounds controlled.&lt;/p&gt;

&lt;p&gt;In reality, it creates code drift across environments.&lt;/p&gt;

&lt;p&gt;Over time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A hotfix is applied directly to prod&lt;/li&gt;
&lt;li&gt;A feature merges into qa but not yet into main&lt;/li&gt;
&lt;li&gt;Staging carries experimental tweaks&lt;/li&gt;
&lt;li&gt;Merge conflicts accumulate&lt;/li&gt;
&lt;li&gt;Re-merging the same logic across branches becomes routine&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now QA is testing one commit history.&lt;br&gt;
Production is running another.&lt;/p&gt;

&lt;p&gt;And when a production bug appears, it cannot be reproduced in QA because QA never tested that exact commit.&lt;/p&gt;

&lt;p&gt;Quality becomes non-deterministic.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why This Directly Impacts Software Quality
&lt;/h2&gt;

&lt;p&gt;Branching strategy is not just a Git preference.&lt;br&gt;
It is a quality control mechanism.&lt;/p&gt;

&lt;p&gt;When environments run different commit histories, several things break:&lt;/p&gt;
&lt;h3&gt;
  
  
  1️⃣ Deterministic Releases Disappear
&lt;/h3&gt;

&lt;p&gt;If the code in QA is not the exact same commit that goes to production, you lose release predictability.&lt;/p&gt;

&lt;p&gt;You are no longer promoting tested code — you are reconstructing it.&lt;/p&gt;
&lt;h3&gt;
  
  
  2️⃣ Regression Risk Increases
&lt;/h3&gt;

&lt;p&gt;When features are re-merged into multiple long-running branches, subtle behavioral differences can emerge.&lt;/p&gt;

&lt;p&gt;Same logic. Different surrounding context.&lt;/p&gt;

&lt;p&gt;That’s where elusive bugs are born.&lt;/p&gt;
&lt;h3&gt;
  
  
  3️⃣ Debugging Becomes Harder
&lt;/h3&gt;

&lt;p&gt;When production fails:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which branch is it running?&lt;/li&gt;
&lt;li&gt;What hotfix was applied?&lt;/li&gt;
&lt;li&gt;Was that merged back?&lt;/li&gt;
&lt;li&gt;Is QA aligned?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of investigating business logic, teams spend time investigating Git history.&lt;/p&gt;
&lt;h2&gt;
  
  
  CI/CD Maturity: Build Once, Promote Everywhere
&lt;/h2&gt;

&lt;p&gt;Modern delivery pipelines introduce a simple but powerful principle:&lt;/p&gt;

&lt;p&gt;Build once. Promote everywhere.&lt;/p&gt;

&lt;p&gt;The flow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feature → main
CI builds an artifact
Artifact promoted → QA → Staging → Prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No re-merging.&lt;br&gt;
No environment-specific code.&lt;br&gt;
No rebuilding for each environment.&lt;/p&gt;

&lt;p&gt;Only configuration changes across environments — not code.&lt;/p&gt;

&lt;p&gt;This ensures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Same commit&lt;/li&gt;
&lt;li&gt;Same artifact&lt;/li&gt;
&lt;li&gt;Same behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is real quality assurance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trunk-Based Development vs Branch-Heavy Models
&lt;/h2&gt;

&lt;p&gt;This is not about declaring one model universally superior.&lt;/p&gt;

&lt;p&gt;GitFlow and release branches can work in certain contexts, especially release-heavy or versioned products.&lt;/p&gt;

&lt;p&gt;The real problem emerges when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Branches are long-lived&lt;/li&gt;
&lt;li&gt;Integration is delayed&lt;/li&gt;
&lt;li&gt;Environments maintain independent code histories&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Trunk-based development, or short-lived feature branches, reduces that risk by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encouraging frequent integration&lt;/li&gt;
&lt;li&gt;Minimizing merge conflicts&lt;/li&gt;
&lt;li&gt;Reducing change size&lt;/li&gt;
&lt;li&gt;Increasing feedback speed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The smaller the batch size, the lower the failure probability.&lt;/p&gt;

&lt;p&gt;And that directly affects quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  The DORA Metrics Connection
&lt;/h2&gt;

&lt;p&gt;Branching strategy quietly influences engineering performance metrics.&lt;/p&gt;

&lt;p&gt;🚀 Lead Time for Changes&lt;/p&gt;

&lt;p&gt;Long-running branches delay integration and validation.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔁 Deployment Frequency
&lt;/h3&gt;

&lt;p&gt;Manual environment merges slow down releases.&lt;/p&gt;

&lt;h3&gt;
  
  
  💥 Change Failure Rate
&lt;/h3&gt;

&lt;p&gt;Branch drift increases production-only defects.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⏱️ Mean Time to Recovery
&lt;/h3&gt;

&lt;p&gt;Hotfix chaos increases recovery time because fixes must be reconciled across multiple branches.&lt;/p&gt;

&lt;p&gt;Branching discipline isn’t just a workflow preference; it directly impacts delivery performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  But What About Incomplete Features?
&lt;/h2&gt;

&lt;p&gt;One common fear is:&lt;/p&gt;

&lt;p&gt;“If we merge early, unfinished features might go live.”&lt;/p&gt;

&lt;p&gt;This is where feature flags become essential.&lt;/p&gt;

&lt;p&gt;Instead of isolating code in environment branches, you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Merge into main early&lt;/li&gt;
&lt;li&gt;Guard incomplete features with toggles&lt;/li&gt;
&lt;li&gt;Enable features selectively per environment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Continuous integration&lt;/li&gt;
&lt;li&gt;Safe rollout control&lt;/li&gt;
&lt;li&gt;No branch drift&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You preserve quality without sacrificing flexibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a Quality-Centric Branching Strategy Looks Like
&lt;/h2&gt;

&lt;p&gt;A simplified, quality-focused model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Single source of truth (main)&lt;/li&gt;
&lt;li&gt;Short-lived feature branches&lt;/li&gt;
&lt;li&gt;Mandatory pull request + CI validation&lt;/li&gt;
&lt;li&gt;Single artifact build&lt;/li&gt;
&lt;li&gt;Progressive promotion across environments&lt;/li&gt;
&lt;li&gt;Immediate merge-back of hotfixes into main&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The principle is simple:&lt;/p&gt;

&lt;p&gt;The same code commit version should run across all environments (QA, Staging, and production).&lt;/p&gt;

&lt;p&gt;Anything else introduces risk and sets up the team for failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;When a production bug appears that QA never saw, when we miss a commit to promote in prod, the instinct is to question testing. But sometimes, the tests were fine.&lt;br&gt;
The code that reached production was not the same as the code QA validated.&lt;/p&gt;

&lt;p&gt;Version control is not just a developer workflow decision. It is a software quality strategy.&lt;/p&gt;

&lt;p&gt;And if your environments are running different histories, you don’t have a testing problem; you have a branching problem.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have reached here, then I have made a satisfactory effort to keep you reading. Please be kind enough to leave any comments or share any corrections.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  My Other Blogs:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;⁠&lt;a href="https://dev.to/akdevcraft/playwright-and-cucumber-are-the-best-tools-for-end-to-end-testing-a28"&gt;Supercharge Your E2E Tests with Playwright and Cucumber Integration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/never-use-spring-restclient-default-implementation-in-production-100g"&gt;To Avoid Performance Impact Never Use Spring RestClient Default Implementation in Production&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/modern-devsecops-requires-more-than-one-tool-a-practical-sdlc-security-strategy-4d74"&gt;Modern DevSecOps Needs More Than One Tool: A Practical Secure SDLC Strategy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/shift-left-performance-testing-in-spring-boot-stability-through-control-5e01"&gt;Shift-Left Performance Testing in Spring Boot: Engineering Stability Before Scale&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/when-resilience-backfires-retry-and-circuit-breaker-in-spring-boot-10m"&gt;When Resilience Backfires: Retry and Circuit Breaker in Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/setup-graphql-mock-server-32fc"&gt;Setup GraphQL Mock Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/when-should-you-use-server-side-rendering-ssr-3a5a"&gt;When Should You Use Server-Side Rendering (SSR)?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/cracking-software-engineer-interview-mp3"&gt;Cracking Software Engineering Interviews&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
      <category>softwareengineering</category>
      <category>architecture</category>
      <category>programming</category>
    </item>
    <item>
      <title>Modern DevSecOps Needs More Than One Tool: Secure SDLC Strategy</title>
      <dc:creator>AK DevCraft</dc:creator>
      <pubDate>Sat, 14 Feb 2026 06:24:34 +0000</pubDate>
      <link>https://dev.to/akdevcraft/modern-devsecops-requires-more-than-one-tool-a-practical-sdlc-security-strategy-4d74</link>
      <guid>https://dev.to/akdevcraft/modern-devsecops-requires-more-than-one-tool-a-practical-sdlc-security-strategy-4d74</guid>
      <description>&lt;h2&gt;
  
  
  🧠 Background: Why Multiple Analysis Tools Became Necessary
&lt;/h2&gt;

&lt;p&gt;Not long ago, software delivery was simpler. Teams wrote code, ran a static analysis tool like SonarQube during the build, and deployed artifacts into controlled environments. Security checks were often centralized and performed toward the end of the release cycle, primarily focused on code-level defects.&lt;/p&gt;

&lt;p&gt;But modern software engineering has expanded far beyond source code.&lt;/p&gt;

&lt;p&gt;Today we ship containers, infrastructure-as-code, open-source dependencies, APIs, and increasingly AI-assisted code. Applications run across distributed systems and cloud-native platforms where risks can originate from many layers, base images, dependency chains, configuration drift, or exposed secrets.&lt;/p&gt;

&lt;p&gt;Because of this shift, relying on a single tool is no longer enough. Instead, teams need a layered analysis strategy, combining tools specialized for different risk areas across the SDLC.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔄 Security Tools Significance Across the SDLC
&lt;/h2&gt;

&lt;p&gt;Modern engineering teams embed analysis throughout the lifecycle, not just at release time, to reduce risk and provide fast feedback to developers.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧑‍💻 Development Phase – Code Quality &amp;amp; Secure Coding
&lt;/h3&gt;

&lt;p&gt;During local development and CI builds, static analysis tools help engineers catch issues early.&lt;/p&gt;

&lt;p&gt;Typical tools include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SonarQube/SonarCloud → Static code quality and maintainability checks&lt;/li&gt;
&lt;li&gt;Checkmarx/Fortify → SAST-focused security scanning&lt;/li&gt;
&lt;li&gt;Semgrep → Lightweight rule-based code and security analysis&lt;/li&gt;
&lt;li&gt;ESLint/PMD/SpotBugs → Language-specific linting and bug detection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These tools enforce coding standards and surface vulnerabilities before code even reaches pull requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔍 Pull Request Phase – Dependency &amp;amp; Supply Chain Security
&lt;/h3&gt;

&lt;p&gt;Most modern applications rely heavily on third-party libraries, making dependency scanning essential.&lt;/p&gt;

&lt;p&gt;Common tools used here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Snyk → Dependency vulnerability scanning integrated with Git workflows&lt;/li&gt;
&lt;li&gt;OWASP Dependency-Check → Open-source vulnerability scanning&lt;/li&gt;
&lt;li&gt;Dependabot/Renovate → Automated dependency updates and alerts&lt;/li&gt;
&lt;li&gt;GitHub Advanced Security → Secret scanning and dependency insights&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These tools prevent vulnerable libraries from silently entering production systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  📦 Artifact &amp;amp; Repository Phase – Binary &amp;amp; Policy Enforcement
&lt;/h3&gt;

&lt;p&gt;Once code is built, artifacts stored in repositories need governance and vulnerability checks.&lt;/p&gt;

&lt;p&gt;This is where tools like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JFrog Xray → Binary analysis, supply chain security, and policy enforcement&lt;/li&gt;
&lt;li&gt;Nexus IQ (Legacy in many organizations) → Repository scanning and governance&lt;/li&gt;
&lt;li&gt;JFrog Artifactory Policies → Artifact lifecycle enforcement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With container-based deployments growing rapidly, JFrog Xray has gained strong adoption due to its seamless integration with Docker images and artifact repositories, often replacing older repository-only tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  🐳 Container &amp;amp; Infrastructure Phase – Image and Runtime Security
&lt;/h3&gt;

&lt;p&gt;In cloud-native environments, vulnerabilities frequently originate from base images or OS layers rather than application code.&lt;/p&gt;

&lt;p&gt;Popular tools here include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JFrog Xray → Container image scanning integrated with repositories&lt;/li&gt;
&lt;li&gt;Trivy → Lightweight container and IaC vulnerability scanning&lt;/li&gt;
&lt;li&gt;Anchore/Grype → Deep container image analysis&lt;/li&gt;
&lt;li&gt;Aqua Security/Prisma Cloud → Runtime and container platform security&lt;/li&gt;
&lt;li&gt;Checkov/tfsec → Infrastructure-as-Code scanning for Terraform &amp;amp; cloud configs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These tools extend security coverage beyond code into the deployment ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚙️ Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Fast-moving teams often face pressure to ship quickly while maintaining security and quality. Large pull requests, distributed teams, and frequent releases increase the chance of issues slipping through unnoticed.&lt;/p&gt;

&lt;p&gt;⚡ TL;DR&lt;/p&gt;

&lt;p&gt;A multi-tool strategy transforms analysis from a gatekeeping exercise into a continuous feedback loop:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Static analysis catches code defects early&lt;/li&gt;
&lt;li&gt;Dependency scanners protect against supply chain risks&lt;/li&gt;
&lt;li&gt;Artifact scanning enforces governance&lt;/li&gt;
&lt;li&gt;Container and IaC tools secure deployment environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rather than slowing development, these tools collectively enable teams to move faster with confidence, supporting a true shift-left and shift-everywhere mindset.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have reached here, then I have made a satisfactory effort to keep you reading. Please be kind enough to leave any comments or share any corrections.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  My Other Blogs:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/shift-left-performance-testing-in-spring-boot-stability-through-control-5e01"&gt;Shift-Left Performance Testing in Spring Boot: Engineering Stability Before Scale&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/never-use-spring-restclient-default-implementation-in-production-100g"&gt;To Avoid Performance Impact Never Use Spring RestClient Default Implementation in Production&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/when-resilience-backfires-retry-and-circuit-breaker-in-spring-boot-10m"&gt;When Resilience Backfires: Retry and Circuit Breaker in Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/setup-graphql-mock-server-32fc"&gt;Setup GraphQL Mock Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⁠&lt;a href="https://dev.to/akdevcraft/playwright-and-cucumber-are-the-best-tools-for-end-to-end-testing-a28"&gt;Supercharge Your E2E Tests with Playwright and Cucumber Integration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/when-should-you-use-server-side-rendering-ssr-3a5a"&gt;When Should You Use Server-Side Rendering (SSR)?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/cracking-software-engineer-interview-mp3"&gt;Cracking Software Engineering Interviews&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>security</category>
      <category>cicd</category>
      <category>devops</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Spring Boot API Performance Automation Testing: Shift-Left With Gatling</title>
      <dc:creator>AK DevCraft</dc:creator>
      <pubDate>Sun, 23 Nov 2025 01:58:58 +0000</pubDate>
      <link>https://dev.to/akdevcraft/shift-left-performance-testing-in-spring-boot-stability-through-control-5e01</link>
      <guid>https://dev.to/akdevcraft/shift-left-performance-testing-in-spring-boot-stability-through-control-5e01</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Performance testing often comes too late in the Software Development Lifecycle, either after the code is merged, deployed, or when something starts slowing down in production.&lt;/p&gt;

&lt;p&gt;But what if performance testing doesn't have to wait until the end?&lt;br&gt;
What if it could run right inside your Spring Boot CI/CD pipeline, every time the code changes?&lt;/p&gt;

&lt;p&gt;That’s the essence of Shift Left Performance Testing, bringing load and latency validation closer to developers.&lt;br&gt;
And when you combine Gatling (for load simulation) with mocked dependencies (for stability), you get both speed and consistency in your performance results.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📬 &lt;strong&gt;I also write about production engineering and real-world system behavior in my newsletter.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If topics like resilience, distributed systems, and performance tuning interest you, you can subscribe here:&lt;br&gt;&lt;br&gt;
&lt;a href="https://akdevcraft.substack.com" rel="noopener noreferrer"&gt;📬 Subscribe to Newsletter&lt;/a&gt;🙏🏻&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;One of the biggest challenges with API performance testing is uncontrolled variables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;External APIs fluctuate in response time&lt;/li&gt;
&lt;li&gt;Databases may have inconsistent caching or data sizes&lt;/li&gt;
&lt;li&gt;Network latency varies per environment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When these factors change, your test results become inconsistent.&lt;br&gt;
You’re left wondering: Is my API slow, or was it the dependency this time?&lt;/p&gt;

&lt;p&gt;To catch genuine performance regressions, you need stable and repeatable test conditions, which means mocking what’s not under test.&lt;/p&gt;
&lt;h2&gt;
  
  
  ⚙️ Setting the Ground for Controlled Perf Testing
&lt;/h2&gt;

&lt;p&gt;To get predictable results, mock or simplify dependencies before running load tests.&lt;/p&gt;
&lt;h3&gt;
  
  
  Mock External APIs with WireMock
&lt;/h3&gt;

&lt;p&gt;If your Spring Boot API calls other services, say for authentication, pricing, or inventory, mock those dependencies using &lt;a href="https://www.wiremock.io/" rel="noopener noreferrer"&gt;WireMock&lt;/a&gt; or any other mocking framework.&lt;/p&gt;

&lt;p&gt;Wiremock example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@AutoConfigureWireMock&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8089&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@SpringBootTest&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductServiceIntegrationTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@BeforeEach&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setupMocks&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;stubFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;urlEqualTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/inventory/123"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;willReturn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aResponse&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withFixedDelay&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// Simulate 200ms latency&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withHeader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withBody&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{\"available\": true}"&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, every test run behaves exactly the same - same delay, same data, same outcome.&lt;br&gt;
That’s controlled performance testing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note - You can also use Wiremock's recording feature to record the response in a file so you don’t have to stub large object responses.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Use H2 for Database Mocking
&lt;/h3&gt;

&lt;p&gt;When your test focuses on the application or API layer, you don’t always need a full production-grade database.&lt;/p&gt;

&lt;p&gt;Using an in-memory database like H2 ensures consistency and isolation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;spring&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jdbc:h2:mem:testdb&lt;/span&gt;
    &lt;span class="na"&gt;driver-class-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;org.h2.Driver&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
    &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;jpa&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;hibernate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;ddl-auto&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;update&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can preload the same dataset before each run for reproducibility.&lt;br&gt;
It eliminates variability from query performance, network I/O, and DB load.&lt;/p&gt;
&lt;h3&gt;
  
  
  Gatling: Performance as Code
&lt;/h3&gt;

&lt;p&gt;Once your environment is stable, define your performance tests in &lt;a href="https://gatling.io/" rel="noopener noreferrer"&gt;Gatling&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  Maven Configuration for Gatling (Java DSL)
&lt;/h4&gt;

&lt;p&gt;pom.xml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;project&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Gatling core and HTTP modules --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.gatling&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;gatling-java&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.11.5&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.gatling&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;gatling-http&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.11.5&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- Gatling Maven Plugin --&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.gatling&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;gatling-maven-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;4.9.2&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;phase&amp;gt;&lt;/span&gt;verify&lt;span class="nt"&gt;&amp;lt;/phase&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Performance test
&lt;/h4&gt;

&lt;p&gt;You can create a separate folder in the project structure and organize all of the performance tests. Treat performance test just like production code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.gatling.javaapi.core.*&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.gatling.javaapi.http.*&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;gatling&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;javaapi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;core&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CoreDsl&lt;/span&gt;&lt;span class="o"&gt;.*;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;gatling&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;javaapi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;HttpDsl&lt;/span&gt;&lt;span class="o"&gt;.*;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductApiSimulation&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Simulation&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// Define the HTTP protocol&lt;/span&gt;
    &lt;span class="nc"&gt;HttpProtocolBuilder&lt;/span&gt; &lt;span class="n"&gt;httpProtocol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://localhost:8080"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Base URL of your Spring Boot service&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;acceptHeader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Define the scenario&lt;/span&gt;
    &lt;span class="nc"&gt;ScenarioBuilder&lt;/span&gt; &lt;span class="n"&gt;scn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scenario&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Get Products Scenario"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exec&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Get All Products"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/products"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;check&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;is&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;setUp&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;scn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;injectOpen&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;rampUsers&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;during&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// ✅ Warm-up over 2 mins&lt;/span&gt;
            &lt;span class="n"&gt;constantUsersPerSec&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;during&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// ✅ Sustain load for 15 mins&lt;/span&gt;
            &lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;protocols&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;httpProtocol&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;maxDuration&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ✅ Hard stop for safety&lt;/span&gt;
        &lt;span class="c1"&gt;// ✅ Add assertions for automated performance gating&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;assertions&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
           &lt;span class="n"&gt;global&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;responseTime&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;percentile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;95&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;lt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;  &lt;span class="c1"&gt;// 95% under 500ms&lt;/span&gt;
           &lt;span class="n"&gt;global&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;successfulRequests&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;percent&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;gt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;98.0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Error rate &amp;lt; 2%&lt;/span&gt;
       &lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Code Explanation
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;rampUsers(50).during(2 * 60)&lt;/code&gt; → Simulates a gradual load (50 users in 120 seconds).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;constantUsersPerSec(20).during(15 * 60)&lt;/code&gt; → maintain the load for 15 mins, quite obviously this is a high number, but we need to strike a balance between pipeline duration and enough load duration to perform the performance test on the application.&lt;/li&gt;
&lt;li&gt;check(status().is(200)) → Verifies each request returns HTTP 200.&lt;/li&gt;
&lt;li&gt;Assertions → Define performance thresholds. If breached:

&lt;ul&gt;
&lt;li&gt;The test fails,&lt;/li&gt;
&lt;li&gt;The pipeline breaks,&lt;/li&gt;
&lt;li&gt;Developers are notified before the code moves to the upper environment.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;To avoid a long pipeline run:&lt;/p&gt;

&lt;p&gt;✅ Run smoke performance tests on every PR for (30–60 sec)&lt;br&gt;
✅ Run long tests only on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;main branch&lt;/li&gt;
&lt;li&gt;nightly builds&lt;/li&gt;
&lt;li&gt;release candidates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GitHub action example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
  &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;cron&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;2&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*"&lt;/span&gt;  &lt;span class="c1"&gt;# nightly&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Why Assertions Matter
&lt;/h4&gt;

&lt;p&gt;These assertions turn your performance test into a quality gate.&lt;br&gt;
If response times exceed 500 ms or error rates go beyond 2%, the test fails automatically.&lt;/p&gt;

&lt;p&gt;This instantly alerts developers that a recent change has caused a performance regression — before it ever reaches production.&lt;/p&gt;

&lt;p&gt;No manual analysis, no post-deployment surprises.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note - “Define your performance thresholds/assertions based on realistic SLAs or baseline metrics, and review them periodically as your service evolves.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  🚀 Running the Test
&lt;/h4&gt;

&lt;p&gt;Once configured, you can run performance tests using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn gatling:test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Launch your Spring Boot API (if already running locally or in CI)&lt;/li&gt;
&lt;li&gt;Run the Gatling simulation (ProductApiSimulation.java)&lt;/li&gt;
&lt;li&gt;Generate an HTML report under:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;target/gatling/productapisimulation-&amp;lt;timestamp&amp;gt;/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fail the build automatically if assertions fail (e.g., high latency, low success rate)&lt;/p&gt;

&lt;h3&gt;
  
  
  🧩 Bringing It into the CI/CD Pipeline
&lt;/h3&gt;

&lt;p&gt;The real power of Shift Left testing comes when performance runs automatically in your pipeline — just like unit or integration tests.&lt;/p&gt;

&lt;p&gt;Here’s an example using GitHub Actions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Performance Tests&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;release/*"&lt;/span&gt;   &lt;span class="c1"&gt;# Run only on release branches to avoid long runs on every commit&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;main"&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# Allow manual trigger&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;performance-test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up JDK &lt;/span&gt;&lt;span class="m"&gt;17&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-java@v3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;java-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;17"&lt;/span&gt;
          &lt;span class="na"&gt;distribution&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temurin"&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build Spring Boot app&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./mvnw clean package -DskipTests&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Gatling performance tests&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./mvnw gatling:test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This setup:&lt;br&gt;
✅ Runs automatically on main or release branches&lt;br&gt;
✅ Can be triggered manually for controlled environments&lt;br&gt;
✅ Produces Gatling HTML reports as pipeline artifacts&lt;br&gt;
✅ Fails the pipeline automatically if performance thresholds are breached&lt;/p&gt;

&lt;p&gt;To keep pipelines lean, run these tests only on main, release, or nightly builds — not every feature branch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why This Approach Works
&lt;/h3&gt;

&lt;p&gt;When you combine stable mocks, assertions, and CI integration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You get consistent metrics across builds&lt;/li&gt;
&lt;li&gt;You isolate application performance from dependency noise&lt;/li&gt;
&lt;li&gt;You catch regressions early with automatic thresholds&lt;/li&gt;
&lt;li&gt;You build confidence without extending pipeline times unnecessarily&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is how teams move from reactive performance firefighting to proactive performance assurance.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏁 Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Shift-left performance testing isn’t about running massive load tests earlier; it’s about running smarter, smaller, and stable tests continuously.&lt;/p&gt;

&lt;p&gt;By combining:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spring Boot for your core service&lt;/li&gt;
&lt;li&gt;WireMock for predictable external calls&lt;/li&gt;
&lt;li&gt;H2 for stable DB interactions&lt;/li&gt;
&lt;li&gt;Gatling for performance-as-code&lt;/li&gt;
&lt;li&gt;Assertions to enforce performance budgets&lt;/li&gt;
&lt;li&gt;CI/CD filters to run tests only where needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You achieve repeatable, reliable, and developer-owned performance validation.&lt;/p&gt;

&lt;p&gt;That’s not just testing earlier — it’s building performance culture into the pipeline.&lt;/p&gt;

&lt;p&gt;⚡ TL;DR&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shift left = move performance testing closer to code commits.&lt;/li&gt;
&lt;li&gt;Mock dependencies (WireMock, H2) → get stable, repeatable results.&lt;/li&gt;
&lt;li&gt;Use Gatling → define performance as code.&lt;/li&gt;
&lt;li&gt;Add assertions → fail builds when thresholds break.&lt;/li&gt;
&lt;li&gt;Configure CI/CD → run only on main/release branches.&lt;/li&gt;
&lt;li&gt;Focus on early detection, not end-stage firefighting.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have reached here, then I have made a satisfactory effort to keep you reading. Please be kind enough to leave any comments or share with corrections.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  My Other Blogs:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/never-use-spring-restclient-default-implementation-in-production-100g"&gt;To Avoid Performance Impact Never Use Spring RestClient Default Implementation in Production&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/when-resilience-backfires-retry-and-circuit-breaker-in-spring-boot-10m"&gt;When Resilience Backfires: Retry and Circuit Breaker in Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/setup-graphql-mock-server-32fc"&gt;Setup GraphQL Mock Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⁠&lt;a href="https://dev.to/akdevcraft/playwright-and-cucumber-are-the-best-tools-for-end-to-end-testing-a28"&gt;Supercharge Your E2E Tests with Playwright and Cucumber Integration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/when-should-you-use-server-side-rendering-ssr-3a5a"&gt;When Should You Use Server-Side Rendering (SSR)?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/cracking-software-engineer-interview-mp3"&gt;Cracking Software Engineering Interviews&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/test-soap-web-service-using-postman-tool-171k"&gt;Test SOAP Web Service using Postman Tool&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>springboot</category>
      <category>java</category>
      <category>microservices</category>
      <category>restapi</category>
    </item>
    <item>
      <title>Spring RestClient Defaults Don’t Scale in Production: Improve API Performance</title>
      <dc:creator>AK DevCraft</dc:creator>
      <pubDate>Sun, 12 Oct 2025 07:58:58 +0000</pubDate>
      <link>https://dev.to/akdevcraft/never-use-spring-restclient-default-implementation-in-production-100g</link>
      <guid>https://dev.to/akdevcraft/never-use-spring-restclient-default-implementation-in-production-100g</guid>
      <description>&lt;h2&gt;
  
  
  🚨 Problem Introduction
&lt;/h2&gt;

&lt;p&gt;Imagine you’re building a SpringBoot Order API that calls three downstream services:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inventory Service&lt;/li&gt;
&lt;li&gt;Pricing Service&lt;/li&gt;
&lt;li&gt;Shipping Service&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You decide to use Spring’s new RestClient (Spring 6 / Boot 3). Locally, everything works perfectly fine. But in production, under load, issues appear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Requests pile up&lt;/li&gt;
&lt;li&gt;Threads block waiting for connections&lt;/li&gt;
&lt;li&gt;Users face delays and even timeouts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How would you prevent the performance impact, or in other words, improve the performance of your application?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📬 &lt;strong&gt;I also write about production engineering and real-world system behavior in my newsletter.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If topics like resilience, distributed systems, and performance tuning interest you, you can subscribe here:&lt;br&gt;&lt;br&gt;
&lt;a href="https://akdevcraft.substack.com" rel="noopener noreferrer"&gt;📬 Subscribe to Newsletter&lt;/a&gt;🙏🏻&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What’s going on?
&lt;/h3&gt;

&lt;p&gt;🔎 As most likely you know, based on my previous blog &lt;a href="https://dev.to/akdevcraft/never-use-spring-resttemplate-default-implementation-2ghj"&gt;Avoid Spring RestTemplate Default Implementation to Prevent Performance Impact&lt;/a&gt;. The&lt;br&gt;
RestTemplate defaults to only 2 total global connections (without Apache HttpClient tuning).&lt;/p&gt;

&lt;p&gt;Welp! RestClient defaults do slightly better with 5 per-host connections.&lt;/p&gt;

&lt;p&gt;👉 But that’s still tiny for production load.&lt;br&gt;
If 100 users call your service simultaneously:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only 5 calls to downstream services can proceed&lt;/li&gt;
&lt;li&gt;95 calls sit waiting in the connection queue&lt;/li&gt;
&lt;li&gt;Latency spikes&lt;/li&gt;
&lt;li&gt;Errors creep in&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why things work locally but fail under load — you’re bottlenecked by the connection pool defaults.&lt;/p&gt;
&lt;h3&gt;
  
  
  🧪 Conceptual Benchmark
&lt;/h3&gt;

&lt;p&gt;Scenario: 100 concurrent requests from OrderService → InventoryService&lt;/p&gt;

&lt;p&gt;With Default RestClient (5 connections/host):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only 5 requests proceed at a time.&lt;/li&gt;
&lt;li&gt;95 requests wait&lt;/li&gt;
&lt;li&gt;Latency grows&lt;/li&gt;
&lt;li&gt;Timeouts are likely under heavy load&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tuned RestClient (150 total, 50 per-host):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pool size reflects expected traffic — e.g., ~150 active users per second.&lt;/li&gt;
&lt;li&gt;Up to 50 concurrent requests per external service can proceed in parallel.&lt;/li&gt;
&lt;li&gt;The remaining requests queue briefly, but overall throughput remains smooth.&lt;/li&gt;
&lt;li&gt;Response times stay predictable and stable.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;The point isn’t the exact number (150 or 50) — it’s about matching pool capacity to your app’s concurrency profile.&lt;br&gt;
Your pool size should be proportional to peak concurrent users and downstream service latency.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  ✅ The Solution
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Add Dependency
&lt;/h3&gt;

&lt;p&gt;Apache HttpClient 5 dependency in the project, maven example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
 &lt;span class="c"&gt;&amp;lt;!-- Apache HttpClient 5 (for advanced pooling, timeouts, etc.) --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.httpcomponents.client5&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;httpclient5&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Code Update
&lt;/h3&gt;

&lt;p&gt;Configure your own HTTP connection pool&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.hc.client5.http.impl.classic.CloseableHttpClient&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.hc.client5.http.impl.classic.HttpClients&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.http.client.HttpComponentsClientHttpRequestFactory&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.client.RestClient&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RestClientConfig&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;RestClient&lt;/span&gt; &lt;span class="nf"&gt;restClient&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;PoolingHttpClientConnectionManager&lt;/span&gt; &lt;span class="n"&gt;connectionManager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PoolingHttpClientConnectionManager&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;connectionManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setMaxTotal&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;          &lt;span class="c1"&gt;// total connections&lt;/span&gt;
        &lt;span class="n"&gt;connectionManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDefaultMaxPerRoute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// per-host connections&lt;/span&gt;

        &lt;span class="nc"&gt;CloseableHttpClient&lt;/span&gt; &lt;span class="n"&gt;httpClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HttpClients&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;custom&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setConnectionManager&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connectionManager&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;RestClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;requestFactory&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HttpComponentsClientHttpRequestFactory&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;httpClient&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ⚙️ Bonus: Don’t Forget the Timeouts
&lt;/h3&gt;

&lt;p&gt;Even with connection pooling tuned, your app can still hang if remote services become slow.&lt;br&gt;
That’s where timeouts come in — they protect threads from waiting indefinitely.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.hc.client5.http.config.RequestConfig&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.hc.client5.http.impl.classic.CloseableHttpClient&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.hc.client5.http.impl.classic.HttpClients&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.http.client.HttpComponentsClientHttpRequestFactory&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.client.RestClient&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RestClientConfig&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;RestClient&lt;/span&gt; &lt;span class="nf"&gt;restClient&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;PoolingHttpClientConnectionManager&lt;/span&gt; &lt;span class="n"&gt;connectionManager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PoolingHttpClientConnectionManager&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;connectionManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setMaxTotal&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;connectionManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDefaultMaxPerRoute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;RequestConfig&lt;/span&gt; &lt;span class="n"&gt;requestConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RequestConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;custom&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setConnectTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;            &lt;span class="c1"&gt;// time to establish connection (ms)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setResponseTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;           &lt;span class="c1"&gt;// time waiting for server response (ms)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setConnectionRequestTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// time to wait for connection from pool (ms)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;CloseableHttpClient&lt;/span&gt; &lt;span class="n"&gt;httpClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HttpClients&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;custom&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setConnectionManager&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connectionManager&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDefaultRequestConfig&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requestConfig&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;RestClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;requestFactory&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HttpComponentsClientHttpRequestFactory&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;httpClient&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  💡 Quick Notes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Timeouts above are in milliseconds (2000 ms = 2 seconds)&lt;/li&gt;
&lt;li&gt;connectTimeout: protects you from unresponsive hosts.&lt;/li&gt;
&lt;li&gt;connectionRequestTimeout: stops threads from waiting too long for a pooled connection.&lt;/li&gt;
&lt;li&gt;responseTimeout: prevents hanging on slow downstream responses.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Combined with a tuned connection pool, these timeouts make your RestClient fast, safe, and production-hardened.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion - Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;RestTemplate default = 2 global connections.&lt;/li&gt;
&lt;li&gt;RestClient default = 5 per-host connections.&lt;/li&gt;
&lt;li&gt;Configured pool = production-safe scaling.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⚠️ Never trust defaults for HTTP clients. They’re tuned for safety in local/dev, not performance in production.&lt;/p&gt;

&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;RestClient (Spring Boot 3 / Spring 6) is better than RestTemplate, but still not production-ready out of the box.&lt;/li&gt;
&lt;li&gt;Default pool size = 5 per host → easily becomes a bottleneck under load.&lt;/li&gt;
&lt;li&gt;Always configure:

&lt;ul&gt;
&lt;li&gt;✅ Connection pool size (maxTotal, maxPerRoute)&lt;/li&gt;
&lt;li&gt;✅ Timeouts (connect, request, read)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Keep your RestClient tuned, and it’ll handle thousands of concurrent requests gracefully.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;💡 In short:&lt;br&gt;
Spring’s RestClient is powerful — but like any engine, it needs tuning before you take it to production.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have reached here, then I have made a satisfactory effort to keep you reading. Please be kind enough to leave any comments or share any corrections.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  My Other Blogs:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/akdevcraft/shift-left-performance-testing-in-spring-boot-stability-through-control-5e01"&gt;Shift Left Performance Testing in Spring Boot: Stability Through Control&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/when-resilience-backfires-retry-and-circuit-breaker-in-spring-boot-10m"&gt;When Resilience Backfires: Retry and Circuit Breaker in Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/setup-graphql-mock-server-32fc"&gt;Setup GraphQL Mock Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⁠&lt;a href="https://dev.to/akdevcraft/playwright-and-cucumber-are-the-best-tools-for-end-to-end-testing-a28"&gt;Supercharge Your E2E Tests with Playwright and Cucumber Integration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/when-should-you-use-server-side-rendering-ssr-3a5a"&gt;When Should You Use Server-Side Rendering (SSR)?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/cracking-software-engineer-interview-mp3"&gt;Cracking Software Engineering Interviews&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/micro-frontend-decision-framework-26hf/edit"&gt;Micro-Frontend Decision Framework&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akdevcraft/test-soap-web-service-using-postman-tool-171k"&gt;Test SOAP Web Service using Postman Tool&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>springboot</category>
      <category>java</category>
      <category>microservices</category>
      <category>spring</category>
    </item>
  </channel>
</rss>
