Education › Site Reliability › Stage 1: The reliability mindset

Eliminating toil

Identify manual, repetitive work and automate it away — and know when not to.

Intermediate ~25 min read Module 3 of 16

Every operations team has a list of chores: restart the stuck worker, extend the certificate, add the new user to six systems, clear the disk on the log server. Each takes ten minutes, and together they eat the week. SRE calls this toil, gives it a precise definition, measures it, and caps it, because a team buried in toil never has time to fix the causes and the load only grows. This module teaches you to recognise toil, measure it honestly, and decide what is worth automating.

After this module you can
  • Define toil using its six characteristics, and distinguish it from overhead and from engineering work
  • Explain why unchecked toil is harmful to both the service and the people running it
  • Measure a team's toil with lightweight tracking and compare it with the 50% cap
  • Evaluate whether automating a task pays off, including the costs people forget
  • Apply a progression from documented procedure to fully autonomous system, with safe automation practices

What toil is, and what it is not

In everyday speech, toil means any work you dislike. In SRE it has a specific meaning. The Google SRE book defines toil as work tied to running a production service that tends to have the following characteristics. The more of them a task has, the more clearly it is toil.

CharacteristicMeaning
ManualA person has to do it, including running a script by hand
RepetitiveYou have done it before and will do it again. The first time solving a new problem is not toil.
AutomatableA machine could do it as well. If it needs human judgement, it is not toil.
TacticalIt is interrupt-driven and reactive, not planned and strategic
No enduring valueThe service is in the same state afterwards. Nothing was permanently improved.
Scales linearly with the serviceTwice the traffic, users or servers means twice the work

The last characteristic is the dangerous one. Work that grows in step with the service will eventually consume any team, however large, and hiring only buys time.

Two things are often confused with toil. Overhead is administrative work not tied to running a service: meetings, planning, reviews, training, expenses. It may be tedious, but it is not toil. Engineering work is the opposite of toil: it requires human judgement, produces a permanent improvement, and lets the team handle a larger service with the same effort. Writing the automation is engineering. Running the automation by hand every Tuesday is toil.

Note

Dull is not the same as toil. Writing a postmortem is tedious and valuable, and it needs judgement. Handling a genuinely novel incident is reactive but not toil. Handling the same alert for the fifth time this month, with the same fix, certainly is.

Why it matters

Some toil is unavoidable, and a little can even be pleasant: quick, predictable tasks give a sense of progress. The problem is quantity. The SRE guideline is that toil, together with other operational work such as on-call, should stay below 50% of each engineer's time, leaving at least half for engineering projects. That number is a ceiling, not a target.

  • It crowds out the fix. Every hour spent restarting the worker is an hour not spent finding out why it hangs. Teams above the cap get slower at everything, permanently.
  • It grows. Because toil scales with the service, a team that is comfortable today is underwater after a year of growth.
  • It causes errors. Humans performing repetitive manual procedures make mistakes. A large share of outages trace back to a manual step done slightly wrong.
  • It damages careers and morale. Engineers who spend their time on chores do not develop, become frustrated, and leave. The people who remain inherit more toil.
  • It sets a precedent. A team that reliably absorbs manual work gets handed more of it, and developers lose the incentive to build systems that do not need it.

The cap is what makes the SRE model sustainable. When a team exceeds it, the response is structural: redirect some operational load back to the development team, pause new service onboarding, or dedicate a sprint to the largest sources. Simply working harder is not on the list.

Measuring toil

You cannot manage what you have not measured, and intuition about toil is poor: people underestimate frequent small interruptions and overestimate the rare dramatic ones. Measurement does not need to be elaborate.

  1. Tag the work. Add a toil label in your ticket system, and a category such as cert-renewal, access-request, manual-deploy, disk-cleanup. Include on-call interrupts.
  2. Record time roughly. Fifteen-minute granularity is plenty. Include the cost of the interruption itself: a five-minute task that breaks your concentration costs far more than five minutes.
  3. Survey the team. Once a quarter, ask everyone to estimate their split between toil, on-call, overhead and engineering. It takes two minutes and the trend is what matters.
  4. Aggregate by category and rank by total hours per month, not by how annoying each task feels.
  5. Review monthly against the cap, and pick the top one or two categories to attack.
python
import csv
from collections import defaultdict

# toil_log.csv columns: date,engineer,category,minutes
TEAM_SIZE = 5
WORK_MINUTES_PER_MONTH = 160 * 60          # one engineer

minutes_by_category: dict[str, int] = defaultdict(int)
with open("toil_log.csv", newline="") as f:
    for row in csv.DictReader(f):
        minutes_by_category[row["category"]] += int(row["minutes"])

total = sum(minutes_by_category.values())
share = total / (TEAM_SIZE * WORK_MINUTES_PER_MONTH)
print(f"Toil: {total / 60:.0f} hours this month = {share:.0%} of team capacity\n")

for category, minutes in sorted(minutes_by_category.items(), key=lambda kv: -kv[1]):
    print(f"{category:<20} {minutes / 60:6.1f} h   {minutes / total:5.0%} of toil")

The output almost always follows a Pareto pattern: two or three categories account for most of the hours. That is good news, because it tells you exactly where a small amount of engineering will return the most time.

Is it worth automating?

Not everything should be automated. Automation is software: it has to be written, tested, documented, secured, monitored and maintained, and it can fail in ways a human would not. A simple comparison keeps you honest.

text
time saved per year = occurrences per year x minutes per occurrence

payback period      = build cost / time saved per year

Example: certificate renewal
  occurrences        40 per year
  time each          45 minutes (including the context switch)
  time saved         40 x 45 = 1,800 minutes = 30 hours per year
  build cost         16 hours to set up automated renewal
  maintenance        about 2 hours per year
  payback            16 / (30 - 2) = 0.57 years, about 7 months

Time saved is only part of the value, and often the smaller part. Weigh these as well.

  • Consistency. Automation performs the step identically every time. If a mistake in the manual procedure could cause an outage, as an expired certificate does, that alone can justify the work.
  • Speed. A machine reacts in seconds. For anything on an incident's critical path, such as failover, that matters more than the hours saved.
  • Growth. A task that happens 40 times this year may happen 400 times next year. Decide using where the service is going.
  • Interruption cost. Removing a task that arrives at random times returns more focus than its minutes suggest.
  • Frequency of change. If the procedure changes every month, the automation will be permanently out of date. Stabilise the process first.

Before automating anything, ask a better question: can the task be eliminated? Disk cleanup disappears if logs are shipped off the machine with a retention policy. Access requests disappear if access derives from group membership in the identity provider. Manual deploys disappear with the pipelines from the DevOps track. Removing the need is cheaper and more reliable than automating the response, and it never needs maintenance.

From runbook to autonomous system

Automation is not all or nothing. The SRE book describes a progression, and moving up even one level is a win. The example is a database failover.

LevelWhat it looks like
0. No automationSomeone works out the failover by hand, from memory, under pressure
1. Documented procedureA runbook lists the exact steps and commands
2. Operator-maintained scriptOne engineer has a script for it on their own laptop
3. Shared, reviewed automationThe script lives in version control, is tested, and anyone on call can run it
4. Triggered automaticallyThe system detects the failure and runs the failover without being asked
5. AutonomousThe platform needs no failover step at all; the design handles it internally

Level 1 is a real and underrated step. Writing the procedure down makes it repeatable, lets anyone perform it, and is the specification for the script that follows. Do not skip it.

Automation acts faster and at a greater scale than any human, which includes making mistakes faster and at a greater scale. Build the safety in from the start.

bash
#!/usr/bin/env bash
# Remove build caches older than N days. Safe to run repeatedly.
set -euo pipefail

days="${1:-14}"
target="/var/cache/builds"
dry_run="${DRY_RUN:-true}"                     # safe by default

[[ -d "$target" ]] || { echo "no such directory: $target" >&2; exit 1; }

count="$(find "$target" -mindepth 1 -maxdepth 1 -mtime +"$days" | wc -l)"
echo "$(date -u +%FT%TZ) candidates=$count older_than_days=$days dry_run=$dry_run"

if (( count > 500 )); then                     # sanity limit: refuse surprising work
  echo "refusing: $count entries exceeds the safety limit" >&2
  exit 2
fi

if [[ "$dry_run" == "false" ]]; then
  find "$target" -mindepth 1 -maxdepth 1 -mtime +"$days" -exec rm -rf {} +
fi
  • Idempotent, so that running it twice, or after a partial failure, does no harm.
  • Dry run by default for anything destructive, with the real action requiring an explicit flag.
  • Sanity limits. Automation that is about to touch far more than expected should stop and ask. Many famous outages were scripts faithfully applying a bad input to the whole fleet.
  • Logged and observable. Record what it did and why, and alert when it fails or has not run.
  • Gradual. Roll automated changes across a fleet in stages, as you would a release.
  • Keep the manual path alive. People must still be able to do the task when the automation is broken, so keep the runbook current and practise it occasionally.
Hands-on practice

Run a two-week toil audit

  1. Create a shared spreadsheet or a ticket label with columns for date, person, category, minutes, and whether it was an interruption. Agree on five to eight categories with your team.
  2. Log every piece of operational work for two weeks, to the nearest fifteen minutes. Include on-call pages and the tasks people think are too small to mention.
  3. Classify each category against the six characteristics. Remove anything that is really overhead or engineering.
  4. Total the hours by category and calculate toil as a percentage of the team's capacity. Compare it with the 50% cap.
  5. For the top three categories, first ask whether the task can be eliminated. For what remains, calculate the payback period, including maintenance, and note non-time benefits such as error reduction.
  6. Take the best candidate up one level on the automation ladder: write the runbook if there is none, or turn an existing runbook into a reviewed, idempotent script with a dry-run mode.
  7. Present the numbers and the plan to the team, and schedule a repeat of the measurement in three months.
Cheat sheet

Eliminating toil — at a glance

Main things to focus on

  • Toil is manual, repetitive, automatable, tactical, without enduring value, and scales linearly with the service.
  • Overhead such as meetings is not toil. Work that needs judgement or leaves a permanent improvement is engineering.
  • Keep toil and other operational work under 50% of each engineer's time. It is a ceiling, not a goal.
  • Measure before acting. A few categories usually account for most of the hours.
  • Ask first whether the task can be eliminated, then whether it should be automated.
  • Payback = build cost / (time saved per year - maintenance per year). Also weigh consistency, speed and growth.
  • Automation must be idempotent, dry-run by default, limited, logged, and rolled out gradually.
  • Keep the manual procedure documented and practised for the day the automation fails.

Toil test: how many apply?

ManualA human has to perform it or start it
RepetitiveDone before, will be done again
AutomatableNeeds no human judgement
TacticalReactive and interrupt-driven
No enduring valueService is no better afterwards
O(n) with service growthMore users or servers means more of it

Formulas

toil share = toil hours / total working hoursPer person and per team; cap at 50% including on-call
time saved per year = occurrences x minutes eachInclude the context-switch cost in minutes each
payback = build cost / (saved per year - maintenance per year)In years; under one year is usually an easy yes
future load = current load x expected growthDecide using next year's volume, not this year's

Automation ladder

0 noneFrom memory, under pressure
1 runbookExact documented steps
2 personal scriptWorks on one laptop
3 shared automationVersioned, reviewed, tested, anyone can run it
4 auto-triggeredThe system starts it itself
5 autonomousThe design makes the task unnecessary

Safe automation checklist

set -euo pipefailStop on the first failure
DRY_RUN=true by defaultDestructive action needs an explicit opt-in
idempotentSafe to re-run after a partial failure
sanity limitRefuse when the scope is far larger than expected
structured log line per runWhat, when, how many, outcome
alert on failure and on absenceA job that silently stopped running is a failure too
staged rolloutOne host, then a few, then the fleet

Common toil and its real fix

manual deploysCI/CD pipeline and GitOps
certificate renewalsAutomated issuance and renewal, plus expiry alerts
access requestsGroup-based access from the identity provider
disk cleanupShip logs off the host; retention and lifecycle policies
restarting a stuck processFix the hang; liveness probe as a stopgap
the same alert every weekFix the cause, or delete the alert if no action is needed

Common pitfalls

  • Calling every unpleasant task toil, which makes the measurement meaningless.
  • Responding to rising toil by hiring, which scales the cost instead of removing it.
  • Automating a task that should not exist at all.
  • Spending weeks automating something that happens twice a year and changes each time.
  • Writing automation with no dry run and no limits, then watching it apply a mistake to the whole fleet.
  • Letting the manual procedure rot, so that nobody can do the task when the automation breaks.
Quiz

Check your understanding

5 questions · 4 to pass · answers are explained as you go. Your best score is saved on this device only.

Progress and quiz scores are saved in this browser only. Back up or restore on the hub.

Was this lesson useful? Tell me what to improve →