You’re staring at a repetitive task. Copy-pasting logs. Rebuilding VMs after a bad deploy. Writing the same Slack report every Friday. Your inner engineer whispers: “Can I automate this?”
Before you spin up another Python script or train another LLM on your runbooks: stop. Automation isn’t free. It has a hidden cost: time, complexity, fragility, and opportunity cost. I’ve seen teams waste months building a shiny dashboard that got deprecated when the monitoring system upgraded.
This isn’t about whether something can be automated. It’s about whether it should be.
Here’s how to decide—practically, not theoretically.
—
Calculate the Real Cost of Manual Work
Before you touch a single line of code, do the math. Not the theoretical math. The actual math—based on your calendar, not your optimism.
Ask:
- How many times per week/month does this happen?
- How long does it actually take? (Not “about 10 minutes”—track it for a week. You’ll be shocked.)
- What’s your real hourly cost? (Salary + overhead + opportunity cost of not doing something else.)
Example: I once spent 20 minutes every Monday fixing a broken CI pipeline. At first glance: “Let’s script the fix!” But tracking it for a month, I found:
- 20 minutes × 4 weeks = 80 minutes/month
- My billable rate? ~$100/hr
- So: $13.33/month in direct cost
A minimal automation (a 50-line Python script) took me 3 hours to write, test, and deploy. That’s $300 in labor. It paid for itself after 22 months. Not worth it.
But—here’s the catch—I could have spent 20 minutes debugging why it broke. Turns out it was a hardcoded path that broke on a minor OS patch. Fixing the root cause (and documenting it) took 45 minutes and saved all future 20-minute fixes. That was the real automation: fixing the system, not the symptom.
Rule of thumb: If the annualized manual cost is under $200, don’t automate—fix or document instead.
—
Consider the Failure Modes (Not the Happy Path)
Automation doesn’t fail quietly. It fails loudly, at 2 a.m., while you’re asleep.
Ask:
- What breaks if this script runs once?
- What breaks if it runs twice?
- What breaks if the output changes slightly?
- What breaks if the tool it depends on updates?
Real example: I automated email reports by scraping a web dashboard. Worked great for 18 months. Then the vendor changed the HTML structure. The script stopped working. No errors—just empty emails. My team didn’t notice until a VP asked for last week’s data. We lost trust, not just time.
Compare that to a more robust approach:
- Use the vendor’s official API (if available)
- Add health checks: “Did the script produce data and match expected fields?”
- Fail open: If the API’s down, send a warning email—not blank reports.
Automation isn’t about saving clicks. It’s about reducing risk. If your script introduces new failure modes, you’ve just outsourced your pain to a silent, harder-to-debug version.
Red flags:
- Requires manual verification after every run
- Depends on a third-party tool with no version stability
- Needs credentials stored in plaintext (yes, even in env vars)
- Has no logging or alerting
—
Automate the Boring, Not the Complex
Not all automation is equal. Prioritize tasks that are:
- Predictable: Same input → same output, every time
- Low-entropy: Little human judgment involved
- High-frequency: Happens often enough to justify the upfront cost
Avoid automating:
- Tasks where context shifts constantly (e.g., “triage this vague incident”)
- One-off tasks (even if they’re tedious)
- Work that’s already mostly done by a tool with a UI you hate (learn the shortcuts first)
Example: I automated log rotation and cleanup for 12 servers. Predictable. Simple. Saved 10 minutes/week. Zero surprises.
But I didn’t automate “generate a status report for the CTO.” Why?
- Stakeholders changed the requested metrics monthly
- “Status” meant different things to different people
- The real need was alignment—not formatting
So I built a shared Notion template with a checklist. The real automation was changing the process, not the output.
Key insight: If the task requires more context than code can hold, you’re automating the wrong thing.
—
AI Doesn’t Fix Broken Workflows
2026 is the year everyone’s slapping “AI” on everything. But AI doesn’t solve the automation problem—it solves perception problems.
- “AI can write my bash scripts!” Yes. But will they work? Will they handle edge cases? Will they be maintainable in 6 months?
- “AI can summarize logs!” Cool. But if your log format changes, your AI output becomes fiction. And who checks?
I ran an experiment: Used an LLM to auto-generate runbooks from past incident reports. It produced plausible steps—but missed 3 critical steps per runbook. Then it confidently hallucinated a rm -rf command as “safe cleanup.” I deleted the repo.
AI is a fast-talking intern. It’s great for boilerplate, but it needs eyes on the output. Use it to draft, not deploy.
Better approach:
- Write the script manually once.
- Identify the boring parts.
- Use AI to refactor or generate tests, not write the core logic.
—
Maintenance Is the Hidden Cost
This is the part everyone skips. Automation has a lifecycle. And it doesn’t stop when the first version runs.
Every automation you ship needs:
- A test suite (even if it’s just
assert output != "") - A way to roll back (or at least detect failure)
- Documentation in the code and in the runbook
- A plan for when the underlying system changes
I keep a “maintenance debt” spreadsheet. Each automation gets an entry:
- Tool version
- Last tested date
- Next upgrade window
- Owner (yes, assign ownership)
- Estimated yearly maintenance hours
One of my earliest automations—a Slack bot that posted deployment status—has been running for 4 years. Why? Because I built it to fail safely: if the API rate-limits, it posts a warning and keeps the last known status. If Slack’s down, it emails the team lead. It’s boring. It’s reliable. It’s maintained.
Compare to the “cool” custom Kubernetes operator I built in 2026. It worked great—until the API version changed. Rewriting it took 2 weeks. Meanwhile, I could’ve used a Helm chart with 30 lines of values.
Hard truth: The best automation is the one you can stop using when it’s no longer needed.
—
What I Would Do First
You don’t need a framework. You need a filter.
Here’s my 5-minute checklist before writing any automation:
- Track it for 2 weeks. How often? How long? What breaks it?
- Ask: “What’s the real task?” (e.g., “fix the CI” vs. “understand why the CI broke”)
- Check for existing tools (Ansible, Terraform, GitHub Actions, even
cron+curl)—don’t reinvent. - Define failure modes. Write down: “If X breaks, what happens?” If it’s not safe, pause.
- Set a maintenance review date. (e.g., “re-evaluate in 6 months or after 3 changes to dependencies”)
If 3+ of these raise red flags—don’t automate. Fix the process. Or accept the tedium.
Automation should make your job less stressful, not add hidden complexity. The goal isn’t to automate everything—it’s to make yourself obsolete on the boring stuff, so you can focus on what matters: reliability, resilience, and sleep.
Now go check your runbook. I bet you’ll find a 10-minute fix hiding behind a 10-hour project.