<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Amr Mubarak - Thoughts on Engineering</title>
    <link>https://amrmubarak.com</link>
    <description>Technical writing on distributed systems, databases, and software engineering</description>
    <language>en-us</language>
    <lastBuildDate>Sat, 25 Jul 2026 02:38:00 GMT</lastBuildDate>
    <atom:link href="https://amrmubarak.com/rss.xml" rel="self" type="application/rss+xml"/>
    
    <item>
      <title>Database Migrations at Scale: Zero-Downtime Schema Changes and What Companies Actually Do</title>
      <link>https://amrmubarak.com/blog/database-migrations-at-scale</link>
      <guid>https://amrmubarak.com/blog/database-migrations-at-scale</guid>
      <pubDate>Sun, 05 Jul 2026 00:00:00 GMT</pubDate>
      <category>Database</category>
      <description>
## Why Migrations Break

A migration that runs in 200ms on your local machine takes 30 minutes on the production table with 50 million rows. During those 30 minutes, your `ALTER TABLE` holds a lock t</description>
    </item>

    <item>
      <title>Caching in Production: Strategies, Pitfalls, and What Companies Actually Do</title>
      <link>https://amrmubarak.com/blog/caching-in-production</link>
      <guid>https://amrmubarak.com/blog/caching-in-production</guid>
      <pubDate>Sat, 04 Jul 2026 00:00:00 GMT</pubDate>
      <category>System Design</category>
      <description>
## Why Caching Exists

A single database query takes 5ms. A cache lookup takes 1ms. The difference seems small — but at 10,000 requests per second, that 4ms gap is 40 seconds of cumulative latency pe</description>
    </item>

    <item>
      <title>TCP for Backend Engineers: From Zero to Practical Mastery</title>
      <link>https://amrmubarak.com/blog/tcp-for-backend-engineers</link>
      <guid>https://amrmubarak.com/blog/tcp-for-backend-engineers</guid>
      <pubDate>Tue, 21 Jul 2026 00:00:00 GMT</pubDate>
      <category>Distributed Systems</category>
      <description>
## 1. What TCP Actually Is, and Why It Exists

Start with the network underneath TCP, because that&apos;s the whole reason TCP exists. The internet moves data in packets, and the protocol that handles tha</description>
    </item>

    <item>
      <title>Building an LSM-Tree Storage Engine in Go, Part 2: The Memtable</title>
      <link>https://amrmubarak.com/blog/lsm-engine</link>
      <guid>https://amrmubarak.com/blog/lsm-engine</guid>
      <pubDate>Wed, 06 May 2026 00:00:00 GMT</pubDate>
      <category>Database Internals</category>
      <description>
## Where We Are

In Part 1 we built a Write-Ahead Log. Every mutation — write or delete — is recorded to disk and fsynced before we acknowledge it to the caller. We have durability.

What we do not h</description>
    </item>

    <item>
      <title>Building an LSM-Tree Storage Engine in Go, Part 3: The SSTable</title>
      <link>https://amrmubarak.com/blog/sstable</link>
      <guid>https://amrmubarak.com/blog/sstable</guid>
      <pubDate>Wed, 06 May 2026 00:00:00 GMT</pubDate>
      <category>Database Internals</category>
      <description>
## Where We Are

Post 1 built the WAL — every write is fsynced to disk before being acknowledged. Post 2 built the memtable — an in-memory skip list that keeps keys sorted and serves reads in O(log n</description>
    </item>

    <item>
      <title>Implementing a Write-Ahead Log in Go</title>
      <link>https://amrmubarak.com/blog/implementing-wal-in-go</link>
      <guid>https://amrmubarak.com/blog/implementing-wal-in-go</guid>
      <pubDate>Mon, 04 May 2026 00:00:00 GMT</pubDate>
      <category>Database Internals</category>
      <description>
## Implementing a Write-Ahead Log in Go

A Write-Ahead Log is the mechanism behind the D in ACID. Before any mutation reaches your data files, a record describing that mutation is written and fsynced</description>
    </item>

    <item>
      <title>Building a Load Balancer in Go, Part 1: Reverse Proxy and Round Robin</title>
      <link>https://amrmubarak.com/blog/buildinga-load-balancer-in-go-part-1</link>
      <guid>https://amrmubarak.com/blog/buildinga-load-balancer-in-go-part-1</guid>
      <pubDate>Sun, 03 May 2026 00:00:00 GMT</pubDate>
      <category>System Design</category>
      <description>
## Introduction

You have three backend servers. Each one can handle 1,000 requests per second. Together they can handle 3,000 — but only if requests are spread evenly across all three.

Something ha</description>
    </item>

    <item>
      <title>Building a Load Balancer in Go, Part 2: Health Checks</title>
      <link>https://amrmubarak.com/blog/buildinga-load-balancer-in-go-part-2</link>
      <guid>https://amrmubarak.com/blog/buildinga-load-balancer-in-go-part-2</guid>
      <pubDate>Sun, 03 May 2026 00:00:00 GMT</pubDate>
      <category>System Design</category>
      <description>
## Where We Left Off

In Part 1 we built a reverse proxy that distributes requests across three backends using round robin. It works — but it is blind. Kill one of the backends and the load balancer </description>
    </item>

    <item>
      <title>Building a Production Job Queue in Go: Concurrency, Tradeoffs, and Getting It Right</title>
      <link>https://amrmubarak.com/blog/implementing-job-queue-in-go</link>
      <guid>https://amrmubarak.com/blog/implementing-job-queue-in-go</guid>
      <pubDate>Sat, 02 May 2026 00:00:00 GMT</pubDate>
      <category>System Design</category>
      <description>
## Introduction

Your API receives a request. You need to send a confirmation email, resize an image, call a third-party webhook, and update an analytics counter.

You could do all of that synchronou</description>
    </item>

    <item>
      <title>Write-Ahead Logging: How PostgreSQL Survives Crashes, Powers Replication, and Never Loses Your Data</title>
      <link>https://amrmubarak.com/blog/write-ahead-logging-postgresql-crash-recovery-replication</link>
      <guid>https://amrmubarak.com/blog/write-ahead-logging-postgresql-crash-recovery-replication</guid>
      <pubDate>Wed, 25 Mar 2026 00:00:00 GMT</pubDate>
      <category>Database Internals</category>
      <description>
## Introduction

Your application writes a row. PostgreSQL says &quot;committed.&quot; The server loses power one millisecond later.

When it comes back, is your row there?

The answer is yes — and the reason </description>
    </item>

    <item>
      <title>Concurrency Control in Databases: How to Handle Many Things Happening at Once</title>
      <link>https://amrmubarak.com/blog/concurrency-control-in-databases</link>
      <guid>https://amrmubarak.com/blog/concurrency-control-in-databases</guid>
      <pubDate>Sat, 14 Mar 2026 00:00:00 GMT</pubDate>
      <category>Database Internals</category>
      <description>
## Introduction

Your application has one user. Concurrency is not a problem. That user reads data, writes data, nothing conflicts with anything.

Then you have ten thousand users. Two of them update</description>
    </item>

    <item>
      <title>Data Partitioning in Distributed Databases: How to Split Your Data Without Breaking Everything</title>
      <link>https://amrmubarak.com/blog/data-partitioning-distributed-databases</link>
      <guid>https://amrmubarak.com/blog/data-partitioning-distributed-databases</guid>
      <pubDate>Thu, 12 Mar 2026 00:00:00 GMT</pubDate>
      <category>Database Internals</category>
      <description>
## Introduction

Your single database server handled your first 100,000 users just fine. Then you hit a million. Queries slowed down. Disk filled up. You threw more RAM at it. It helped — for a while</description>
    </item>

    <item>
      <title>Implementing a B+ Tree in Go: What Databases Actually Use</title>
      <link>https://amrmubarak.com/blog/btree</link>
      <guid>https://amrmubarak.com/blog/btree</guid>
      <pubDate>Tue, 10 Mar 2026 00:00:00 GMT</pubDate>
      <category>Database Internals</category>
      <description>
## Why B+ Trees Exist

Your database has 50 million rows. You query by user ID. Without an index, the database reads every row until it finds yours. That&apos;s a full table scan. It gets slower with ever</description>
    </item>

    <item>
      <title>Distributed Transactions: The Hard Truth About Keeping Multiple Systems in Sync</title>
      <link>https://amrmubarak.com/blog/distributed-transactions</link>
      <guid>https://amrmubarak.com/blog/distributed-transactions</guid>
      <pubDate>Fri, 28 Nov 2025 00:00:00 GMT</pubDate>
      <category>Distributed Systems</category>
      <description>
## Why Single-Database Transactions Don&apos;t Scale

A transaction in a single database is simple. You start a transaction, make changes, commit. Either everything commits or nothing does. The database h</description>
    </item>

    <item>
      <title>Replication Strategies in Distributed Databases: What Actually Happens When You Copy Your Data</title>
      <link>https://amrmubarak.com/blog/replication-strategies-in-distributed-databases</link>
      <guid>https://amrmubarak.com/blog/replication-strategies-in-distributed-databases</guid>
      <pubDate>Wed, 26 Nov 2025 00:00:00 GMT</pubDate>
      <category>Distributed Systems</category>
      <description>
## Why Replication Exists

Your database will crash. Not maybe. It will. Hard drives fail, memory corrupts, someone runs the wrong command, power goes out. When that happens, you need another copy of</description>
    </item>

    <item>
      <title>How Databases Actually Store Data: Pages, Tuples, and the Architecture That Matters</title>
      <link>https://amrmubarak.com/blog/inside-database-engine-how-data-is-stored</link>
      <guid>https://amrmubarak.com/blog/inside-database-engine-how-data-is-stored</guid>
      <pubDate>Mon, 20 Oct 2025 00:00:00 GMT</pubDate>
      <category>Database Internals</category>
      <description>
## Introduction

Most developers understand SQL. Fewer understand what happens after the query planner finishes — how rows are physically laid out on disk, why certain writes cost more than others, w</description>
    </item>

    <item>
      <title>Consistency and Data Models in Real Life: The Art of Building Systems That Never Lie to You</title>
      <link>https://amrmubarak.com/blog/consistency-and-data-models-in-real-life-the-art-of-building-systems-that-never-lie-to-you</link>
      <guid>https://amrmubarak.com/blog/consistency-and-data-models-in-real-life-the-art-of-building-systems-that-never-lie-to-you</guid>
      <pubDate>Fri, 17 Oct 2025 00:00:00 GMT</pubDate>
      <category>Distributed Systems</category>
      <description>
## Introduction

At some point you ship something that works perfectly in staging. The code is clean. The tests pass. You deploy it and feel good about it.

Six months later you&apos;re debugging a produc</description>
    </item>

    <item>
      <title>ACID Properties and Isolation Levels: Deep Dive into Production Database Behavior</title>
      <link>https://amrmubarak.com/blog/acid-properties-and-isolation-levels-deep-dive-into-production-database-behavior</link>
      <guid>https://amrmubarak.com/blog/acid-properties-and-isolation-levels-deep-dive-into-production-database-behavior</guid>
      <pubDate>Thu, 16 Oct 2025 00:00:00 GMT</pubDate>
      <category>Database Internals</category>
      <description>
## Why This Matters in Production

Every backend engineer has a story about a production incident that made ACID properties real. Maybe it was a race condition in a payment system that took hours to </description>
    </item>

    <item>
      <title>Idempotency in Production: Making Your System Safe to Retry</title>
      <link>https://amrmubarak.com/blog/idempotency-in-production-making-your-system-safe-to-retry</link>
      <guid>https://amrmubarak.com/blog/idempotency-in-production-making-your-system-safe-to-retry</guid>
      <pubDate>Thu, 16 Oct 2025 00:00:00 GMT</pubDate>
      <category>System Design</category>
      <description>
## The Real Cost - What happens when you don&apos;t have idempotency

Every backend engineer has experienced this: a user clicks a button, the request times out, they panic and click it again. Now somethi</description>
    </item>

    <item>
      <title>Database Indexing Strategies for High-Performance Systems</title>
      <link>https://amrmubarak.com/blog/database-indexing-strategies</link>
      <guid>https://amrmubarak.com/blog/database-indexing-strategies</guid>
      <pubDate>Tue, 14 Oct 2025 00:00:00 GMT</pubDate>
      <category>Database Internals</category>
      <description>
## Introduction

Your database has 50 million users. Someone searches by email. Without an index, the database reads every single row until it finds a match. That&apos;s a full table scan — and it gets sl</description>
    </item>
  </channel>
</rss>