Measure → Optimise → Automate → Repeat

Code
to Org.

Twenty years between the keyboard and the org chart. What I learned growing systems, teams, and myself — from one server to a platform, from developer to Head of Platform — and why, now that AI makes building faster, the judgment is still the job.

Start Reading Contents
20+Years in the work
6Roles I've held
~13Engineers hired
16Engineers mentored
Part I

The Pendulum

Twenty years between the keyboard and the org chart — and why moving back and forth is the point, not a failure to pick.

Chapter 1

My Story

I didn't plan a career in platform engineering. Nobody did in 2005 — the phrase didn't exist. I finished a Computer Science diploma at Enrico Fermi, spent time at Tor Vergata, and started freelancing in Rome: eCommerce sites, community platforms, small-company websites. One person, every job. Code, server, client call, invoice.

That self-reliant, end-to-end habit never left. It's the thread through everything that follows.

The web years

At Populis I worked on the Excite network, building from scratch the front end of a user management system that went live across six European countries. At DNSEE I grew from developer into lead developer, reporting to the CTO and running a cross-functional team of seven — three developers, an art director, a sysadmin, an account manager and QA — on the San Raffaele healthcare portal. That project had everything: a CMS, departments, profiled registration, appointment booking, a supplier system with a confidential document archive, and a course system spanning several universities. Projects like that make it obvious early that the code is only part of the job.

London

In 2012 I moved to London. FusePump, then IOVOX: real-time statistics, telephony, analytics dashboards. I introduced unit testing and code coverage to a team that didn't have them, gave an internal talk on it, and trained new hires as they arrived. A colleague from that period said they had never seen a developer cover their code with unit tests as thoroughly as I did. I mention it not as a boast but because it explains a lot of what comes later: I trust things I can verify.

Then I founded Kodebeat. Our product, DXpertise, aggregated IT training courses — by developers, for developers. I ran architecture, marketing, sales, partnerships, and a small team of three non-engineers. Running a company teaches you that a beautiful system nobody pays for is a hobby. I also spent time at Immobiliare.it and LuxuryEstate.com, where I mentored a team of six through a full rewrite.

CTO, then engineer again

In 2016 I became CTO at Skuola.net, one of Italy's largest education platforms. Seven people, remote and in-house. I reported to the CEO on strategy, budget, and roadmap. We cut IT costs by 30%, halved web server load through caching, brought 80+ servers under Infrastructure as Code, stood up a secondary data centre, and introduced on-call rotations, runbooks and incident management.

In 2020 I stepped down — voluntarily — and went back to hands-on engineering at Radical. That decision gets its own chapter.

Platform

In 2022 I joined Treatwell as a Platform Engineer, became Engineering Manager, and was promoted to Head of Platform Engineering. I report to the CTO and present platform strategy and budget to the C-level. This is where the threads came together: the code, the infrastructure, the money, the people.

Hands-on roleLeadership role
Twenty years, swinging both ways

And on the side, always

I've never stopped building in the open. nginx-lua, a multi-distro, multi-arch Nginx + LuaJIT image, has been maintained since 2020. go-proxy-cache is a Redis-backed caching reverse proxy I wrote from scratch in Go. I wrote books on GreenOps, disaster recovery, and IT metrics. I gave talks at PUG Roma and Codemotion. And in 2026, with heavy AI assistance, I shipped a wave of new tools — which is the reason this guide talks about AI at all.

Why this guide exists

Most writing about engineering careers picks a lane. Management books assume you've stopped coding. Technical guides assume you'll never manage. Career advice assumes the ladder only goes up.

My experience doesn't fit any of those. I've gone up, sideways, and deliberately back down. I've run teams of seven and been a team of one. The most useful things I've learned live in the overlaps: how a caching decision changes a budget conversation, how a metric can help a team or hurt a person, how a platform succeeds or fails on adoption rather than architecture.

This is the guide I'd have wanted at each of those turns: practical, a little opinionated, and honest about where the evidence stops.

Chapter 2

Stepping Down Is Not Stepping Back

In 2020 I left the CTO seat at Skuola.net to join Radical as an engineer. It was a career change, not a level upgrade, and I wrote about it publicly because I knew how it would look from the outside.

Here's how it felt from the inside. As CTO I was juggling business, product, metrics, processes and people every day. Each one deserved real depth, and I was giving each of them a slice. I'd started to feel like a jack of all trades and a master of none. Engineering — the thing that got me into the room — was the thing I did least.

So I chose depth. A different stack, more time with my family, and my development passion back.

Doing it responsibly

Leaving a leadership role is easy. Leaving it well is not. The part I'm proudest of isn't the decision; it's that the person who took over as CTO was someone I had developed into the role. A leader who leaves a hole behind hasn't stepped down — they've stepped out.

Rule of thumb

Before you change direction, ask: if I left tomorrow, who would carry this, and have I actually prepared them? If the answer is "nobody", that's your next quarter's work.

The pendulum is a feature

There's a popular idea that the management/IC switch is one-way. I don't buy it. The engineer/manager pendulum is real, and I've swung it more than once. Each swing made the other side better:

  • Engineering again after being CTO, I wrote code with a budget conversation in my head. I knew why a 50% cut in pre-production spend mattered, not just how to deliver it.
  • Leading again after being an engineer, I could read a Terraform plan in a review and tell when "it's complicated" meant complicated and when it meant unclear.

The best engineering leaders stay close to the work. Sometimes the only way to stay close is to go back to it.

I'd already written this down years before I did it. In 10x Software Engineer I described management as "totally a different career track compared to software development" — and added that "once tried if you don't like it can always switch back to individual contributor." Easier to write than to do. Still true.

When to swing

This is opinion, not a formula. The signals I've learned to trust:

  • You're spread across everything and deep in nothing, and it's not a phase.
  • You've stopped being able to judge technical work you're accountable for.
  • The energy you spend outside work goes to the other side. If your evenings are spent building, that's information.
  • You can leave the seat in good hands. If you can't, fix that first.

What the swing costs

It isn't free, and pretending otherwise does nobody a favour. Going back to engineering means a title that reads like a step down, a period of being slow at things you used to be fast at, and explaining the decision more often than you'd like. Going back to leadership means giving up the satisfaction of finishing things yourself. In my experience the cost is paid up front and the return comes later: each time I swung, I came back to the other side with a perspective I couldn't have got by staying.

Chapter 3

What Shape Are You?

In 2019 I wrote a post called What Kind of Shaped Professional Are You?. The idea is old: an I-shaped engineer goes deep in one thing; a T-shaped engineer adds breadth across the top; a π-shaped one has two deep stems.

Looking back, my shape grew one stem at a time — and always for the same reason: a problem in front of me needed it.

How each stem arrived
StemWhenWhat forced it
Backend / web2005 →Freelancing: if it broke, it was mine
Testing & qualityLondonTeams with no tests and no coverage
InfrastructureSkuola.net80+ servers and nobody else to own them
Cloud & DevOpsRadicalCI that took too long and bills that grew too fast
Platform & peopleTreatwellMany teams, one shared foundation
GreenOps2025 →Cost and carbon turned out to be the same lever
Supply chain & AI infra2026Shipping open source responsibly, with agents in the loop

One learning vector at a time

One habit made the stems manageable: every project gets exactly one new thing. A shop prototype is where I tried transducers. A worker pipeline is where I tried HTTP/3. The proxy is where I tried TLS fuzzing. Not five new things in a production system — one, in soil close enough to production to be honest, far enough away to be safe.

In 2026 the "one new thing" was AI orchestration itself. The tools were the vehicle; learning to direct agents was the lesson.

Breadth is cheap. A stem is only real when you've been accountable for something built on it.

Breadth across the top, depth added one stem at a time (lengths are indicative, not measured)

The "10x" is mostly context

Between 2019 and 2021 I wrote 10x Software Engineer, a week-by-week learning path of curated resources. The title needed a disclaimer, so I wrote one: I believe in the 10x only "in the sense that one developer could achieve x-times more of other developers in certain circumstances" — knowing the domain, the language, the project, and managing time well. That's context, not genius. Which means it can be learned and it can be shared.

The book borrows three levels from the Dreyfus model — advanced beginner, competent, proficient — and deliberately skips the last one, expert, because being competent in many areas is realistic and being expert in all of them is not. Its premise is the same as this chapter's: companies "do not need just software developers, they need software engineers with soft skills and breadth of knowledge."

Chapter 4

Who Is This For?

This guide is for you if:

  • You're a developer starting to own infrastructure, cost, or reliability — and nobody handed you a manual.
  • You've just become a tech lead or engineering manager and you're wondering how much code you're still allowed to write.
  • You run, or want to run, a platform team and you need it to be adopted, not tolerated.
  • You're a CTO at a small company carrying every hat, and you want to know which ones to put down first.
  • You're using AI tools seriously and want guardrails that hold up in production.

It is not for you if you want a promotion script, a vendor comparison, or a framework that replaces judgment. There's no shortcut in here. There are, I hope, fewer wrong turns.

Three ways to read it

Suggested routes
If you are…Start withThen
An engineer taking on infra, cost or reliabilityParts II–IVChapter 27, then Part I
A new tech lead or managerPart VChapters 2, 6 and 21
A small-company CTO wearing every hatChapters 24 and 25Part V, then Chapter 9
Running a platform teamChapters 8, 15 and 6Part IV

Every chapter ends with a short Try this week box. They're deliberately small: one experiment you can run before the next planning meeting, not a programme you'd need approval for.

How it's organised

The middle of the guide follows the loop I've used in every role: Measure → Optimise → Automate → Repeat. Part II is about seeing clearly. Part III is about spending well — money, carbon, risk. Part IV is about making improvements stick. Part V is about the people, which is most of the job. Part VI covers the traps I fell into, so you can fall into different ones.

Part II

Measure

You can't fix what you can't see — and you can damage what you measure badly.

Chapter 5

Visibility Before Change

I don't start by changing things. I start by understanding them. In every role — new company, new team, new codebase — the first weeks go into the same three questions:

  1. What does this cost? In money, in time, in incidents, in carbon.
  2. Where does work get stuck? Between which stages, waiting on whom?
  3. What fails, and how would we know?

If nobody can answer, the first deliverable is the ability to answer. That's not procrastination; it's the foundation every later decision rests on.

Measure, Optimise, Automate, Repeat A four-step cycle. Measure feeds Optimise, Optimise feeds Automate, Automate feeds Repeat, which returns to Measure. Each automation produces new telemetry. Measure observability · metrics · friction Optimise highest-leverage change first Automate make the gain stick Repeat new baseline, next question every automation emits new telemetry
The loop behind every part of this guide

Observability as a reflex

In my own code, error tracking goes in before the features do. Sentry is literally the first line of the app's entry point in two-file hobby projects. Flagship work adds request IDs in every log line, OpenTelemetry traces, Prometheus metrics, and healthcheck endpoints. It sounds excessive for a hobby app. It isn't: the cheapest time to add telemetry is before you need it, and the most expensive time is during the incident.

In practice

Telemetry precedes features. If a new service can't tell you it's unhealthy, it isn't ready, however good the code is.

The clearest lesson I had in this came from an open-source project, not a job. When I took over the infrastructure for Badge Poser — a PHP service generating README badges for a lot of projects — the first workaround didn't hold, and the slide I showed afterwards at PUG Roma and Codemotion was titled simply: "It keeps crashing: need visibility." Centralised logs and uptime checks came before any further fix. More on that story in Chapter 12.

Surface the friction, not just the errors

Error rates are the easy part. The friction that drains teams rarely throws exceptions: a pipeline that takes twenty minutes, a review queue that sits for two days, a manual step everyone performs and nobody owns. Those don't show up on a dashboard unless you put them there.

Chapter 6

Metrics That Matter (While They Matter)

In 2019 I gave a talk called IT Metrics in Real Life (and later turned it into a book). It ended with three recommendations I still stand by:

  1. Measure what matters, while it matters. A metric that answered last year's question is noise this year. Retire it.
  2. Focus on the goal, not the metric. The moment a number becomes the target, people optimise the number.
  3. Don't use raw metrics as performance evaluation. Deployment counts are about the system. Using them to rank people breaks both the people and the metric.

The talk's other point was that every role needs different numbers. I walked through seven perspectives — developer, DevOps, sysadmin, customer support, project manager, HR, and manager — from cyclomatic complexity and build time to MTTR, defect escape rate, team morale and bus factor. A metric that's vital to one seat is noise to another, which is exactly why one dashboard for everyone tends to serve no one.

DeveloperCyclomatic complexity, code coverage, technical debt
DevOpsBroken builds, build time, deployment frequency, change fail %
SysadminUptime, MTTR, MTBF, disk I/O
Customer supportFirst response time, defect escape rate
Project managerLead time, velocity, burn-down variance
HRTeam morale, tech-test passing rate
ManagerBudget, earned value, turnover, bus factor
Seven seats, seven sets of numbers — from IT Metrics in Real Life (2019)

The set I use today

At Treatwell I track delivery health with three layers, because each one catches what the others miss:

Three lenses on delivery
LensWhat it measuresWhat it misses
DORADeployment frequency, lead time for changes, change failure rate, time to restoreWhy work is slow; how people feel about it
SPACE signalsCycle time, review-to-merge time, CI/CD coverage, WIP limits, tech-debt age, infra incident rateWhether the work being done is the right work
CSAT surveysDeveloper satisfaction with the platform and its toolsAnything people have stopped noticing

Using these, we doubled the platform team's throughput by removing bottlenecks and standardising IaC and CI/CD practices. The surveys mattered as much as the dashboards: numbers told us where work slowed down; people told us why.

When metrics lie

  • Small numbers are noisy. One bad week on a small team swings every rate. Look at trends, not points.
  • Averages hide two populations. "Average lead time" can be a mix of trivial changes and stuck ones. Split them.
  • Slow delivery is almost always a systems problem, not a people problem. If the dashboard points at a person, check the system first.

Label what you don't know

Two rules from my tooling that I now apply to every dashboard. First: not run is a third state, and it isn't scored — a check that didn't execute is not a pass, and a repository shouldn't reach green by quietly accumulating exceptions. Second: every number carries its provenance — measured, declared, or guessed. A guess with a label is useful. A guess dressed as a measurement is how a whole report loses credibility.

When teams hesitate to ship, the problem is usually reliability, not courage. Fix observability and the release process, and confidence follows.

Chapter 7

Estimates That Don't Lie

As Technical Project Manager at Skuola.net I owned estimation and forecasting for the whole team: planning poker, burn-downs, capacity planning, Gantt charts when the business needed dates. I learned the hard way that a single number ("three weeks") is a promise disguised as an estimate.

Ranges, not points

In 2019 I wrote Practical Estimates, applying the Monte Carlo method to software work. The idea is simple: instead of guessing one duration, use your team's real historical throughput, simulate thousands of possible futures, and answer with a probability.

Not:   "It'll be done in 3 weeks."
But:   "50% chance by week 3. 85% by week 5.
        If the date is fixed, here's the scope we can commit to."

A range turns a negotiation about optimism into a conversation about risk — and gives the business a real choice between date and scope.

Illustrative Monte Carlo forecast A cumulative probability curve rising from zero at week one to nearly one hundred percent at week seven. It crosses fifty percent at week three and eighty-five percent at week five. Illustrative shape, not real data. 0%50%85%100% wk 0123456 50% chance done by week 3 85% chance done by week 5 50% by week 3 85% by week 5 weeks from start
What a range looks like — illustrative shape, not real data

How to run one, by hand

  1. Take your team's weekly throughput for the last ten to twenty weeks — items finished per week, nothing fancier.
  2. Count the items left in the piece of work. Split anything huge; don't size anything.
  3. Simulate: for each future week, pick a random past week's throughput, subtract it from what's left, repeat until done. Record how many weeks it took.
  4. Do that a few thousand times — a spreadsheet is enough. Sort the results. The 50th and 85th percentiles are your answer.

It works because it uses what actually happened, including the weeks lost to incidents and holidays that optimistic estimates always forget.

The oldest constraint still applies, and I put it plainly in my own learning book: cheap, fast, and without defects "cannot be obtained together, one of the three must be sacrificed." An estimate that pretends otherwise is just choosing which one to sacrifice later, in secret.

Define "done" before you start

Many estimate misses are really disagreements about what "done" means. I wrote about this in The Tricky Definition of Done: merged isn't done; deployed isn't done; done is when the business outcome is available to the people who needed it, with the monitoring to know it's working.

Try this

Write the definition of done into the ticket template, not into people's heads. Then estimates have something stable to point at.

Chapter 8

Maturity Models Are Maps, Not Grades

When I took over platform engineering at Treatwell, one of the first things I did was assess the platform against the CNCF Platform Engineering Maturity Model. It looks at five dimensions, each with four levels.

CNCF platform maturity — the shape of the map
DimensionAsks
InvestmentHow are people and money allocated to the platform?
AdoptionWhy and how do teams discover and use it?
InterfacesHow do people interact with it — tickets, docs, self-service, APIs?
OperationsHow is it planned, run, and maintained?
MeasurementHow do you know it's working, and for whom?

The levels run Provisional → Operational → Scalable → Optimising. We baselined at Provisional and drove toward Operational, with the clearest progress in documentation and observability. I also introduced DevSecOps and platform maturity models alongside it.

BaselineWhere we focused first (docs, observability)
Baseline everywhere, focus in two places — simplified; real assessments are rarely this uniform

How to use one without being used by it

  • Baseline honestly. A generous self-score is a wasted assessment. Provisional is a perfectly good starting point.
  • Pick one or two dimensions per cycle. Trying to raise all five at once is how roadmaps die.
  • Use it to explain, not to grade. In budget conversations, "we're Provisional on Measurement, which is why we can't answer your question" is far more persuasive than "we need observability".

Running the assessment

The assessment itself is worth more than the score. Do it with the people who use the platform, not just the people who build it: product engineers will place you lower on Interfaces than your own team will, and they're the ones who are right. Write down the evidence for each level you claim — a doc, a dashboard, a survey result — so the next assessment compares facts, not memories. Then repeat it on a fixed cadence. A single assessment is a snapshot; two make a trend; three start to make a case.

A maturity model is a map of where you could go. It's not a report card on where you are.

If you’re trying to work out what to measure where you work — or why the numbers you already have don’t help — it’s the conversation I have most often. A 30-minute call is usually enough to find the first question worth answering.

Part III

Optimise

Money, carbon, risk and latency — four budgets that turn out to be the same conversation.

Chapter 9

Cost Is a Design Property

Cloud costs should be intentional, not accidental. I've cut infrastructure spend at three companies, and none of those cuts came from a heroic one-off. They came from visibility, followed by boring, consistent decisions.

Cost work, by context — not a benchmark
WhereResultHow
Skuola.net (CTO)−30% overall IT costBudget ownership, caching, IaC, stack upgrades
Radical−50% dev & pre-prod spendCost monitoring, observability, alerting
Treatwell (2024)−10% AWS costAccount consolidation, right-sizing, EKS upgrades, decommissioning; cost-allocation tagging

Notice the percentages shrink as the company gets bigger and more mature. That's normal. The first 30% at a small company is often waste nobody looked at. The 10% at a mature one is earned line by line.

The FinOps habits that matter

TagEvery resource has an owner
Show backTeams see their own spend
Right-sizeMatch capacity to real use
DecommissionTurn off what nobody needs
ReviewOn a calendar, then repeat
Cost work as a cycle, not a project
  • Tag before you optimise. If spend can't be attributed to a team or service, it can't be owned, and unowned spend only grows.
  • Showback before chargeback. Let teams see their costs before you make them pay for them. Visibility changes behaviour on its own.
  • Decommission deliberately. The cheapest resource is the one you turned off. Make removal a normal, celebrated kind of work.
  • Review on a cadence. Cost optimisation isn't a project. It's a practice with a calendar slot.

Tools that respect intent

Two principles from the cost tools I've built since. A cost report is a piece of writing, not a dataset: it should say what moved, and treat brand-new spend separately, because letting new spend fall through a percentage filter is how a surprise bill survives long enough to become an annual one. And an idle-resource scanner should never delete anything — it can't know your intent, and a scanner with delete permissions can cause the very incident it exists to prevent. The permission set is the proof of the claim.

One more lever people forget: reliability targets are a cost decision. Designing for five nines when the business needs three means paying — in money and energy — for over-provisioning nobody asked for. Match the SLO to the actual need.

For the budget meeting

Never present a saving without the reliability story next to it. A cut that raises incident risk is a loan, not a saving, and finance will find out when it's called in.

Chapter 10

Carbon Is the Next Cost Line

Somewhere in the middle of the cost work I noticed something: almost every lever that cut the bill also cut energy. Right-sizing, shutting down idle environments, scheduling batch work smartly — they're FinOps levers and GreenOps levers at the same time.

The ICT sector is commonly estimated at around 4% of global greenhouse gas emissions. I think that's an engineering responsibility, not a marketing one. In 2025 I became a Green Software Champion through the Green Software Foundation and published GreenOps & GreenCoding, free to read.

GreenOps is where DevOps, FinOps and sustainability overlap Three overlapping circles labelled DevOps, FinOps and Sustainability. Their shared centre is labelled GreenOps. DevOpsFinOpsSustainability automation, deliverycost visibilityenergy, carbon GreenOps
GreenOps = DevOps + FinOps + Sustainability, from GreenOps & GreenCoding

The book's working definition is short: GreenOps = DevOps + FinOps + Sustainability. GreenOps grew out of FinOps — the same techniques that cut cloud cost also cut energy and emissions. Its first rule is just as blunt: if you don't measure your digital carbon footprint, you can't reduce it. And its warning: offsets should be the last step, not the first.

Getting it adopted

The hardest part isn't technical. Engineers often see sustainability as extra work, so the advice I give in the book is to make it not extra: embed it into existing workflows and policy-as-code guardrails, present it as low-effort and high-impact, and — for executives — start with a cloud cost initiative. If it saves money, support for expanding it follows. Culturally, it belongs in onboarding, the same way security training does.

Measure, then budget, then place

Carbon follows the same loop as everything else. I've built open-source tools for each step:

  • Measure: co2-grid-meter, carbon-badge, greenlint (a linter where every finding explains why it wastes energy), plus Terraform/Helm modules for Kepler, Scaphandre, OpenCost, KubeGreen and others.
  • Budget: carbon-budget-action, a GitHub Action that fails a PR when its carbon cost exceeds a budget — the same way a test suite fails on a regression.
  • Place: carbon-region-picker for choosing lower-carbon regions when latency and data rules allow.

Two design rules run through all of them. Rank regions by filtering on latency first and carbon second, rather than inventing an exchange rate between milliseconds and grams that nobody could defend. And when the data isn't there, return nothing rather than a plausible guess — a carbon figure a reviewer can't check is not a disclosure.

Sustainable software isn't a constraint. It's the same discipline as cost control, pointed at a second bill the planet pays.

The regulatory direction in Europe — sustainability reporting on one side, the Cyber Resilience Act on the other — suggests engineers who can account for carbon will be asked to. My opinion: learn it before you're told to.

Chapter 11

Disaster Is a When, Not an If

In 2021 a fire took out a datacenter at OVH's Strasbourg site. A lot of people discovered, overnight, that their backups lived in the same building as their servers.

I ran a handful of small personal websites at the time. Nothing critical. But I asked myself the uncomfortable question — what happens if my provider disappears tonight? — and didn't like the answer. So I fixed it, on a budget, and documented every step in a ten-part series, a talk, and the book Save Yourself From a Disaster.

  1. Secure the database — real backups, tested restores
  2. Secure the storage — off-site copies of everything that isn't code
  3. Redundancy of the database — replication across providers
  4. Redundancy of storage
  5. Redundancy of web servers — more than one place to serve from
  6. Redundancy of DNS — the single point of failure everyone forgets
  7. Billing impact — what this actually costs per month
  8. Manual configurations — hunting down everything that isn't in code
  9. Disaster recovery plan — written down, with a threat taxonomy
  10. Play with providers — prove you can actually move
The trap inside step one

A backup you haven't restored is a hope. Integrity is not restorability: a logically corrupt dump has perfect checksums, and monitoring the backup job only tells you it exited zero. Restore it, on a schedule, and test what comes back. And watch the calendar — a quarterly test that slips twice is an annual test.

Two things from that talk people ask about most. First, start by writing down your RTO (how long you can be down) and RPO (how much data you can afford to lose); every other choice follows from those two numbers. Second, the bill — because resilience has a price, and the honest move is to show it and then optimise it.

What redundancy cost my personal sites, per year
StageWhat's in itAnnual cost
BeforeOne DigitalOcean VPS at $5/month$60
Fully redundantThe same VPS, plus a Hetzner VPS (€3.04/month, about $43/year), off-site backups on AWS S3 (about $26/year), and premium DNS for five domains ($2.88 each, $14.40/year)$143.47+
After trimmingShorter backup retention, no static mirror, DigitalOcean replaced with a second Hetzner VPS in another region, and DNS fallback dropped for non-critical sites$88
Annual cost of redundancy for my personal sites Bar chart. Before: 60 dollars a year. Fully redundant: 143 dollars 47 cents or more. After trimming: 88 dollars. $0$50$100$150 BeforeFully redundantAfter trimming Before: $60/year Fully redundant: $143.47+/year After trimming: $88/year $60$143.47+$88
From the Save Yourself From a Disaster talk — the table above has the line items

The first redundant setup more than doubled the bill, and I said so on stage. The setup hours weren't on that bill either. Then I cut back, one line at a time:

  • Backup retention. I was keeping 24 hourly, 31 daily, 12 weekly and 3 monthly backups: 70 copies, 3 GB in total. Retention is a policy, and it should follow from your RPO, not from habit.
  • The static mirror. A full static copy of the sites, kept on S3 as a last resort, was the biggest thing in storage. Once the services themselves were redundant, it was paying for the same risk twice.
  • Providers. Replacing DigitalOcean with a second Hetzner VPS in another region saved another ~$10 a year. The cost was relying on one provider across Germany and Finland — acceptable only because the whole thing was in IaC and I could move providers in minutes.
  • DNS fallback. Worth paying for if your sites make money; a few dollars per domain adds up fast if they don't.

The final figure was $88 a year: an extra $28, about $2.50 a month — "just like a couple of coffees" for peace of mind. One caveat I gave at the time and repeat here: free AWS credits were covering the backups, so that line was temporarily zero.

The trade-off, stated plainly

Giving up multi-provider high availability to save money was the right call for sites that aren't critical or very profitable. It would be the wrong call for anything that is. Redundancy is a business decision priced in coffees or in outages. Make it on purpose.

My personal infrastructure ended up spread across Hetzner (two regions), Scaleway, AWS and Cloudflare DNS, with a written Disaster Recovery Plan covering threats from "one application fails" all the way up to "a whole provider is gone". For personal websites. That's the point: if it's feasible for a hobby budget, it's feasible for yours.

Ceremony check

A DR plan for four personal sites sounds like overkill. It isn't, because the risk is real and the cost was small. Ceremony should follow risk and audience, never effort — more on that in Chapter 25.

At Skuola.net, the same thinking became a secondary data centre and an upgraded stack. At Treatwell it became AWS Well-Architected reviews and disaster-recovery structures. Same question, different scale.

Chapter 12

Caching, Performance, and Patience

My first public talk, at PUG Roma in 2016, was on performance optimisation, in front of fifty-odd people. Its opening line is still the one I'd lead with: performance is a process, not a project. Its second lesson was about measuring it: use percentiles, not averages, because averages can be misleading — the median hides the users having the worst time. And underneath both: the fastest request is the one you never have to compute.

At Skuola.net, a careful caching strategy — Varnish in front, Redis and Memcached behind — cut web server load by half. Not by rewriting the application. By putting the right answer in the right place, and being honest about how stale each answer could be.

Failure modes are features

When I built go-proxy-cache, I designed the resilience in from the start, not after the first outage:

  • Circuit breakers around dependencies, so a slow upstream doesn't take you down with it.
  • Cache-stampede protection with jitter, so a thousand clients don't recompute the same expired page at once.
  • Serve-stale windows, so an upstream blip shows slightly old content instead of an error.
  • Upstream healthchecks and configurable timeouts, because the defaults are rarely right.

The principle underneath all of them: a cache is an optimisation, and an optimisation must not become a hard dependency. Plenty of setups quietly turn a Redis outage into a total outage. Mine should degrade to slower, never to down.

Design the failure modes. Don't wait to discover them.

A DevOps journey, in public

InheritOne VM, software 4–6 years old
WorkaroundsTuning that didn't hold
VisibilityCentral logs, uptime checks
FireOOM killer, CPU capped at 20%
Start overContainers on ECS
Step backAlpine unstable → Debian
CacheNginx + Lua, serve stale
Dark canaryForked real traffic first
99.97%Deploying during breakfast
Badge Poser v3.0, from the 2020 talk

In 2020 I told the full story of taking over Badge Poser's infrastructure in a talk called Badge Poser v3.0: A DevOps Journey. It started on a single VM running software four to six years old — Apache 2.4.10, PHP 5.6 past end of life, Redis 2.8, MySQL 5.5. Then everything went wrong in sequence: workarounds that didn't hold, the OOM killer taking Redis down, burstable instances running out of CPU credits and getting capped at 20%. At one point the right move was literally "ditch everything, start over" on containers — and even then, a multi-container Alpine setup proved unstable, so I took a step back to the boring all-in-one Debian image that worked.

What fixed it in the end was caching (Nginx + Lua, which became nginx-lua, and later full-page caching with go-proxy-cache), proper observability, and dark-canary releases that forked a slice of real traffic to the new version before it took any of it. The result was 99.97% uptime, and — my favourite slide — deploying during breakfast. That's what confidence looks like.

The talk's takeaways

Never trust code — and never trust yourself. Use specific versions; never use the latest tag. Commit often and version everything. Do small steps. Prefer quick and easy fixes. Don't stick to playing by the manual. Monitor and benchmark: they're your best friends for troubleshooting.

Patience

Performance work rewards patience more than cleverness. Profile first (XHProf, in my PHP years). Change one thing. Measure again. The tempting big rewrite is usually a way of avoiding the boring measurement.

Cost, carbon and recovery are most of my day job. If one of them is the thing on your mind, this is where I usually help.

Part IV

Automate

Making improvements stick — in code, in pipelines, in platforms, and now in agents.

Chapter 13

If You Can't Reproduce It, It's a Liability

I favour Infrastructure as Code over manual configuration, every time. A snowflake server is risk with a hostname.

At Skuola.net we brought 80+ servers under IaC with Ansible, Terraform and Packer. Maintenance time dropped by about 80%. More importantly, the infrastructure became reviewable: a change was a diff someone could read, question, and roll back.

At Radical I gave an internal talk on Infrastructure as Code whose whole pitch fit in its subtitle: how to version infrastructure changes and sleep soundly. That's still the best argument I know for it.

At Treatwell I introduced Terraform to the platform toolbox and expanded it across engineering until it managed all of our stateful resources. Then came the guardrails — policy checks and automated scans — so that the easy path and the safe path were the same path.

The manual-configuration hunt

Step 8 of my disaster recovery series was "manual configurations", and it's the one I recommend to everyone. Sit down and list everything that only exists because somebody clicked it: DNS records, a console setting, a cron entry on one box, a secret in someone's password manager. Each item is either a candidate for code or a known risk you've chosen to accept. Both are fine. Unknown is not.

In codeReviewed, versioned, reproducible
Known riskWritten down, owned, accepted on purpose
UnknownThe only state that isn't acceptable
Where every clicked setting should end up

Drift is the slow failure

The other half of IaC is keeping it true. Code that describes infrastructure as it was six months ago is worse than no code, because people trust it. Run plans on a schedule and treat unexpected differences as incidents in miniature: someone changed something by hand, and the question is why the code didn't make the right path easy enough. Vendor-agnostic tools help here too — I've always preferred Terraform and Ansible for exactly that reason, so the description of the infrastructure doesn't lock you into one provider's configuration language.

Secrets climb a ladder

Match the secret handling to the exposure
ExposureHandling
Private throwaway prototypeAcceptable shortcuts — never in anything with readers
Anything shared.env.dist templates, real values outside the repo
Infrastructure in gitEncrypted at rest: Ansible Vault, SOPS with age
Platform servicesA managed store (AWS Secrets Manager), least-privilege access
Chapter 14

Toil Is a Silent Tax

Manual deployments, manual checks, manual rollbacks. Toil never shows up as an incident. It shows up as a team that's always a bit tired and never quite has time for the important thing.

At Radical, streamlining the CI/CD pipeline halved its running time. At Treatwell, onboarding five-plus engineering teams onto standard tooling cut tooling complexity and operational overhead by roughly 35%. Neither was glamorous. Both gave people back hours every week.

The one-verb front door

My favourite anti-toil pattern is tiny: every project I touch exposes its whole lifecycle through one self-documenting entry point.

$ make help

Usage: make <target>

##@ DEVELOP
  setup       Install hooks and toolchain
  dev         Run locally
##@ QUALITY
  lint        Lint everything
  test        Run the test suite
  sca         Lint + security scan + format check
##@ RELEASE
  build       Build the artefact
  release     Tag and publish

Nobody should need tribal knowledge to build, test, or deploy. I've done this since 2012 — first as a ./console script, later as Makefiles with a help target — and in 2026 it turned out to be exactly what AI agents need too. An agent that can run make test doesn't need to guess.

Auditing toil

  1. For two weeks, ask the team to note every repetitive manual task. Duration and frequency, nothing more.
  2. Multiply. Sort. The top three are usually obvious and usually smaller than people expect.
  3. Automate one. Tell everyone the hours it saved. Then do the next.
Prioritising toil by frequency and duration A two-by-two grid. Frequent and long tasks: automate first. Frequent and short: script it. Rare and long: write a runbook. Rare and short: leave it. Script itAutomate first Leave itWrite a runbook often, but quickoften, and slow rare and quickrare, but slow duration per occurrence → frequency →
A rough triage for the toil audit — the numbers decide the borders

If you put a money figure on toil — and it helps, in budget meetings — make every assumption defensible. Count triage once per broken commit, not once per red check. Leave unknown queue time at zero rather than inventing it. The audit is only as credible as its assumptions, and one inflated number discredits the whole thing.

Chapter 15

The Platform Is a Product

An Internal Developer Platform is a product, not a project. Projects end. Products have users, and users can leave — quietly, by building their own workaround.

So I run the platform like one:

  • A vision and a roadmap that teams can read and argue with.
  • Adoption metrics, because a golden path nobody walks is just a path.
  • Satisfaction surveys, because adoption can be forced and satisfaction can't.
  • A service catalog — Backstage, at Treatwell — so ownership is a fact, not a guess.
  • Pipeline building blocks — shared GitLab CI/CD components — so teams compose pipelines instead of copy-pasting them.

Golden paths, not golden cages

The aim is to make the right way the easy way, without forbidding the other ways. If a team has a real reason to go off-road, the platform team should learn from it, not block it. Often their workaround is your next feature.

Infrastructure should be invisible — not because nobody cares, but because it's never the source of friction or surprise.

Moving a platform is the real test

Treatwell went from a mix of bare metal and cloud to 100% AWS during my time there. Migrations like that are where a platform team shows its value: not in the new architecture diagram, but in how little product teams had to stop and think about it.

RoadmapPublic, arguable
Golden pathEasiest way is the right way
AdoptionWho actually uses it
SatisfactionSurvey, in their words
WorkaroundsTomorrow's features
Run the platform like a product: every step feeds the next roadmap

Who the platform team serves

The hardest mindset shift for a platform team is accepting that its customers are other engineers, and that they have alternatives — including doing nothing. That changes how you prioritise. A feature only the platform team finds elegant is a cost. A boring improvement to the thing every team touches daily — a faster pipeline, a clearer error message, a template that works the first time — is worth more than any new capability. When onboarding five-plus teams cut tooling complexity and operational overhead by about 35%, nothing about it was novel. It was the same few paths, made smoother, for more people.

Chapter 16

Security Debt Is Silent Until It Isn't

Vulnerabilities pile up quietly with no clear owner until one becomes a crisis. My approach is the same loop again: build visibility, assign ownership, reduce the backlog bit by bit, automate the scanning.

Least privilege, by default

At Treatwell I've pushed toward Zero Trust with least-privilege IAM and Service Control Policies, alongside automated security scans and Terraform guardrails. None of it is exotic. All of it has to be continuous.

Supply chain, from the maintainer's side

Maintaining nginx-lua since 2020 taught me that open source security is mostly maintenance. Keeping a multi-distro, multi-arch build matrix green and absorbing upstream breaking changes for six years is the real work, not the first commit. Along the way I've adopted:

  • SBOMs generated automatically (Syft, Trivy), so anyone can see what's inside.
  • Signed images with Cosign, so anyone can verify where they came from.
  • OpenSSF Scorecard, to measure the project's own security posture.
  • CI actions pinned to commit SHAs, with the version in a comment, because tags can move.

In 2026 I completed Linux Foundation certifications on the EU Cyber Resilience Act, security self-assessments, and SBOM-based supply chain automation. My opinion: the CRA will make much of this mandatory for anything with digital elements sold in the EU. It's cheaper to have the habits before the deadline.

Ownership beats tooling

Every scanner I've seen adopted produced the same first week: a wall of findings, nobody sure who should fix them, and a strong temptation to turn the scanner off. The fix isn't a better scanner. It's ownership — each finding lands with the team that owns the service, the backlog shrinks a little every sprint, and new findings are held to a stricter bar than old ones. Introduce gates in warn mode first: a tool that breaks the build the day it's installed gets uninstalled the same day.

SourceActions pinned to SHAs
BuildReproducible, in CI
SBOMSyft, Trivy
SignCosign, bound to the workflow
ScoreOpenSSF Scorecard
VerifyBefore it runs
Each step makes a claim the next one can check

Be precise about what each control guarantees. An image-signature check in an init container, for example, is a speed bump, not a boundary — and a signature that is merely valid only proves somebody signed it; one bound to this workflow in this repository says who. A security control that overstates its guarantee is worse than no control, because somebody will rely on it.

Baseline, not bonus

Scanning, signing, SBOMs and least privilege aren't extras for mature teams. They're the minimum for anything other people run.

Chapter 17

Direct the AI. Don't Trust It.

In 2026 I built more public repositories than in any year before — around 37 new ones, most with tagged releases — with heavy AI assistance. Most of the code was written by agents under my direction. That changed my job on those projects from author to director, and it taught me where the leverage is and isn't.

Steering files are the new onboarding doc

Nearly every repository gets its own CLAUDE.md, written for that project — never a stamped template. They all follow the same four sections:

The steering file grammar
SectionContainsExample
ProjectIdentity and the product thesis"The rule set is the product."
CommandsThe make verbsmake dev / lint / test / build
ConventionsHow work is shapedConventional Commits drive the release; never hand-edit the changelog
GuardrailsWhat's off-limitsPrefer the stdlib; new rules need a rationale and a test; ask before large refactors

It's the same thing you'd tell a new team member on day one. The better the onboarding, the better the output — for people and for agents.

Gates, not trust

I don't merge AI output on trust. The harness I'm building runs each change through gates and uses the resulting score as a control plane:

Auto-mergeLow risk, small blast radius
Open a PRNeeds a human to read it
HoldHigh risk or wide blast radius
Risk and blast radius decide how much human review a change gets

That harness is still in development. The principle isn't: review effort should scale with risk, not with how confident the generated code sounds.

Contain the agent

Agents that can run commands can also run the wrong ones. Two of my tools exist for exactly that: offline cuts a process off from the network, and azkaban confines a coding agent to one project directory. Both follow one rule — subtract, don't permit — so every future mistake in the configuration is a mistake of omission, which fails safe. And both are honest about it: they're fences, not vaults. Relying on an agent's own permission prompts means trusting it to classify its own actions correctly, which is exactly the component you're guarding against. In my own local-first platform (still in development), an LLM is allowed to act on the live database — but only from localhost, after a snapshot, with automatic rollback if a run deletes data.

Subtract, don't permit: fences around the agent, not trust in it

Reviewing code nobody wrote

  • Reproduce before you believe. Models invent plausible bugs as readily as they invent plausible code — and they'll meet whatever standard you ask of them, including a low one.
  • Don't close the loop on itself. Reviewing a diff against a description generated from that same diff can only ever agree with itself.
  • A fix is a new artefact. It gets reviewed like one.
  • Know what wasn't checked. An audit that can't tell a clean report from an empty one isn't an audit.

AI makes producing code cheaper. It doesn't make being wrong any cheaper. Spend the time you save on review, tests, and containment.

At work the same principle applies at team scale: I introduced AWS Bedrock to the platform so teams could build with AI on infrastructure we govern, and we use Claude Code and Copilot for IaC authoring and tooling — with the same review bar as any other change.

The assessments, templates and guardrail sets I use in practice aren’t in this guide; they only make sense applied to a specific platform. If you’d like to look at them against yours, get in touch.

Part V

Grow People

Building foundations is mostly people. I treat that as the real job, not overhead.

Chapter 18

Hiring, and the 1:1 That Follows

I've hired around thirteen engineers across my career. The hiring decision felt like the big one each time. It wasn't. What happened in the first year after it mattered far more.

Hire with a challenge you'd want to take

At Skuola.net I designed our technical challenge and later explained it publicly. My rules: the challenge should be small enough to respect the candidate's time, open enough to show judgment, and reviewed against a written checklist so two reviewers reach the same verdict. I later published that review checklist as open source. "No over-engineering" is one of its lines — on purpose.

The 1:1 is the job

My 1:1s have a running agenda: a shared document both of us add to during the week, so the meeting starts with what matters rather than "so… how's it going?". A rough shape:

  • Their topics first. It's their meeting.
  • Blockers — what I can remove this week.
  • Growth — one thread we're pulling on, tied to the career framework.
  • Feedback, in both directions, little and often.
Small habit, big effect

Write down what you agreed. Next week, start there. Consistency is what makes a 1:1 feel like support rather than surveillance.

The first ninety days

Most of what decides whether a hire works out happens in the first three months, and most of it is the manager's job, not the new person's. My checklist is short:

  • A first change in production in the first week or two, however small. Nothing builds confidence like seeing your work live.
  • An onboarding path measured in copy-pastes, not tribal knowledge. If setup needs a person to explain it, it needs fixing.
  • A named buddy who isn't the manager, for the questions people are embarrassed to ask their boss.
  • An explicit check-in at thirty, sixty and ninety days, about expectations in both directions.

Onboarding is also the cheapest audit your team will ever get. A new hire sees every broken doc and every undocumented step with fresh eyes. Ask them to write it down — and then actually fix what they find.

Chapter 19

A Career Framework You Actually Run

Plenty of companies have a career framework. Fewer use one. At Skuola.net we had no formal review process at all; at that size, 1:1s were it. At Treatwell I defined the platform engineering roles and career framework for my team, then did the part that matters: ran people through it.

The performance cycle, as I run it
CadenceWhat happens
Weekly1:1 with a running agenda
QuarterlyCheck-in against the framework: where you are, what's next
YearlyFormal review, then calibration with peer managers
YearlySalary review within the defined ranges
When readyPromotion case

Promotions are built, not requested

I've driven one promotion case end to end, drafted a second, and backed a third. The pattern that worked: decide early, with the person, which expectations they're working toward, then collect evidence through the year. A promotion case written in a weekend is a guess. One written from a year of notes is a record.

Calibration keeps you honest

Calibration with peer managers is uncomfortable, and that's why it works. It's the moment your "exceeds expectations" meets someone else's definition of the same words. Go in with evidence, not adjectives.

Fifty-two conversations, four check-ins, one review — the review should hold no surprises

Writing a framework people can use

The career framework I wrote for my team had one test: could an engineer read it and say, specifically, what they'd need to do to reach the next level? That rules out most adjectives. "Strong communication" fails the test; "explains a design trade-off in writing so that someone outside the team can challenge it" passes. Keep levels few, describe behaviour rather than traits, and include the platform-specific things that generic frameworks miss — ownership of shared infrastructure, on-call maturity, how someone improves other teams' experience, not only their own output.

Chapter 20

The Harder Half

Most writing about growing people covers the pleasant half: coaching, stretch projects, promotions. The other half is part of the job too.

I've managed an engineer through a performance improvement plan, and when it didn't work out, I managed the exit. I'm not going to share details — they aren't mine to share — but I can share what I'd tell myself beforehand:

  • Say it early. The kindest version of hard feedback is the earliest one. A surprise at review time is a management failure, not theirs.
  • Be specific. "Not senior enough" helps nobody. "These three expectations, with these examples" is something a person can act on.
  • Make the plan real. A PIP with goals nobody could reach is a paper trail, not a chance. Write one you'd want to succeed.
  • Protect the team's bar. The rest of the team sees how you handle this. Letting it drag is unfair to them too.
  • End with dignity. However it ends, it should end clearly and humanely.

Protecting the team's bar sometimes means making the decision nobody enjoys — clearly, and without dragging it out.

Early signalSay it the week you see it
SpecificExpectations, with examples
Real planReachable goals, real support
Clear decisionEither way, with dignity
The earlier each step happens, the less likely you need the last one

Look at the system first

Before concluding that a person is the problem, I check the system around them — the same instinct as with slow delivery. Are the expectations written down? Was the onboarding real? Is the work they've been given actually at their level, or did we hand them the hardest, least-defined problem we had? Sometimes the honest answer is that we set someone up badly, and the fix is ours. Sometimes it isn't. Either way, you can only make a fair call once you've ruled out the first possibility.

Chapter 21

Delegate the Project, Keep the Outcome

As a manager I stay accountable for outcomes. But I hand each project to a single owner to lead, instead of owning them all myself.

Single owner matters. A project with two owners has none; a project "owned by the team" belongs to whoever cares most that week. One name, clearly stated, with the authority to make calls.

What I keep, what I give

Delegation, split down the middle
The owner decidesI stay accountable for
How the work is broken downWhy the work matters, and its priority
Technical approach, within guardrailsThe guardrails themselves
Day-to-day trade-offsOutcomes, and what we tell stakeholders
When to ask for helpBeing available when they do

People don't grow doing work you've already decided for them.

The hardest part, for an engineer-turned-manager, is watching someone take a different path from the one you'd have taken. If their path is safe, let it run. You might learn something. They certainly will.

How to hand a project over

A good handover is a short written brief, not a meeting. It answers four things: why the work matters and to whom; what done looks like, including how we'll know; the guardrails — budget, deadline, the things that must not break; and when to escalate, so the owner knows which decisions are theirs and which aren't. Then agree how you'll keep up — a weekly written update usually beats a status meeting — and resist the urge to check in more often than that.

A useful test

If the owner comes to you for every decision, the brief was unclear or the guardrails were too tight. If they never come to you, check the brief said when to escalate.

Chapter 22

Grow Your Replacement

The clearest test of whether you've grown people is whether they could replace you.

When I stepped down as CTO, the person who took over was someone I had developed into the role. Since then I've developed a couple of leads the same way. It's not altruism. It's the only thing that makes a leader's next move — up, sideways, or back to the keyboard — safe for everyone left behind.

How to start, this quarter

Name itSay it out loud
Give itA real responsibility
Show themIn the rooms that decide
Write itDecisions and runbooks
Each step makes the next one possible
  1. Name it. Tell the person you see them as a possible successor for parts of your role. Ambiguity wastes a year.
  2. Give away a real responsibility, not a task: a recurring meeting, a budget line, a stakeholder.
  3. Let them be seen. Bring them to the meetings where decisions are made, then let them speak.
  4. Write things down. Every decision record and runbook you write is succession you don't have to do in person. Undocumented decisions can never be challenged, improved, or handed over.
Uncomfortable but true

If you're irreplaceable, you're also unpromotable — and you can't leave either.

The bus-factor view

In my metrics talk, bus factor sat on the manager's list: how many people would have to disappear before a project stalls. Apply it to yourself. If the answer for your own role is one, that's a risk you're carrying for the company, and a ceiling you're putting on your own next step. Raising it is slow, deliberate work — but it's the work that turns a leader's departure, promotion or swing back to engineering into a non-event.

Chapter 23

Mentoring Outside the Org Chart

Some of the most useful growth I've been part of happened outside any reporting line. On MentorCruise I've mentored sixteen engineers so far, at every career stage: AWS, Kubernetes, Terraform, CI/CD, architecture, Go, PHP, and plenty of "should I take this job?".

One mentee called me "an IT handyman, able to help with a bit of everything." I'll take it. Range is useful to someone whose problem doesn't fit a single box.

Teaching is how I learn

At Treatwell I led a bi-weekly internal DevSecOps Guild — twenty to thirty people each session. I've spoken at PUG Roma and Codemotion. I keep a curated dev learning path on GitHub. Every one of those taught me more than it taught anyone else, because explaining something clearly is where you find the gaps in your own understanding.

Leadership without authority

Maintaining open source with real users is leadership without a reporting line. Nobody has to accept your review. The quality bar holds only through clarity, consistency, and taste. It's the best training I know for leading peers and stakeholders who don't work for you.

The line from 10x Software Engineer I repeat most to mentees: "you do need to make mistakes to become better - just avoid making ALL the possible mistakes." Mentoring, mostly, is helping someone skip the ones you've already made.

You don't need a team to grow people. You need to show up where they're stuck, and say something useful.

What a good session looks like

The mentoring sessions that work best follow a pattern. The mentee brings one concrete problem — a design, a decision, a conversation they're dreading. We spend most of the time on that, not on general advice. When it's technical, we often do it hands-on, which mentees consistently say they value. And it ends with one thing they'll try before next time, which we start the next session by checking. Advice nobody acts on isn't mentoring; it's conversation.

The other half is knowing what you're not. A mentor isn't a manager, can't fix the mentee's organisation, and shouldn't pretend to know a domain they don't. "I don't know, but here's how I'd find out" is one of the more useful things you can say.

If you’re new to leading people and want someone to think out loud with, I mentor engineers and managers on MentorCruise.

Part VI

Traps & the Long Game

The mistakes I made, the ones I nearly made, and the habit that ties everything together.

Chapter 24

The Jack-of-All-Trades Trap

A small company's CTO does everything: strategy, budget, hiring, process, incidents, the odd production fix at midnight. That breadth is real and valuable. It's also a trap, because "I can do all of it" quietly becomes "I'm the only one who does any of it".

I fell into it. The signs, in hindsight:

  • Every decision queued behind me.
  • My calendar was full, and none of it was deep work.
  • I knew a little about everything happening and a lot about nothing.

The way out

The way out wasn't to work harder. It was to put hats down, deliberately, in order:

  1. Put down the hats someone else can wear better. Process, estimation, on-call: give each one an owner.
  2. Turn recurring decisions into written defaults, so they stop needing you.
  3. Keep one deep stem for yourself, on purpose — or, as I did, change seats to get one back.

Breadth is a strength when it connects deep people. It's a weakness when it replaces them.

Which hats to put down first

A rough order, from my own experience — yours will differ
HatWhy it goes earlyWho it goes to
Process and ceremoniesRepeats weekly, easy to describeA tech lead or a rotating facilitator
Estimation and planningBenefits from a consistent method more than a senior voiceA delivery-minded engineer
On-call and incidentsNeeds a rota, not a heroThe team, with runbooks
Day-to-day technical callsBottleneck risk is highest hereProject owners, within guardrails
Budget and strategyUsually stays with you — but write the defaults downYou, with a deputy who's seen it

The order matters less than the habit: every quarter, pick one hat and find it a better head. The time you get back is what lets you go deep somewhere again.

Chapter 25

The Ceremony Trap

When I went back over fourteen of my repositories from 2012 to 2023, one rule explained my wildly different levels of formality: ceremony should track audience and risk — never effort.

A solo prototype gets an empty README. The same engineer's hobby app that reads your contacts gets a carefully explained permission flow. Personal websites get a disaster recovery plan. It looks inconsistent. It isn't: formality goes where readers or dangers exist, and stays away where they don't.

Pick the register before you pick the process
RegisterKeepDrop
PrototypeClear names, honest TODOsDocs, CI, ceremony
Ship (small app)Error tracking from line one, a one-command releaseExhaustive tests, public docs
Founder / opsRunbooks, secrets tooling, licence diligenceMarketing polish
Team / communityThe house style — theirs, not yoursYour personal conventions
Open source with usersEverything: tests, CI matrix, docs, release policyNothing
Ceremony follows audience and risk A chart with audience on the horizontal axis and risk on the vertical axis. Prototype sits low and left. Ship mode sits low with a small audience. Founder and ops mode sits high-risk with a small audience. Team and community sits with a larger audience and medium risk. Open source with users sits top right. audience — who will read or run it → risk — what breaks if it's wrong → more ceremonyless ceremony Prototype Ship (small app) Founder / ops Team / community Open source with users
Ceremony should rise toward the top-right — never because something took a lot of effort

Both directions are traps

Too much ceremony on something small, and it never ships. Too little on something risky, and it ships a liability. Startups tend toward the first error with their infrastructure and the second with their data. Big companies often do the reverse.

Ask first

Who will read this, and what breaks if it's wrong? Spend process where the answer is "many people" or "something important". Nowhere else.

Chapter 26

The Shiny Tool Trap

Platform engineering has a tool for everything, and a new one every week. It's easy to mistake adopting tools for building a platform.

I like tools. I keep a long list of ones I believe in. But each one I've brought into a team came with a specific problem attached: Terraform because state was unmanaged, Backstage because ownership was unknown, Bedrock because teams needed governed access to models.

A filter for new tools

  1. What problem, measured how? If you can't name the metric it moves, it's a hobby.
  2. Who will own it in a year? Every tool is an on-call rota, an upgrade path, and a security surface.
  3. What does it replace? If the answer is "nothing", you're adding complexity, not removing it.
  4. One at a time. One new thing per project — the same rule from Chapter 3.

Decommissioning is part of adoption

The test of a tool decision isn't the launch. It's whether you can remove the tool later without a crisis. Before adopting anything, write down how you'd get off it: what data it holds, what depends on it, what the replacement would be. That one paragraph changes the decision more often than any feature comparison, and it's the cheapest insurance against the next shiny thing replacing this one.

AI makes this trap deeper

In 2026 it became trivially cheap to start things. My own year shows it: around 37 new repositories. I've tried to be honest about what that costs. Every repository is maintenance, a dependency update stream, and a promise to users. Shipping a shared skeleton across about 30 of them — CI, security policy, pinned actions, docs — was how I made that number survivable, not how I justified it.

Whenever I've published a reading list or a roadmap, I've put the same warning at the top: it's "not a bible nor a reference manual" — don't follow any suggestion "blindly without understanding the reasons behind" it. The same applies to every tool and every framework in this guide.

Starting is cheap now. Maintaining isn't. Choose what you're willing to keep alive.

Chapter 27

Proof Over Claims

If one principle holds across everything I've built, it's this: quality is shown by machines and artefacts, never asserted in prose.

  • A README shows the real --help output and a real run, not a description of them.
  • "No race conditions" is a claim only if CI runs the race detector on every build.
  • Coverage is exported to an external grader, not kept as a private number.
  • A cost saving is a before-and-after from the bill, not a slide.

Honesty is a strategy

The other half of proof is publishing weaknesses. My caching proxy's tagline says "(semi) production-ready". Known limitations go in the docs next to the feature. Unfinished items stay visible as unchecked boxes.

That isn't modesty. It's credibility. People trust the claims of someone who tells them where the edges are. This guide's evidence note follows the same rule.

Credibility is built by hedging in public. Never claim more than your tooling can prove.

Write the limits into the format

When I wrote whitepapers for my tools — forty-four of them, one per problem — I made honesty structural rather than optional. Every paper follows the same template, and some of its rules:

  • The title names the problem, never the tool.
  • Name the existing alternative and state the gap factually. If the honest answer is "the existing tool is fine and this one is narrower", say that.
  • Every design decision costs something; a section that lists only benefits is marketing.
  • Console output is real, or explicitly labelled illustrative.
  • Every paper ends with Limits and non-goals: what it deliberately does not do.

Some of my favourite sentences in the series are the limits: "The euro figure is a model, not a measurement." "It restores; it does not fail over." "It explains movement; it does not explain cause." Each one makes the rest of the paper more believable.

The problemNot the tool
The gapNamed fairly
ApproachWith its costs
Use casesTwo to four, concrete
EvidenceHow every number is made
LimitsWhat it won't do
The core of the whitepaper template — honesty as a required section

It works on agents too

Proof over claims turned out to be the right posture for AI work. An agent will happily say it's done. A green pipeline, a passing gate, and a diff you've read are what tell you it actually is.

Chapter 28

The Learning Loop

We've covered a lot: metrics, cost, carbon, disasters, platforms, agents, promotions, exits. Nobody masters all of it, and you don't need to. What you need is the loop that every chapter has been describing: measure, optimise, automate, repeat — applied to yourself as well as your systems.

Measure yourself, gently

For years I wrote a public past year review — 2019, 2020, 2021, 2022. Not for an audience: for me. What did I set out to do? What happened? What will I change? It's the personal version of a retrospective: the same loop, pointed at yourself.

Today I keep a written document of two possible paths for the next decade, and I review it yearly:

Two paths, reviewed every year
Management trackIndividual contributor track
DirectionDirector of Platform → VP → CTO at scalePrincipal → Distinguished → independent authority on sustainable platforms
Optimises forOrganisational scaleLeverage, depth, autonomy
Biggest gapManaging managersInternational visibility
Reversible?Harder to swing back to deep ICBack to leadership stays open — done it once

I haven't "decided". That's the point. I've written down what each path needs, so every year I can check which way my evidence and energy are pointing — and swing the pendulum on purpose rather than by accident.

Keep learning, on purpose

NoviceSkipped — needs basics first
Advanced beginnerTroubleshooting, still hasty
CompetentSolves and plans on their own
ProficientSees the bigger picture; learns from others' mistakes too
Expert, the fifth level, is skipped too: competent in many areas is realistic; expert in all of them isn't.
The levels used in 10x Software Engineer (definitions after the Dreyfus model)

I started programming at fifteen and I've never stopped spending spare time on new methodologies and technologies, because, as I wrote in the introduction to 10x Software Engineer, "especially in this field, who hesitates is lost." That book's advice still holds for me: start from the lowest level even when you're experienced, because you never know what you'll find; rate what you read, so future-you can skip straight to what mattered; and learn from people with different roles, backgrounds and styles.

Every bug becomes instinct

My talk How to Survive the Day, given internally at Skuola.net in 2019, organised habits for being stuck into three levels. Foundations: reproduce the bug before changing code, doubt your assumptions, take a step back, beware of yak shaving, read the manual, take notes. Smart moves: keep the main branch working, push and pull every day, keep safety nets like logging, monitoring and profiling, take breaks. And only then the last resort: ask for help — a rubber duck, a colleague, the community. The underlying idea is that getting stuck is fine; staying stuck is the problem. Every hard day, written down, becomes a pattern you'll recognise in seconds next time.

What AI changes, and what it doesn't

AI has made parts of my loop dramatically shorter. Prototypes, scaffolding, documentation and tooling that took weeks can take days. That's real, and I use it every day.

What it hasn't changed: knowing what's worth measuring. Deciding which saving is worth the risk. Telling someone the truth in a 1:1. Choosing who to grow into your seat. Those are still the job — and in a world of cheaper code, they're a bigger share of it than ever.

A closing reflection

I started in 2005, one person doing every job for small companies in Rome. Twenty years later I lead a platform team, mentor engineers I'll never manage, and direct agents I'll never fully trust. In between I was a CTO, then wasn't, on purpose.

If there's one thing I'd tell the version of me starting out, it's that growth isn't a ladder. It's a loop. Measure where you are. Change one thing. Make the gain stick. Look again.

You can't fix what you can't see. Start by looking. Then go from code to org, and back again, as many times as it takes.

— Fabio Cicerchia, Rome, 2026

I revise this guide when something changes my mind; this version is from October 2026. If you disagree with something in it, or want to know when it changes, write to me at [email protected] or follow along on LinkedIn.

Source notes

Where things come from

Numbers and roles come from my own career record. Frameworks and external claims are linked to their primary sources, which may have changed since October 2026 — prefer the current versions.

Back to contents

↑