Skip to main content
Back to Blog
Engineering

The Automation Mindset: If You Do It Twice, Script It

September 8, 202510 min read
AutomationScriptingDevOpsProductivityBash

The Automation Mindset: If You Do It Twice, Script It

Last Tuesday, I ran a database migration, tested 3 API endpoints, checked the Stripe webhook logs, verified the CI pipeline was green, and deployed to production. Total time: 4 minutes.

It used to take 45.

The difference isn't that I got faster at clicking buttons. It's that I stopped clicking buttons entirely.

The Rule

If I do something manually twice, I automate it the third time.

Not "when I have time." Not "next sprint." The third time. Because the fourth time is coming, and the fifth, and the hundredth.

My Automation Stack

Deploy Script (replaced 12 manual steps)

```bash #!/bin/bash

deploy.sh — one command to deploy safely

set -e # Exit on any error

echo "Running pre-deploy checks..." npm run lint npm run test npm run build

echo "Checking production health..." curl -sf https://api.sageideas.dev/health > /dev/null || { echo "Production is already unhealthy. Aborting." exit 1 }

echo "Deploying..." git push origin main

echo "Waiting for Vercel deploy..." sleep 30

echo "Verifying deployment..." curl -sf https://api.sageideas.dev/health > /dev/null || { echo "POST-DEPLOY HEALTH CHECK FAILED" exit 1 }

echo "Deploy successful." ```

This script replaced a checklist I used to follow manually: lint, test, build, check prod health, push, wait, verify. Now it's one command.

Database Backup Verification (replaced a weekly manual check)

```bash #!/bin/bash

verify-backup.sh — runs as a weekly cron job

BACKUP_AGE=$(supabase db dump --dry-run 2>&1 | grep "Last backup" | awk '{print $NF}')

if [ "$BACKUP_AGE" -gt 24 ]; then echo "WARNING: Last backup was $BACKUP_AGE hours ago" | mail -s "Backup Alert" sage@sageideas.org fi ```

I used to manually check backup status every Monday morning. Now a cron job checks every 6 hours and emails me only if something is wrong.

New Project Setup (replaced 30 minutes of boilerplate)

```bash #!/bin/bash

new-project.sh — scaffolds a new project with my standards

PROJECT_NAME=$1

npx create-next-app@latest $PROJECT_NAME --typescript --tailwind --app --eslint cd $PROJECT_NAME

Add my standard config files

cp ~/.templates/.env.example . cp ~/.templates/.github/workflows/ci.yml .github/workflows/ci.yml cp ~/.templates/lib/config.ts lib/config.ts cp ~/.templates/.prettierrc .

Initialize git with conventional commit hook

npx husky init echo 'npx commitlint --edit $1' > .husky/commit-msg

echo "Project $PROJECT_NAME created with CI, linting, and commit hooks." ```

Every new project starts with CI, linting, and commit hooks. No "I'll add those later" — they're there from the first commit.

The ROI of Automation

I track time saved by my automations:

Automation Frequency Time Before Time After Annual Savings
Deploy script 5x/week 15 min 1 min 60 hours
Backup verification Daily 5 min (manual check) 0 min 20 hours
Project setup 2x/month 30 min 2 min 11 hours
Test data generation 3x/week 20 min 1 min 48 hours
SSL cert monitoring Continuous Manual check Automated alert 5 hours

Total: ~144 hours saved per year. That's 18 working days. Almost a full month of engineering time recovered by scripts that took a few hours each to write.

When NOT to Automate

Not everything should be automated. My rules:

  • Don't automate things you do once. A one-time data migration doesn't need a reusable script.
  • Don't automate things that change constantly. If the process changes every week, the script will need maintenance every week.
  • Don't automate critical decisions. Automated deploys: yes. Automated database drops: absolutely not.

The goal isn't to automate everything. The goal is to automate the stuff that's boring, repetitive, and error-prone — freeing your brain for the stuff that actually requires thinking.

The Mindset Shift

Junior engineers think "I should do this task." Senior engineers think "How do I make sure nobody ever has to do this task again?"

That shift — from executing work to eliminating work — is what separates operators from builders.

Want to see this in action?

Check out the projects and case studies behind these articles.