ITIL for Developers: Five Questions Your Code Should Answer
By Sergey Nosov
16 October 2026
On 29 May 2025, Google added a feature to Service Control, the binary that checks policy and quota on requests to Google’s APIs. The new code path never ran during the region-by-region rollout, because it needed a policy change to trigger it. On 12 June, a policy change with unintended blank fields was replicated globally within seconds. The new code hit a null pointer, and Service Control went into a crash loop in every region.
Google’s incident report says the 29 May code change “did not have appropriate error handling nor was it feature flag protected.” The code had gone out in stages. The data that triggered it went everywhere at once.
ITIL, a body of guidance for IT service management, has precise words for what happened: a change, a deployment, a release. Read from the developer’s side, its core practices ask five questions that your software makes easy or hard to answer:
- What changed?
- What is broken, and how do we restore service?
- Why does it keep breaking?
- Are we keeping our promises?
- What is running where?
Under other names, you already do much of what ITIL describes. This article starts with ITIL as it stands in 2026, then takes each question in turn: the practice behind it, its terms, and what answers it in code. As you read, run a gap analysis in your head: which of the five would your software struggle to answer today?
What ITIL Is Now
ITIL 4’s glossary defined ITIL as “best-practice guidance for IT service management.” It began as guidance from the UK government. In 2013, the Cabinet Office and Capita created a joint venture, AXELOS, to manage and develop it, and PeopleCert completed its purchase of AXELOS on 30 July 2021.
ITIL 4, published in 2019, arranged the guidance as a service value system. Its five components are seven guiding principles, governance, a service value chain of six activities, thirty-four management practices, and continual improvement. A practice is broader than the processes of earlier versions. The glossary defines it as “a set of organizational resources designed for performing work or accomplishing an objective.” That takes in people, tools, and suppliers as well as the steps of a process.
In early 2026, PeopleCert released the next version. Its official name is simply ITIL; “ITIL (Version 5)” only tells it apart from earlier versions. According to Stephen Mann, who reviewed a prerelease copy of the new Foundation book for ITSM.tools, the letters no longer stand for IT Infrastructure Library. The scope widened from IT services to “digital product and service management.” The service value chain gave way to a lifecycle of eight activities, which the ITIL author Stuart Rance lists as discover, design, acquire, build, transition, operate, deliver, and support.
For a developer, what stayed matters more than what moved. Mann reports that the seven guiding principles carried over and that the names of all thirty-four management practices remain unchanged. The detailed practice guides are another matter. Roman Jouravlev, responsible for ITIL’s continual development, wrote in March 2026 that they would be updated for Version 5 in the second half of the year. This article therefore uses the practice names both versions share and quotes ITIL 4’s official glossary for definitions. Check a practice’s revised guide once it appears.
ITIL is guidance, not a standard your software complies with. PeopleCert certifies people who pass ITIL exams. It also issues certificates for maturity assessments against its ITIL Maturity Model, and it accredits vendors after assessing their service management tools against ITIL. Unless you build such tools, none of that assesses your software. A service provider that wants its service management certified is audited against a standard, ISO/IEC 20000-1. So the useful question is not whether your software is ITIL compliant, but whether it helps the people who run it answer ITIL’s questions.
Seven Principles, Read as Engineering Advice
The glossary calls the guiding principles “recommendations that can guide an organization in all circumstances.” Each one also reads well as advice for engineers:
- Focus on value. Judge work by what users get from it, not by how busy it keeps the team, and measure the service the way users experience it.
- Start where you are. Measure what exists and reuse what works before you propose a rewrite.
- Progress iteratively with feedback. Ship small changes, release them in stages, and let production feedback choose the next step.
- Collaborate and promote visibility. Keep changes, incidents, and service levels where everyone can see them. ITIL’s change schedule is simply “a calendar that shows planned and historical changes.”
- Think and work holistically. A change to one service can break everything that depends on it.
- Keep it simple and practical. A few alerts and targets that people act on beat a hundred that nobody reads.
- Optimize and automate. Simplify a process before you automate it, and keep human judgment for the decisions that need it.
What Changed? Change Enablement
ITIL defines a change as “the addition, modification, or removal of anything that could have a direct or indirect effect on services.” Taken at its word, the definition covers code, infrastructure, configuration, a feature flag, and data such as Google’s quota policy.
ITIL’s practice for governing changes is change enablement. It exists to assess risks, authorize changes, and manage a change schedule “in order to maximize the number of successful service and product changes.” ITIL v3 called it change management. The first ITIL 4 book called it change control, and the name changed again after the industry objected to the word “control.”
Three of its terms do most of the work:
- A change authority is “a person or group responsible for authorizing a change.” Nothing in that definition requires a weekly board.
- A standard change is “a low-risk, pre-authorized change that is well understood and fully documented, and which can be implemented without needing additional authorization.”
- An emergency change is “a change that must be introduced as soon as possible.” It moves faster than other changes, but it still needs authorization, a record, and, afterward, a post-implementation review.
Most approvals belong in the engineering work. DORA’s 2019 State of DevOps Report found that “change approvals are best implemented through peer review during the development process, supplemented by automation to detect, prevent, and correct bad changes early in the software delivery life cycle.” Heavyweight approval by people outside the team, such as a change advisory board or a senior manager, had “a negative impact on software delivery performance.” DORA found no evidence linking such approval to lower change fail rates, yet it still gives the change advisory board “a vital role” in coordinating teams and weighing business trade-offs.
The practical move is to make the pipeline a change model. ITIL defines one as “a repeatable approach to the management of a particular type of change.” Then agree with the change authority on the model’s scope: which well-understood, low-risk kinds of change become standard changes when they pass it. Other changes still need assessment and authorization, as normal changes or, when they cannot wait, as emergency changes. For example:
Change model: service deployment
Standard (pre-authorized) when:
- it changes no schema or
permission
- a second engineer approved
the pull request
- every pipeline test passed
- new behavior ships behind
a flag, off by default
- rollback is one command
Otherwise: normal or emergency
Always: a canary that misses
its targets rolls back
Your tools already keep the evidence: the diff and its review in the code platform, the flag’s state in the flag service, and the tests, canary result, and deployment log in the pipeline. That evidence also serves audits; my article on SOC 2 for developers shows where change controls appear in the Trust Services Criteria. DORA sets the bar for speed in its guidance on change approval: “Your goal should be to make your regular change management process fast and reliable enough that you can use it to make emergency changes too.”
Release Is Not Deployment
ITIL keeps two practices apart. Deployment management moves “new or changed hardware, software, documentation, processes, or any other service component to live environments,” while release management makes “new and changed services and features available for use.” Feature flags separate the two in code: deploy with the feature off, release it to a small group, watch, and widen.
Google’s code change had no flag, so deploying the binary also released its new code path. The report says that with flag protection, the issue would have been caught in staging. One of its remedies reads: “We will enforce all changes to critical binaries to be feature flag protected and disabled by default.”
The policy change that reached that path was a separate change, and nothing staged it. Another of the report’s remedies says that “data replication needs to be propagated incrementally with sufficient time to validate and detect issues,” even where the business wants the data everywhere at once. Treat configuration and data the way you treat code: stage them and record them.
Two cautions apply. Flipping a flag is a change by ITIL’s definition, so the audit log of your flag service belongs in the change record. And a flag left in place becomes a hazard of its own. An old flag reused for new code was part of what went wrong at Knight Capital in 2012, as I described in the article on deleting dead code.
What Is Broken? Incident Management
An incident, in ITIL’s glossary, is “an unplanned interruption to a service or reduction in the quality of a service.” Incident management minimizes the negative impact of incidents “by restoring normal service operation as quickly as possible.” Restoring comes first: responders diagnose as far as restoring needs, and finding and removing the causes is the job of problem management.
During the June outage, Google Cloud, Google Workspace, and Google Security Operations saw a rise in 503 errors on external API requests. That outage was what ITIL calls a major incident, “an incident with significant business impact, requiring an immediate coordinated resolution.”
Within 10 minutes, the report says, “the root cause was identified and the red-button (to disable the serving path) was being put in place.” The code change had come with that red button as a safety precaution. Even so, it was ready to roll out only after about 25 minutes, and the rollout was complete within 40. The deeper questions, such as why the code had no flag and why the data reached every region at once, belonged to the analysis that followed.
Communication lagged: Google’s status page depended on infrastructure that the outage took down, so the first public report came about an hour after the crashes began. Recovery lagged in places too. In us-central1, one of the larger regions, the restarting Service Control tasks overloaded the Spanner table they all read. Service Control lacked the randomized exponential backoff that would have spread them out, and full recovery there took up to about 2 hours and 40 minutes.
Developers decide much of how fast service comes back, long before the incident:
- a kill switch for each risky path, and a rollback that takes one command;
- randomized exponential backoff on retries and reconnects;
- an ID on every request, returned to the caller and written on each of its log lines;
- logs written as structured events with stable error codes;
- error responses that tell the user what to do and give them an ID to quote;
- health checks that keep liveness separate from readiness.
The last item hides a trap. The Kubernetes documentation warns that “incorrect implementation of liveness probes can lead to cascading failures.” A liveness check that calls the database can restart all instances when the database slows down.
For an app with a strict dependency on back-end services, Kubernetes puts the dependency checks in readiness instead: “The liveness probe passes when the app itself is healthy, but the readiness probe additionally checks that each required back-end service is available.” Scope even those checks: if all instances check one shared database, a slowdown there can take them all out of rotation at once.
Three items on the list above are plain code: request IDs, structured logs, and actionable errors. The excerpts below come from one small Node.js service, tested on Node.js 24.21.0, with a stub behind its order lookup. AsyncLocalStorage, a stable Node.js API, carries the request ID across each await in this service, and the log function adds it to each line it writes during the request:
const requestContext = new AsyncLocalStorage();
// A caller's ID is only a claim:
// log it beside ours, and only if
// it has a safe shape.
const SAFE_ID = /^[A-Za-z0-9-]{8,64}$/;
function log(level, event, fields = {}) {
const store = requestContext.getStore();
console.log(JSON.stringify({
time: new Date().toISOString(),
level,
event,
version: build.version,
commit: build.commit,
requestId: store?.requestId,
callerId: store?.callerId,
...fields,
}));
}
const server = createServer((req, res) => {
const header = req.headers["x-request-id"];
const callerId = SAFE_ID.test(header ?? "")
? header
: undefined;
const requestId = randomUUID();
res.setHeader("X-Request-ID", requestId);
requestContext.run({ requestId, callerId }, () =>
route(req, res).catch((err) => {
// Last resort: drop this
// connection, not the
// whole process.
log("error", "request_failed", {
stack: err?.stack,
});
res.destroy();
}),
);
});
The service generates its own UUID for every request. A caller’s X-Request-ID header is input like any other, so check it where it enters, as the article on the boundary defense principle argues. This service logs a caller’s ID beside its own only when the ID has a safe shape. It never adopts that ID: a safe shape does not make the caller honest.
Behind your own gateway, you can reuse the gateway’s ID instead, if the gateway always sets the header itself and callers cannot bypass it. OpenTelemetry raises the same trust question: its default propagator reads the W3C traceparent header, so a service joins whatever trace the caller names. Its documentation advises: “You might want to ignore or sanitize incoming context from untrusted sources.” Ignore that context at the public edge, and the trace ID can serve as the request ID.
When a lookup fails, the log gets the stable error code and the stack. The caller gets the code, a message written for a person, and the request ID:
const FALLBACK_MESSAGE =
"Something went wrong on our side. " +
"Try again later, or contact support " +
"and quote the request ID.";
async function route(req, res) {
if (req.url === "/version") {
return sendJson(res, 200, build);
}
try {
const order = await findOrder(req.url);
sendJson(res, 200, order);
} catch (err) {
const known = err instanceof ServiceError;
const code = known ? err.code : "INTERNAL_ERROR";
log("error", "order_lookup_failed", {
errorCode: code,
stack: err?.stack,
});
sendJson(res, known ? err.status : 500, {
error: code,
message: known
? err.publicMessage
: FALLBACK_MESSAGE,
requestId: requestContext.getStore()?.requestId,
});
}
}
A user who reports the failure can quote the ID, and the ID leads to that request’s log lines. In the test, a programming error and a lookup that rejected with null both got a 500 whose message asks the user to quote the request ID. The log kept the stack trace of the first; for the second, err?.stack yields no stack where err.stack would throw. When even the error response fails, the last-resort handler in the first excerpt drops that one connection, and the process keeps serving everyone else.
Why Does It Keep Breaking? Problem Management
In ITIL’s glossary, a problem is “a cause, or potential cause, of one or more incidents.” Problem management reduces “the likelihood and impact of incidents by identifying actual and potential causes of incidents, and managing workarounds and known errors.” In ITIL’s terms, a known error is a problem that has been analyzed but not yet resolved. A workaround “reduces or eliminates the impact of an incident or problem for which a full resolution is not yet available.” The red button was one: it restored service and left the defect in place.
Many permanent fixes are code changes, so developers belong in this practice. Stable error codes make recurrence countable. Group failures by error code, and split the INTERNAL_ERROR group by stack trace; a group that keeps growing points to a problem before anyone files one. Record each known error with its workaround in the runbook that the alert links to. Then the next person on call does not have to rediscover the workaround.
The glossary even defines technical debt in terms of workarounds: “the total rework backlog accumulated by choosing workarounds instead of system solutions that would take longer.” Each workaround left in place adds to that backlog, and problem management is a natural place to decide when to pay it back.
Analysis needs care. ITIL’s glossary for its High-velocity IT book defines a blameless postmortem as “a non-judgemental description and analysis of the circumstances and events that preceded an incident.” Google’s report does not stop at the null pointer. It names missing error handling, the missing flag, data replicated globally at once, the missing backoff, and a status page that the outage took down. A problem record that stopped at one root cause would leave most of that list unaddressed. My article on complicated and complex systems discusses how hindsight distorts postmortems.
Are We Keeping Our Promises? Service Level Management
In ITIL, service level management sets “clear business-based targets for service performance” and measures the service against them. The targets go into a service level agreement (SLA): “a documented agreement between a service provider and a customer that identifies both services required and the expected level of service.”
Site reliability engineering added the terms a developer needs underneath it. The first edition of Google’s SRE book has a chapter on service level objectives. In its terms, a service level indicator (SLI) measures some aspect of the service, such as latency or error rate. A service level objective (SLO) is a target for an SLI.
The chapter defines the SLA by its consequences, not by a document. SLAs are “an explicit or implicit contract with your users that includes consequences of meeting (or missing) the SLOs they contain.” It also observes: “Most people really mean SLO when they say ‘SLA.’”
The SLA is what the business promises. The SLO is the target your team holds itself to. The chapter suggests a safety margin: an internal SLO tighter than the one you advertise leaves room to respond to chronic problems before users see them. For SLAs, it adds: “It is wise to be conservative in what you advertise to users.” The SLI is what your code and monitoring measure. For example:
SLI: share of valid checkout
requests that succeed
in under 300 ms
SLO: 99.5% over 28 days
SLA: 99.0% per calendar month,
with service credits below
Developers own the SLI. Measure it close to the user, such as at the load balancer or API gateway rather than inside one process. The chapter’s advice is to “start by thinking about (or finding out!) what your users care about, not what you can measure.” The gap between the SLO and 100 percent is your error budget, which my article on availability by the numbers works through. My book, Software Development Principles, has entries on SLOs and error budgets.
What Is Running Where? Service Configuration Management
In an incident, the question “What changed?” comes early, and answering it takes accurate records of what runs where. ITIL’s service configuration management practice exists to make such information “available when and where needed.” Its term for each piece is configuration item: “any component that needs to be managed in order to deliver an IT service.” A configuration management database (CMDB) stores the records and “also maintains the relationships between configuration records.”
For software, the records least likely to drift are the ones the system produces itself. Infrastructure as code and version control describe the intended state. An orchestrator or a cloud provider knows where each instance runs, and each running process should be able to report what it is. Keep configuration and secrets outside the code, and make the service refuse to start without what it needs:
// Fail at startup, not at the
// first request that needs it.
const required = [
"APP_VERSION",
"GIT_COMMIT",
"DATABASE_URL",
];
const missing = required.filter(
(name) => !process.env[name],
);
if (missing.length > 0) {
const names = missing.join(", ");
console.error(`Missing configuration: ${names}`);
process.exit(1);
}
// Identity only. DATABASE_URL
// holds a password, so it never
// appears here.
const build = Object.freeze({
version: process.env.APP_VERSION,
commit: process.env.GIT_COMMIT,
startedAt: new Date().toISOString(),
});
The route in the incident section serves this object at /version. The log function stamps the version and commit on every line, so failing log lines say which build served them. Neither shows a flag flip or a data push, so the change schedule has to record those.
The endpoint reports identity, never configuration values such as the database URL. Keep it off the public internet too—serve it on an internal port or block it at the gateway—because version details help an attacker match the service to known vulnerabilities. The sample uses one port for brevity.
Checklist
- What changed? Agree on a change model, so that well-understood, low-risk deployments through the pipeline run as standard changes. Deploy new behavior behind flags that are off by default, and treat configuration, data, and flag flips as changes too: stage them and record them.
- What is broken? Ship a kill switch with each risky path, keep rollback to one command, and retry with randomized exponential backoff. Put your own ID on every request, its response, and its log lines, and log a safe-shaped caller ID beside it, not in its place. Keep dependency checks out of liveness probes.
- Why does it keep breaking? Log stable error codes, record known errors with their workarounds where responders look, and track the workarounds as debt.
- Are we keeping our promises? Measure SLIs close to the user, and hold an internal SLO tighter than the SLA.
- What is running where? Make every service report its version and commit to the people who run it, and keep configuration and secrets out of the code and out of that report.
Further Reading
- ITIL (Version 5) Changes Explained: 20 Important Changes from ITIL 4 (Stephen Mann, ITSM.tools, 17 March 2026)
- The New ITIL (Stuart Rance, Optimal Service Management, 2 February 2026)
- Streamlining Change Approval (DORA)
- Service Level Objectives (Chris Jones, John Wilkes, and Niall Murphy, with Cody Smith; Site Reliability Engineering, Google)