Inside the Trenches of CI/CD
Inside the Trenches of CI/CD
Stories, insights, and opinions from the team behind Mergify

∙
5 min
read
GitHub Merge Queue Was Step One. Real CI Orchestration Comes Next.
GitHub’s merge queue solved safety, not scale. As CI grows slower, costlier, and shared across teams, merging becomes a scheduling problem. Learn why large monorepos and Bazel users outgrow native queues and what real CI orchestration looks like.

Julien Danjou

∙
5 min
read
GitHub Merge Queue Was Step One. Real CI Orchestration Comes Next.
GitHub’s merge queue solved safety, not scale. As CI grows slower, costlier, and shared across teams, merging becomes a scheduling problem. Learn why large monorepos and Bazel users outgrow native queues and what real CI orchestration looks like.

Julien Danjou

∙
5 min
read
GitHub Merge Queue Was Step One. Real CI Orchestration Comes Next.
GitHub’s merge queue solved safety, not scale. As CI grows slower, costlier, and shared across teams, merging becomes a scheduling problem. Learn why large monorepos and Bazel users outgrow native queues and what real CI orchestration looks like.

Julien Danjou

∙
5 min
read
GitHub Merge Queue Was Step One. Real CI Orchestration Comes Next.
GitHub’s merge queue solved safety, not scale. As CI grows slower, costlier, and shared across teams, merging becomes a scheduling problem. Learn why large monorepos and Bazel users outgrow native queues and what real CI orchestration looks like.

Julien Danjou

∙
5 min
read
Stop Lying to Your Dependency Resolver: The Real Rules for Python Dependency Management
Your Python app didn’t change: your dependencies did. This post explains why apps must pin dependencies, libraries must declare ranges, dev tools must be locked, and how to use lockfiles correctly with Poetry, PDM, and uv to avoid CI and production surprises.

Mehdi Abaakouk

∙
5 min
read
Stop Lying to Your Dependency Resolver: The Real Rules for Python Dependency Management
Your Python app didn’t change: your dependencies did. This post explains why apps must pin dependencies, libraries must declare ranges, dev tools must be locked, and how to use lockfiles correctly with Poetry, PDM, and uv to avoid CI and production surprises.

Mehdi Abaakouk

∙
5 min
read
Stop Lying to Your Dependency Resolver: The Real Rules for Python Dependency Management
Your Python app didn’t change: your dependencies did. This post explains why apps must pin dependencies, libraries must declare ranges, dev tools must be locked, and how to use lockfiles correctly with Poetry, PDM, and uv to avoid CI and production surprises.

Mehdi Abaakouk

∙
5 min
read
Stop Lying to Your Dependency Resolver: The Real Rules for Python Dependency Management
Your Python app didn’t change: your dependencies did. This post explains why apps must pin dependencies, libraries must declare ranges, dev tools must be locked, and how to use lockfiles correctly with Poetry, PDM, and uv to avoid CI and production surprises.

Mehdi Abaakouk

∙
9 min
read
Lessons From a Noisy Monitor
Your database monitors keep firing even though nothing is wrong? We hit the same problem: noisy IOPS alerts caused by predictable jobs. This post explains how we replaced brittle thresholds with an SLO-based approach that restored signal, eliminated noise, and stopped the monitor from "crying wolf."

Julian Maurin

∙
9 min
read
Lessons From a Noisy Monitor
Your database monitors keep firing even though nothing is wrong? We hit the same problem: noisy IOPS alerts caused by predictable jobs. This post explains how we replaced brittle thresholds with an SLO-based approach that restored signal, eliminated noise, and stopped the monitor from "crying wolf."

Julian Maurin

∙
9 min
read
Lessons From a Noisy Monitor
Your database monitors keep firing even though nothing is wrong? We hit the same problem: noisy IOPS alerts caused by predictable jobs. This post explains how we replaced brittle thresholds with an SLO-based approach that restored signal, eliminated noise, and stopped the monitor from "crying wolf."

Julian Maurin

∙
9 min
read
Lessons From a Noisy Monitor
Your database monitors keep firing even though nothing is wrong? We hit the same problem: noisy IOPS alerts caused by predictable jobs. This post explains how we replaced brittle thresholds with an SLO-based approach that restored signal, eliminated noise, and stopped the monitor from "crying wolf."

Julian Maurin

∙
7 min
read
await Is Not a Context Switch: Understanding Python's Coroutines vs Tasks
Python’s async model is misunderstood, especially by engineers coming from JS or C#. In Python, awaiting a coroutine doesn’t yield to the event loop. Only tasks create concurrency. This post explains why that distinction matters and how it affects locking, design, and correctness.

Mehdi Abaakouk

∙
7 min
read
await Is Not a Context Switch: Understanding Python's Coroutines vs Tasks
Python’s async model is misunderstood, especially by engineers coming from JS or C#. In Python, awaiting a coroutine doesn’t yield to the event loop. Only tasks create concurrency. This post explains why that distinction matters and how it affects locking, design, and correctness.

Mehdi Abaakouk

∙
7 min
read
await Is Not a Context Switch: Understanding Python's Coroutines vs Tasks
Python’s async model is misunderstood, especially by engineers coming from JS or C#. In Python, awaiting a coroutine doesn’t yield to the event loop. Only tasks create concurrency. This post explains why that distinction matters and how it affects locking, design, and correctness.

Mehdi Abaakouk

∙
7 min
read
await Is Not a Context Switch: Understanding Python's Coroutines vs Tasks
Python’s async model is misunderstood, especially by engineers coming from JS or C#. In Python, awaiting a coroutine doesn’t yield to the event loop. Only tasks create concurrency. This post explains why that distinction matters and how it affects locking, design, and correctness.

Mehdi Abaakouk

∙
4 min
read
Updating Materialized Views (Without Worrying Too Much)
Materialized views are powerful but painful to change. Here’s how we safely version, refresh, and migrate them without locking production or timing out deployments, plus the approach we use to avoid dangerous DROP/CREATE migrations.

Rémy Duthu

∙
4 min
read
Updating Materialized Views (Without Worrying Too Much)
Materialized views are powerful but painful to change. Here’s how we safely version, refresh, and migrate them without locking production or timing out deployments, plus the approach we use to avoid dangerous DROP/CREATE migrations.

Rémy Duthu

∙
4 min
read
Updating Materialized Views (Without Worrying Too Much)
Materialized views are powerful but painful to change. Here’s how we safely version, refresh, and migrate them without locking production or timing out deployments, plus the approach we use to avoid dangerous DROP/CREATE migrations.

Rémy Duthu

∙
4 min
read
Updating Materialized Views (Without Worrying Too Much)
Materialized views are powerful but painful to change. Here’s how we safely version, refresh, and migrate them without locking production or timing out deployments, plus the approach we use to avoid dangerous DROP/CREATE migrations.

Rémy Duthu

∙
5 min
read
Goodbye Checklists, Hello AI Linters
We turned our pull request rules into small AI-powered linters using GitHub’s new actions/ai-inference. Each linter enforces one rule: catching risky changes before humans do, without regexes, static analysis, or friction.

Mehdi Abaakouk

∙
5 min
read
Goodbye Checklists, Hello AI Linters
We turned our pull request rules into small AI-powered linters using GitHub’s new actions/ai-inference. Each linter enforces one rule: catching risky changes before humans do, without regexes, static analysis, or friction.

Mehdi Abaakouk

∙
5 min
read
Goodbye Checklists, Hello AI Linters
We turned our pull request rules into small AI-powered linters using GitHub’s new actions/ai-inference. Each linter enforces one rule: catching risky changes before humans do, without regexes, static analysis, or friction.

Mehdi Abaakouk

∙
5 min
read
Goodbye Checklists, Hello AI Linters
We turned our pull request rules into small AI-powered linters using GitHub’s new actions/ai-inference. Each linter enforces one rule: catching risky changes before humans do, without regexes, static analysis, or friction.

Mehdi Abaakouk

∙
8 min
read
Origin and Evolution of the Globstar
Discover how the double-asterisk recursive glob pattern evolved: from Zsh’s early 1990s innovation to Bash’s globstar and beyond, spreading into Python, Ruby, Git, and modern build tools.

Julien Danjou

∙
8 min
read
Origin and Evolution of the Globstar
Discover how the double-asterisk recursive glob pattern evolved: from Zsh’s early 1990s innovation to Bash’s globstar and beyond, spreading into Python, Ruby, Git, and modern build tools.

Julien Danjou

∙
8 min
read
Origin and Evolution of the Globstar
Discover how the double-asterisk recursive glob pattern evolved: from Zsh’s early 1990s innovation to Bash’s globstar and beyond, spreading into Python, Ruby, Git, and modern build tools.

Julien Danjou

∙
8 min
read
Origin and Evolution of the Globstar
Discover how the double-asterisk recursive glob pattern evolved: from Zsh’s early 1990s innovation to Bash’s globstar and beyond, spreading into Python, Ruby, Git, and modern build tools.

Julien Danjou

∙
5 min
read
Shadow Shipping: How We Double-Executed Code to Ship Safely
How do you ship risky code without crossing your fingers? In this post, we explain how he ran old and new logic in parallel (“shadow shipping”) to validate behavior in production before rollout. Learn how this simple pattern turned feature-flag anxiety into data-driven confidence.

Julian Maurin

∙
5 min
read
Shadow Shipping: How We Double-Executed Code to Ship Safely
How do you ship risky code without crossing your fingers? In this post, we explain how he ran old and new logic in parallel (“shadow shipping”) to validate behavior in production before rollout. Learn how this simple pattern turned feature-flag anxiety into data-driven confidence.

Julian Maurin

∙
5 min
read
Shadow Shipping: How We Double-Executed Code to Ship Safely
How do you ship risky code without crossing your fingers? In this post, we explain how he ran old and new logic in parallel (“shadow shipping”) to validate behavior in production before rollout. Learn how this simple pattern turned feature-flag anxiety into data-driven confidence.

Julian Maurin

∙
5 min
read
Shadow Shipping: How We Double-Executed Code to Ship Safely
How do you ship risky code without crossing your fingers? In this post, we explain how he ran old and new logic in parallel (“shadow shipping”) to validate behavior in production before rollout. Learn how this simple pattern turned feature-flag anxiety into data-driven confidence.

Julian Maurin

∙
6 min
read
Why PostgreSQL Ignored Our Index (and What the Planner Was Thinking)
PostgreSQL doesn’t "ignore" your indexes, it just does the math differently. We dive into how the planner weighs cost, why it sometimes chooses sequential scans, and how we tuned our queries to make peace with it.

Fabien Martinet

∙
6 min
read
Why PostgreSQL Ignored Our Index (and What the Planner Was Thinking)
PostgreSQL doesn’t "ignore" your indexes, it just does the math differently. We dive into how the planner weighs cost, why it sometimes chooses sequential scans, and how we tuned our queries to make peace with it.

Fabien Martinet

∙
6 min
read
Why PostgreSQL Ignored Our Index (and What the Planner Was Thinking)
PostgreSQL doesn’t "ignore" your indexes, it just does the math differently. We dive into how the planner weighs cost, why it sometimes chooses sequential scans, and how we tuned our queries to make peace with it.

Fabien Martinet

∙
6 min
read
Why PostgreSQL Ignored Our Index (and What the Planner Was Thinking)
PostgreSQL doesn’t "ignore" your indexes, it just does the math differently. We dive into how the planner weighs cost, why it sometimes chooses sequential scans, and how we tuned our queries to make peace with it.

Fabien Martinet
Join our community on Slack
Join our community on Slack
Get tips, news, and resources from Mergify and its users.
Curious where your CI is slowing you down?
Try CI Insights — observability for CI teams.
Curious where your CI is slowing you down?
Try CI Insights — observability for CI teams.
Curious where your CI is slowing you down?
Try CI Insights — observability for CI teams.
Curious where your CI is slowing you down?
Try CI Insights — observability for CI teams.