The DevOps world is full of brilliant ideas. And brilliant ways to misapply them.

Somewhere between the whiteboard and production, things go sideways. The tools get adopted, the terminology gets memorized, the org chart gets restructured—and yet somehow, you end up worse off than before.

This isn’t a story about teams that ignored DevOps. It’s about teams that tried—earnestly, expensively—and still ended up here. Welcome to the anti-patterns: the shadow versions of the practices we love.

CI—Continuous Isolation

You call it Continuous Integration. Your engineers call it “I pushed to my branch six weeks ago and I’m afraid to merge.”

The pipeline runs green on every push. Dashboards show 100% pass rates. The CI server hums along faithfully, validating code that will never meet other code.

Long-lived feature branches are the original sin of CI. Six weeks of parallel development converge into a three-day conflict resolution marathon, a prayer session, and a hotfix at 2am. Nobody is integrating—they’re just running tests in isolation.

The irony is complete when the CI server’s job becomes to prove, repeatedly, that your code works in a universe where no one else exists.

Symptom: The longest-living branch in your repo has outlasted two sprints, one all-hands, and a reorg.

CD—Continuous Divergence

Your deployments are automated. Your servers are not.

Production has 47 servers. Forty-six of them were provisioned by Terraform. One of them was SSH’d into by Dave in 2019 to “just fix one little thing,” and now it’s the only one that actually works.

Configuration management is nominally in place. But snowflake servers proliferate faster than your documentation. Infrastructure as Code exists in the repository; the actual infrastructure exists somewhere else entirely. Every deployment is a game of which server is going to be the special one this time.

What was promised: a reproducible, auditable, automated path from commit to production.
What was delivered: a distributed collection of artisanal server configurations, each one unique, each one load-bearing.

Symptom: ssh prod-server-03 and ssh prod-server-07 exhibit meaningfully different behavior for the same application version.

GitOops

Git as the single source of truth. Until someone force-pushes to main on a Friday afternoon.

GitOps is a beautiful idea: declare your desired state in git, let automation reconcile reality toward it, sleep soundly. The philosophy is sound. The execution collapses when the git history looks like a Jackson Pollock painting and “desired state” means different things to different teams.

The reconciliation loop goes haywire. Production starts deploying a commit from three months ago. The ArgoCD dashboard turns red—but nobody has looked at it since the day it was set up.

In practice, GitOops is less about git as truth and more about git as the place where truth goes to die: under layers of revert commits, merge conflicts resolved with “ours”, and configuration changes that were “just temporary.”

Symptom: Your deployment history contains the phrase “revert of revert of revert.”

IaC—Infrastructure as Chaos

It’s all in Terraform. Somewhere.

The modules are nested four levels deep. State files live in three different backends, two of which were migrated and one of which was migrated twice. The prod workspace was last touched by someone who left the company eight months ago, and terraform plan now outputs 847 lines of changes that nobody can explain.

“But it’s reproducible,” someone says—right before discovering the AMI ID is hardcoded, the secrets are plaintext variables, and terraform apply will silently destroy the database if you forget to set one flag.

Infrastructure as Code without code review, versioning discipline, and module design is just shell scripting with a state machine and better branding.

Symptom: The Terraform repo has a directory called old/, a directory called old2/, and a file called main_FINAL_v3_USE_THIS.tf.

SRE—Site Reacting Engineering

You hired SREs. You just forgot to give them time to do SRE work.

The promise of Site Reliability Engineering is proactive reliability: error budgets, SLOs, eliminating toil, building systems that fail gracefully. The reality in many organizations is a team of very talented engineers who spend 80% of their time on on-call rotations, incident response, and “just this one operational task that will only take an hour.”

Toil elimination is on the roadmap. It’s been on the roadmap for six quarters. The roadmap keeps getting disrupted by incidents that—if the toil had been eliminated—would not have happened.

The SRE team wanted to build a chaos testing framework. They spent the month firefighting the chaos that already existed.

Symptom: Your SREs have more war stories than engineering designs. Their runbooks are longer than their design docs.

SLO—Service Level Optional

The target exists. The accountability does not.

The SLO is the centerpiece of SRE: a precise, measurable reliability target backed by an error budget that governs how much risk the team can take. It turns “the site feels slow sometimes” into “99.5% of requests complete in under 200ms over a 28-day rolling window”—a number that can be owned, tracked, and defended.

In the anti-pattern, SLOs are written in a document that gets presented to leadership once, celebrated, filed, and never opened again. The error budget runs dry in week two. Nobody adjusts the release cadence. The on-call engineer has never seen the SLO doc. The target still says 99.9%.

“We have SLOs” means the document exists. “We work to SLOs” means something else entirely—and is far rarer.

Symptom: Your SLOs live in a Confluence page last edited fourteen months ago. It has zero comments. Nobody knows who owns it.

MTTR—Mean Time To Repeat

You fixed it in twelve minutes. It came back in three weeks.

The industry obsesses over MTTR as Mean Time To Recovery: how quickly you restore service. Low MTTR is the mark of a mature team. But there is a shadow metric lurking behind it—Mean Time To Repeat: how long before the same class of incident strikes again.

Fixing a symptom fast is not the same as fixing a cause. The connection pool exhaustion runbook gets faster with every execution. Response is practiced and efficient. The system learns nothing. The incident returns on schedule, the team runs the runbook again, and the DORA metrics continue to look excellent.

Fast recovery without durable fixes is not reliability—it’s a very well-rehearsed emergency.

Symptom: Your “database connection pool exhaustion” runbook has been executed eleven times this year. It has never been revised.

CAB—Change Avoidance Board

Governance as a service. The service is unavailable.

The Change Advisory Board exists to bring coordination to risky changes—the right people reviewing the right deployments, catching conflicts, preventing simultaneous changes to fragile systems. In a complex, pre-DevOps environment, it made sense.

In a CI/CD world, the CAB becomes the place where change goes to die. Every PR, config update, and dependency bump requires a ticket, a form, a meeting, and a committee that convenes on Tuesdays. The board doesn’t assess risk—it imposes delay as a proxy for risk reduction. These are not the same thing.

The consequence is classical: developers batch changes to avoid the process, batched changes have larger blast radii, larger blast radii cause more incidents, and the CAB responds by adding more gates.

Symptom: Your change approval process takes longer than your deployment pipeline. You release once a month—to minimize the number of CAB meetings.

DR—Disaster Recreation

You have a disaster recovery plan. Every time you test it, you discover a new disaster.

Disaster Recovery is the practice of ensuring your systems can survive catastrophic failure: replication, failover, backups, runbooks, regular drills. The goal is confidence that when the real failure arrives, your team has already lived through it.

In the anti-pattern, the quarterly DR test is itself the incident. The failover procedure was written two migrations ago and references infrastructure that no longer exists. The backup job has been silently failing for four months. The runbook says to contact the DBA team, and the DBA team was outsourced in January.

You test DR not to build confidence, but to rediscover all the ways it doesn’t work.

Symptom: The DR test post-mortem is longer than the DR runbook.

FinOops

The cloud bill arrives. Everyone is surprised. Nobody is responsible.

FinOps is the discipline of financial accountability for cloud infrastructure: understanding what you’re running, why you’re running it, and whether it’s worth the cost. Done well, it’s engineers and finance in genuine dialogue about trade-offs, with clear ownership of spend.

FinOops is what happens when the practice amounts to a dashboard nobody reads and a Slack channel where someone posts the monthly AWS total and tags @engineering. Nobody owns the line items. Nobody knows why data transfer costs tripled in March. Orphaned resources accumulate. Dev environments run all weekend. Reserved instance coverage is 12%.

Visibility without ownership is not FinOps. It’s just an unusually detailed bill.

Symptom: Your cloud spend grew 45% last quarter. Engineering headcount did not. No one can explain the difference.

Drunk-Based Development

The strategy is trunk. The execution is something else.

Trunk-Based Development is the backbone of true continuous integration: everyone commits to main frequently, branches are short-lived or absent, the trunk is always releasable. It demands discipline, feature flags, and a team that has internalized the cost of divergence.

Change one letter and you have Drunk-Based Development: direct commits to main with no review, no gates, and no apparent strategy. It has all the structural characteristics of trunk-based development—short branches, fast merges—without the engineering practices that make it safe. It looks like discipline from the outside. It feels like Russian roulette from the inside.

The metric “time from commit to main” is very low. So is confidence.

Symptom: Your trunk is always green on the dashboard. Your team has a policy of not checking the dashboard before a release.

Summary: The Pattern Behind the Anti-Patterns

Every one of these anti-patterns has something in common: the form of a good practice was adopted without the substance.

A CI server without a branch strategy. Deployments automated while servers stay snowflakes. SLOs defined but never enforced. Recovery rehearsed but never improved.

The tools are not the transformation. The metrics are not the improvement. The terminology is not the culture.

The best DevOps teams aren’t distinguished by which tools they use—they’re distinguished by the questions they keep asking: Is this actually working? Is this faster than before? Is the team less stressed? Are we deploying with more confidence or less?

Anti-patterns persist not because teams are careless, but because the feedback loops are slow and the victory conditions are fuzzy. The fix isn’t a different tool. It’s a clearer question.

Which of these have you lived through? Drop your own DevOps anti-pattern in the comments—the more painful, the better.