<?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: Karam Khoury</title>
    <description>The latest articles on DEV Community by Karam Khoury (@karamkhoury88).</description>
    <link>https://dev.to/karamkhoury88</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4045189%2Fe44cb307-6c08-4fc0-8ff8-6bf3fa1dbfcc.png</url>
      <title>DEV Community: Karam Khoury</title>
      <link>https://dev.to/karamkhoury88</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/karamkhoury88"/>
    <language>en</language>
    <item>
      <title>MCP vs RAG: Two AI Buzzwords, Explained Without the Buzzwords</title>
      <dc:creator>Karam Khoury</dc:creator>
      <pubDate>Thu, 06 Aug 2026 12:33:37 +0000</pubDate>
      <link>https://dev.to/karamkhoury88/mcp-vs-rag-two-ai-buzzwords-explained-without-the-buzzwords-d2h</link>
      <guid>https://dev.to/karamkhoury88/mcp-vs-rag-two-ai-buzzwords-explained-without-the-buzzwords-d2h</guid>
      <description>&lt;p&gt;A few weeks ago, a junior engineer on my team asked me: "Should we use RAG or MCP for this feature?"&lt;/p&gt;

&lt;p&gt;He said it like the two were competing options. Like picking between React and Vue.&lt;/p&gt;

&lt;p&gt;They're not. One is about &lt;strong&gt;giving an AI knowledge&lt;/strong&gt;. The other is about &lt;strong&gt;giving an AI hands&lt;/strong&gt;. Once you see that difference, the buzzwords stop being scary.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Concept, in One Line Each
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;RAG (Retrieval-Augmented Generation):&lt;/strong&gt; Before the AI answers you, it goes and &lt;em&gt;reads&lt;/em&gt; relevant documents first, then writes its answer based on what it just read.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP (Model Context Protocol):&lt;/strong&gt; A standard way for an AI to &lt;em&gt;connect to and use&lt;/em&gt; outside tools — like your calendar, your database, or your file system — instead of just talking about them.&lt;/p&gt;

&lt;p&gt;Here's the simplest way to picture it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RAG:  Question -&amp;gt; Search your documents -&amp;gt; Read the best matches -&amp;gt; Answer
MCP:  Question -&amp;gt; Call a real tool (email, calendar, database) -&amp;gt; Get a real result -&amp;gt; Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;RAG makes the AI &lt;strong&gt;smarter about what it knows&lt;/strong&gt;.&lt;br&gt;
MCP makes the AI &lt;strong&gt;capable of doing something&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where They're Similar
&lt;/h3&gt;

&lt;p&gt;Both exist to fix the same core problem: an AI, by itself, only knows what it was trained on, up to a certain date. It can't see your company's internal wiki. It can't see today's stock price. It can't see the email that just landed in your inbox.&lt;/p&gt;

&lt;p&gt;Both RAG and MCP are ways of feeding an AI &lt;em&gt;fresh, outside information&lt;/em&gt; at the moment you ask your question, instead of relying only on what it memorized during training.&lt;/p&gt;

&lt;p&gt;That's the whole family resemblance. After that, they split in very different directions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where They're Different
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;RAG is about reading. MCP is about acting.&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;RAG&lt;/th&gt;
&lt;th&gt;MCP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;What it does&lt;/td&gt;
&lt;td&gt;Finds and reads relevant text&lt;/td&gt;
&lt;td&gt;Connects to and operates a tool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical use&lt;/td&gt;
&lt;td&gt;"Answer using our documents"&lt;/td&gt;
&lt;td&gt;"Book this meeting" or "Update this record"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Output&lt;/td&gt;
&lt;td&gt;Better, more accurate answers&lt;/td&gt;
&lt;td&gt;Real actions with real side effects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Example source&lt;/td&gt;
&lt;td&gt;A PDF, a knowledge base, a set of notes&lt;/td&gt;
&lt;td&gt;A calendar app, an email inbox, a database&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Think of RAG as a &lt;strong&gt;very fast research assistant&lt;/strong&gt;. You ask a question, they run to the library, grab the three most relevant pages, and hand them to you before you even finish your coffee.&lt;/p&gt;

&lt;p&gt;Think of MCP as a &lt;strong&gt;universal remote control&lt;/strong&gt;. It doesn't know anything by itself — but it can press the right buttons on whichever device you point it at: your calendar, your CRM, your ticketing system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where To Use Each
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Use RAG when the problem is "the AI doesn't know this."&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A customer support bot that needs to answer questions using your product manuals.&lt;/li&gt;
&lt;li&gt;A legal assistant that needs to reference your actual contracts, not generic legal knowledge.&lt;/li&gt;
&lt;li&gt;An internal chatbot that answers HR questions using your company's real policy documents.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use MCP when the problem is "the AI needs to do this."&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An assistant that checks your real calendar and books a meeting for you.&lt;/li&gt;
&lt;li&gt;A support agent that actually creates a ticket in your helpdesk system, not just describes one.&lt;/li&gt;
&lt;li&gt;A coding assistant that reads your real files and runs your real tests, instead of guessing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use both when you need an AI that is both well-informed and useful.&lt;/strong&gt; A great example: a customer support AI that uses RAG to pull the correct refund policy from your documents, then uses MCP to actually process the refund in your billing system.&lt;/p&gt;




&lt;h3&gt;
  
  
  A Real-Life Example
&lt;/h3&gt;

&lt;p&gt;Imagine you run an online store and you build an AI assistant for customer support.&lt;/p&gt;

&lt;p&gt;A customer asks: &lt;em&gt;"What's your return policy for items bought during the sale, and can you start my return?"&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RAG&lt;/strong&gt; kicks in first. It searches your actual return policy documents, finds the section about sale items (which usually has different rules than regular items), and pulls the exact, correct answer instead of a generic guess.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP&lt;/strong&gt; kicks in next. It connects to your order management system, finds the customer's real order, and actually starts the return process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without RAG, the AI might confidently give the wrong policy. Without MCP, the AI could only &lt;em&gt;tell&lt;/em&gt; the customer how to start a return, not &lt;em&gt;actually&lt;/em&gt; start it. Together, the customer gets a correct answer and a completed action, in one conversation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Impact for Your Team
&lt;/h2&gt;

&lt;p&gt;Getting this distinction right changes how you scope a project.&lt;/p&gt;

&lt;p&gt;If a stakeholder says "make the AI smarter about our documents," that's a RAG problem — you're building a search-and-retrieve pipeline over your content.&lt;/p&gt;

&lt;p&gt;If they say "make the AI actually do things in our systems," that's an MCP problem — you're building integrations and giving the AI safe, well-defined tools to call.&lt;/p&gt;

&lt;p&gt;Confusing the two leads to wasted sprints: teams building elaborate document search when what the business actually wanted was for the AI to update a record, or vice versa.&lt;/p&gt;

&lt;h2&gt;
  
  
  Actionable Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;RAG = knowledge.&lt;/strong&gt; Use it when the AI needs facts it wasn't trained on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP = capability.&lt;/strong&gt; Use it when the AI needs to perform a real action in a real system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;They're not rivals.&lt;/strong&gt; Most serious AI products end up using both together.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope your project by the verb.&lt;/strong&gt; "Answer using X" → RAG. "Do X" → MCP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start small.&lt;/strong&gt; Pick one document set for RAG, or one tool for MCP, prove it works, then expand.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you strip away the acronyms, both ideas are things you already understand: look it up before you answer, and use the right tool for the job.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>rag</category>
      <category>mcp</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Concurrency vs Parallelism: A Simple Guide</title>
      <dc:creator>Karam Khoury</dc:creator>
      <pubDate>Tue, 04 Aug 2026 06:44:36 +0000</pubDate>
      <link>https://dev.to/karamkhoury88/concurrency-vs-parallelism-a-simple-guide-33l9</link>
      <guid>https://dev.to/karamkhoury88/concurrency-vs-parallelism-a-simple-guide-33l9</guid>
      <description>&lt;h2&gt;
  
  
  Concurrency: juggling tasks
&lt;/h2&gt;

&lt;p&gt;Think of concurrency like a chef in a busy kitchen. The chef doesn't cook all dishes at the exact same time — they chop some vegetables, stir a pot, check the oven, and go back to chopping. They make progress on multiple tasks by switching between them quickly.&lt;/p&gt;

&lt;p&gt;In computing, concurrency means a system can handle multiple tasks overlapping in time, but not necessarily running at the same instant.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tasks take turns (like a single CPU core switching between processes).&lt;/li&gt;
&lt;li&gt;Useful when tasks involve waiting (downloading files, handling user input).&lt;/li&gt;
&lt;li&gt;Common in applications like web servers that manage many users at once.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Parallelism: doing tasks side by side
&lt;/h2&gt;

&lt;p&gt;Now imagine two chefs in the same kitchen. One chops vegetables while the other grills meat — both working at the same time.&lt;/p&gt;

&lt;p&gt;That's parallelism: tasks actually running simultaneously, using multiple resources (like multiple CPU cores).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tasks run truly at the same time.&lt;/li&gt;
&lt;li&gt;Requires hardware support (multi-core processors, GPUs).&lt;/li&gt;
&lt;li&gt;Used for heavy computation (video encoding, scientific simulations).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Real-world examples
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Concurrency:&lt;/strong&gt; a chat app handling thousands of messages — it switches between users so fast it seems instant.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallelism:&lt;/strong&gt; a weather-forecast model running calculations across multiple CPUs to predict storms faster.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When to use each
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;concurrency&lt;/strong&gt; when tasks involve waiting (I/O, network requests).&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;parallelism&lt;/strong&gt; when you need brute-force speed (data processing, rendering).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Concurrency&lt;/strong&gt; = managing multiple tasks efficiently (even on a single core).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallelism&lt;/strong&gt; = executing multiple tasks at the same time (needs multiple cores).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both are essential in modern software, and understanding them helps you write faster, more responsive programs.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by Karam Khoury — Lead Software Engineer (.NET &amp;amp; Azure) with 14+ years building secure, scalable fintech systems. More at &lt;a href="https://karamkhoury.me" rel="noopener noreferrer"&gt;karamkhoury.me&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>parallelism</category>
      <category>concurrency</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>AWS Introduction for Beginner Software Engineers</title>
      <dc:creator>Karam Khoury</dc:creator>
      <pubDate>Tue, 04 Aug 2026 06:39:39 +0000</pubDate>
      <link>https://dev.to/karamkhoury88/aws-introduction-for-beginner-software-engineers-4ec5</link>
      <guid>https://dev.to/karamkhoury88/aws-introduction-for-beginner-software-engineers-4ec5</guid>
      <description>&lt;p&gt;As a software engineer starting with AWS, you might feel overwhelmed by all the services. Let me break down the key components with real-world examples to help you get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. DNS &amp;amp; How AWS Route 53 Works
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Users can't remember IP addresses like &lt;code&gt;54.210.167.101&lt;/code&gt; for your app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; AWS Route 53 (DNS service) maps &lt;code&gt;yourdomain.com&lt;/code&gt; to your servers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real example:&lt;/strong&gt; Your startup has servers in Ohio and Frankfurt. Route 53 automatically sends European users to Frankfurt and routes US traffic to Ohio — faster load times for everyone.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Networking: VPC &amp;amp; Subnets
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VPC:&lt;/strong&gt; Your private cloud network (like an office building).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public subnet:&lt;/strong&gt; For web servers (needs internet access).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private subnet:&lt;/strong&gt; For databases (blocked from direct internet access).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Internet Gateway:&lt;/strong&gt; Connects public subnets to the internet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NAT Gateway:&lt;/strong&gt; Lets private subnets reach the internet (one-way).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Real example:&lt;/strong&gt; In your e-commerce app, the web server runs in a public subnet while the database sits in a private subnet.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Storing &amp;amp; Delivering Static Files (S3 + CloudFront)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Amazon S3:&lt;/strong&gt; Stores images, videos, and logs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudFront (CDN):&lt;/strong&gt; Caches content globally for faster loading.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Real example:&lt;/strong&gt; Your blog hosts images in S3; CloudFront caches them in 450+ locations, so a reader in Tokyo gets images from Japan instead of Virginia — cutting load time by ~50%.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro tip:&lt;/strong&gt; Enable S3 Versioning to recover accidentally deleted files.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Running Backend Services
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AWS Lambda (Serverless)&lt;/strong&gt; — best for event-driven tasks. &lt;em&gt;Example:&lt;/em&gt; a photo app resizes images automatically on upload.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EC2 (Virtual Servers)&lt;/strong&gt; — best for full control (custom OS, legacy apps). &lt;em&gt;Example:&lt;/em&gt; hosting a Java monolith with specific dependencies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ECS/EKS (Containers)&lt;/strong&gt; — best for microservices (Docker/Kubernetes). &lt;em&gt;Example:&lt;/em&gt; a food-delivery app with separate services for orders, payments, and tracking.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Databases: Picking the Right One
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Amazon RDS (SQL):&lt;/strong&gt; Structured data with relationships — e.g. user accounts + orders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DynamoDB (NoSQL):&lt;/strong&gt; High-speed, scalable lookups — e.g. a ride-sharing app tracking real-time driver locations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aurora (High-Performance SQL):&lt;/strong&gt; Low-latency apps — e.g. stock-trading platforms.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. Adding AI/ML to Your App
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Amazon Bedrock (pre-trained AI):&lt;/strong&gt; e.g. a customer-support chatbot trained on your FAQ docs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SageMaker (custom ML models):&lt;/strong&gt; e.g. a recommendation engine ("users who bought X also liked Y").&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. Security Essentials
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VPC:&lt;/strong&gt; Controls how your networking works — what can connect to what, what reaches the internet, and what stays private.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NACLs (Network ACLs):&lt;/strong&gt; A firewall for an entire subnet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Groups:&lt;/strong&gt; A firewall for each specific instance or service.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IAM (Identity &amp;amp; Access Management):&lt;/strong&gt; Controls who can access what.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Golden rule — least privilege:&lt;/strong&gt; a Lambda function should only access the one DynamoDB table it needs; backup processes get read-only access; only DevOps can reach production databases.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Monitoring &amp;amp; Debugging
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch:&lt;/strong&gt; Tracks performance metrics and logs (EC2 CPU, Lambda errors). &lt;em&gt;Example:&lt;/em&gt; alert when database CPU hits 90%.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudTrail:&lt;/strong&gt; Audit logs ("who changed IAM policies?", "who deleted an S3 bucket?") — critical for compliance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Putting it all together
&lt;/h2&gt;

&lt;p&gt;Imagine building "Twitter Lite":&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Route 53 routes users to the nearest server.&lt;/li&gt;
&lt;li&gt;CloudFront + S3 deliver profile pictures fast.&lt;/li&gt;
&lt;li&gt;EC2 or Lambda runs the backend API.&lt;/li&gt;
&lt;li&gt;DynamoDB stores tweets for instant loading.&lt;/li&gt;
&lt;li&gt;CloudWatch alerts you if something breaks.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Next steps for beginners
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Hands-on:&lt;/strong&gt; try the AWS Free Tier (12 months free).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;First project:&lt;/strong&gt; deploy a static website on S3 + CloudFront.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deep dive:&lt;/strong&gt; learn Lambda + DynamoDB.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;em&gt;Written by Karam Khoury — Lead Software Engineer (.NET &amp;amp; Azure) with 14+ years building secure, scalable fintech systems. More at &lt;a href="https://karamkhoury.me" rel="noopener noreferrer"&gt;karamkhoury.me&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Oops, I Committed a Secret: A Calm Guide to Scrubbing Git History</title>
      <dc:creator>Karam Khoury</dc:creator>
      <pubDate>Fri, 24 Jul 2026 12:00:25 +0000</pubDate>
      <link>https://dev.to/karamkhoury88/oops-i-committed-a-secret-a-calm-guide-to-scrubbing-git-history-38ll</link>
      <guid>https://dev.to/karamkhoury88/oops-i-committed-a-secret-a-calm-guide-to-scrubbing-git-history-38ll</guid>
      <description>&lt;p&gt;You just finished a great feature. You're in the flow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Fixed the bug!"&lt;/span&gt;
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you see it, staring back from the GitHub UI: your live API key. 💀&lt;/p&gt;

&lt;p&gt;We've all been there. Here's the calm, correct order of operations — from "quick save" for a mistake you caught instantly, to the deep clean for a secret that's been buried in history for months.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 0: Rotate the secret first (yes, before anything else)
&lt;/h2&gt;

&lt;p&gt;This is the step people skip, and it's the only one that's non-negotiable. &lt;strong&gt;The moment a secret hits a remote, assume it's compromised.&lt;/strong&gt; Bots scrape public GitHub for credentials within &lt;em&gt;seconds&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So before you touch history:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Revoke / rotate&lt;/strong&gt; the leaked key, token, or password at its source (AWS, Stripe, your DB, wherever).&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Then&lt;/em&gt; clean the repo.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Cleaning history without rotating is like changing the locks after posting the old key online. Rotate first, always.&lt;/p&gt;

&lt;h2&gt;
  
  
  Case 1: You caught it before pushing (the quick save)
&lt;/h2&gt;

&lt;p&gt;If the secret is only in your &lt;strong&gt;last, un-pushed commit&lt;/strong&gt;, this is trivial:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Stop tracking the file and ignore it going forward&lt;/span&gt;
git &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;--cached&lt;/span&gt; .env
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;".env"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .gitignore

&lt;span class="c"&gt;# Fold the fix into the last commit&lt;/span&gt;
git commit &lt;span class="nt"&gt;--amend&lt;/span&gt; &lt;span class="nt"&gt;--no-edit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Done. Nothing left the building. (Still rotate the key if it was ever real.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Case 2: It's deep in history, or already pushed (the deep clean)
&lt;/h2&gt;

&lt;p&gt;Once the secret is several commits back — or on the remote — you need to rewrite history. The modern, recommended tool is &lt;strong&gt;&lt;code&gt;git filter-repo&lt;/code&gt;&lt;/strong&gt; (Git's own docs now steer you here instead of the old &lt;code&gt;filter-branch&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install (Python)&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;git-filter-repo

&lt;span class="c"&gt;# Option A: remove a whole file from ALL history&lt;/span&gt;
git filter-repo &lt;span class="nt"&gt;--path&lt;/span&gt; config/secrets.yml &lt;span class="nt"&gt;--invert-paths&lt;/span&gt;

&lt;span class="c"&gt;# Option B: redact a specific string everywhere it appears&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'AKIAIOSFODNN7EXAMPLE==&amp;gt;REDACTED'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; replacements.txt
git filter-repo &lt;span class="nt"&gt;--replace-text&lt;/span&gt; replacements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prefer &lt;strong&gt;BFG Repo-Cleaner&lt;/strong&gt; if you like a faster, simpler tool for the common cases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bfg &lt;span class="nt"&gt;--delete-files&lt;/span&gt; id_rsa
bfg &lt;span class="nt"&gt;--replace-text&lt;/span&gt; passwords.txt

&lt;span class="c"&gt;# Expire the old refs and garbage-collect&lt;/span&gt;
git reflog expire &lt;span class="nt"&gt;--expire&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;now &lt;span class="nt"&gt;--all&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git gc &lt;span class="nt"&gt;--prune&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;now &lt;span class="nt"&gt;--aggressive&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Then: force-push and warn your team
&lt;/h2&gt;

&lt;p&gt;History rewriting changes commit hashes, so you must overwrite the remote:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;⚠️ This rewrites shared history. Tell every collaborator to &lt;strong&gt;re-clone or hard-reset&lt;/strong&gt; — if someone merges an old local branch, the secret comes right back. And remember: on GitHub, the old commit can still be reachable via its hash / cached views for a while, which is exactly why &lt;strong&gt;Step 0 (rotation)&lt;/strong&gt; is what actually protects you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prevention: never live on the edge again
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;.gitignore&lt;/code&gt; first.&lt;/strong&gt; Add &lt;code&gt;.env&lt;/code&gt;, &lt;code&gt;*.pem&lt;/code&gt;, &lt;code&gt;secrets.*&lt;/code&gt; &lt;em&gt;before&lt;/em&gt; the first commit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environment variables / a secret manager&lt;/strong&gt; (Azure Key Vault, AWS Secrets Manager, Doppler) — secrets never touch the repo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A pre-commit scanner&lt;/strong&gt; so a secret is blocked &lt;em&gt;before&lt;/em&gt; it's committed:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# gitleaks catches secrets in staged changes&lt;/span&gt;
brew &lt;span class="nb"&gt;install &lt;/span&gt;gitleaks
gitleaks protect &lt;span class="nt"&gt;--staged&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wire that into a pre-commit hook and the "cold sweat" moment mostly disappears.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Rotate the secret&lt;/strong&gt; (non-negotiable, do it first).&lt;/li&gt;
&lt;li&gt;Un-pushed? &lt;code&gt;git commit --amend&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;In history? &lt;code&gt;git filter-repo&lt;/code&gt; or BFG, then &lt;code&gt;git push --force&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Tell your team to re-clone.&lt;/li&gt;
&lt;li&gt;Add a pre-commit scanner so it never happens again.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;How do you handle secrets in your workflow — pre-commit hooks, or living life on the edge? 👇&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by Karam Khoury — Lead Software Engineer (.NET &amp;amp; Azure) with 14+ years building secure, scalable fintech systems. More at &lt;a href="https://karamkhoury.me" rel="noopener noreferrer"&gt;karamkhoury.me&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>security</category>
      <category>devops</category>
      <category>webdev</category>
    </item>
    <item>
      <title>System Design: The 6 Core Load Balancing Algorithms, Explained</title>
      <dc:creator>Karam Khoury</dc:creator>
      <pubDate>Fri, 24 Jul 2026 11:58:19 +0000</pubDate>
      <link>https://dev.to/karamkhoury88/system-design-the-6-core-load-balancing-algorithms-explained-2gc</link>
      <guid>https://dev.to/karamkhoury88/system-design-the-6-core-load-balancing-algorithms-explained-2gc</guid>
      <description>&lt;p&gt;Stop guessing how your traffic scales — understand the routing mechanics. Here's how the six core algorithms actually dictate traffic distribution, and when to reach for each.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Round Robin
&lt;/h2&gt;

&lt;p&gt;Distributes requests sequentially across the server pool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; Dealing a deck of cards — Server A gets request 1, Server B gets 2, Server C gets 3, then the cycle repeats. Best for identical, stateless servers.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Weighted Round Robin
&lt;/h2&gt;

&lt;p&gt;Sequential routing that accounts for unequal hardware.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; Server A has 64 GB RAM, Server B has 32 GB. Assign weight 2 to A and 1 to B, and A receives exactly twice as many requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Least Connections
&lt;/h2&gt;

&lt;p&gt;Routes traffic to the server with the fewest active, open sessions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; Joining the supermarket checkout with the fewest people. Ideal for long-lived connections — WebSockets, heavy database queries.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. IP Hash
&lt;/h2&gt;

&lt;p&gt;Uses a hash of the client's IP to guarantee the same client hits the same server every time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; A user at 192.168.1.50 is always routed to Server C. Mandatory for legacy stateful apps that store session data in-memory rather than a distributed cache.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Least Response Time
&lt;/h2&gt;

&lt;p&gt;A hybrid: lowest number of active connections combined with the lowest average response time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; Joining the line that has both the fewest people &lt;em&gt;and&lt;/em&gt; the fastest cashier. Essential when server performance degrades unpredictably.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Adaptive (Resource-Based)
&lt;/h2&gt;

&lt;p&gt;Routes based on real-time hardware telemetry from an agent on each server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; The load balancer queries CPU, memory, and I/O wait in real time, and avoids any server spiking above 80% utilization.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;Choose your algorithm based on your infrastructure and state management — not trends. Build systems that scale predictably.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Written by Karam Khoury — Lead Software Engineer (.NET &amp;amp; Azure), building secure, scalable fintech systems. More at &lt;a href="https://karamkhoury.me" rel="noopener noreferrer"&gt;karamkhoury.me&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>architecture</category>
      <category>webdev</category>
      <category>backend</category>
    </item>
  </channel>
</rss>
