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.
A note on evidence. This is a field guide, not a promise of outcomes. Every number in it comes from a role I held, and it is labelled with where it happened. Those numbers describe one context, at one scale, at one time — treat them as stories, not benchmarks. Frameworks I didn't invent (DORA, SPACE, the CNCF maturity model) are linked to their sources at the end. Where I'm offering opinion, I say so.
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.
Building
Leading
2005Freelance developer
2008Populis / Excite
2010Lead developer, DNSEE
2012London: FusePump, IOVOX
2015Founder, Kodebeat
2016CTO, Skuola.net
2020Engineer, Radical
2022Platform Engineer, Treatwell
2022+EM → Head of Platform
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
Stem
When
What forced it
Backend / web
2005 →
Freelancing: if it broke, it was mine
Testing & quality
London
Teams with no tests and no coverage
Infrastructure
Skuola.net
80+ servers and nobody else to own them
Cloud & DevOps
Radical
CI that took too long and bills that grew too fast
Platform & people
Treatwell
Many teams, one shared foundation
GreenOps
2025 →
Cost and carbon turned out to be the same lever
Supply chain & AI infra
2026
Shipping 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.
Backend2005
TestingLondon
InfraSkuola
CloudRadical
Platform & peopleTreatwell
GreenOps2025
Supply chain & AI2026
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 with
Then
An engineer taking on infra, cost or reliability
Parts II–IV
Chapter 27, then Part I
A new tech lead or manager
Part V
Chapters 2, 6 and 21
A small-company CTO wearing every hat
Chapters 24 and 25
Part V, then Chapter 9
Running a platform team
Chapters 8, 15 and 6
Part 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:
What does this cost? In money, in time, in incidents, in carbon.
Where does work get stuck? Between which stages, waiting on whom?
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.
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:
Measure what matters, while it matters. A metric that answered last year's question is noise this year. Retire it.
Focus on the goal, not the metric. The moment a number becomes the target, people optimise the number.
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.
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
Lens
What it measures
What it misses
DORA
Deployment frequency, lead time for changes, change failure rate, time to restore
Why work is slow; how people feel about it
SPACE signals
Cycle time, review-to-merge time, CI/CD coverage, WIP limits, tech-debt age, infra incident rate
Whether the work being done is the right work
CSAT surveys
Developer satisfaction with the platform and its tools
Anything 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.
What a range looks like — illustrative shape, not real data
How to run one, by hand
Take your team's weekly throughput for the last ten to twenty weeks — items finished per week, nothing fancier.
Count the items left in the piece of work. Split anything huge; don't size anything.
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.
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
Dimension
Asks
Investment
How are people and money allocated to the platform?
Adoption
Why and how do teams discover and use it?
Interfaces
How do people interact with it — tickets, docs, self-service, APIs?
Operations
How is it planned, run, and maintained?
Measurement
How 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.
ProvisionalProv.
OperationalOper.
ScalableScal.
OptimisingOpt.
Investment
Adoption
Interfaces
Operations
Measurement
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.
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.
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.
Secure the database — real backups, tested restores
Secure the storage — off-site copies of everything that isn't code
Redundancy of the database — replication across providers
Redundancy of storage
Redundancy of web servers — more than one place to serve from
Redundancy of DNS — the single point of failure everyone forgets
Billing impact — what this actually costs per month
Manual configurations — hunting down everything that isn't in code
Disaster recovery plan — written down, with a threat taxonomy
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
Stage
What's in it
Annual cost
Before
One DigitalOcean VPS at $5/month
$60
Fully redundant
The 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 trimming
Shorter backup retention, no static mirror, DigitalOcean replaced with a second Hetzner VPS in another region, and DNS fallback dropped for non-critical sites
$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
Exposure
Handling
Private throwaway prototype
Acceptable shortcuts — never in anything with readers
Anything shared
.env.dist templates, real values outside the repo
Infrastructure in git
Encrypted at rest: Ansible Vault, SOPS with age
Platform services
A 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
For two weeks, ask the team to note every repetitive manual task. Duration and frequency, nothing more.
Multiply. Sort. The top three are usually obvious and usually smaller than people expect.
Automate one. Tell everyone the hours it saved. Then do the next.
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
Section
Contains
Example
Project
Identity and the product thesis
"The rule set is the product."
Commands
The make verbs
make dev / lint / test / build
Conventions
How work is shaped
Conventional Commits drive the release; never hand-edit the changelog
Guardrails
What's off-limits
Prefer 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:
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.
Host— your machine, your credentials
offline— no network unless you allow it
azkaban— one project directory, nothing else
Coding agent— does the work, can't reach past the fences
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
Cadence
What happens
Weekly
1:1 with a running agenda
Quarterly
Check-in against the framework: where you are, what's next
Yearly
Formal review, then calibration with peer managers
Yearly
Salary review within the defined ranges
When ready
Promotion 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.
WeeklyQuarterlyYearly
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 decides
I stay accountable for
How the work is broken down
Why the work matters, and its priority
Technical approach, within guardrails
The guardrails themselves
Day-to-day trade-offs
Outcomes, and what we tell stakeholders
When to ask for help
Being 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
Name it. Tell the person you see them as a possible successor for parts of your role. Ambiguity wastes a year.
Give away a real responsibility, not a task: a recurring meeting, a budget line, a stakeholder.
Let them be seen. Bring them to the meetings where decisions are made, then let them speak.
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:
Put down the hats someone else can wear better. Process, estimation, on-call: give each one an owner.
Turn recurring decisions into written defaults, so they stop needing you.
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
Hat
Why it goes early
Who it goes to
Process and ceremonies
Repeats weekly, easy to describe
A tech lead or a rotating facilitator
Estimation and planning
Benefits from a consistent method more than a senior voice
A delivery-minded engineer
On-call and incidents
Needs a rota, not a hero
The team, with runbooks
Day-to-day technical calls
Bottleneck risk is highest here
Project owners, within guardrails
Budget and strategy
Usually stays with you — but write the defaults down
You, 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
Register
Keep
Drop
Prototype
Clear names, honest TODOs
Docs, CI, ceremony
Ship (small app)
Error tracking from line one, a one-command release
Exhaustive tests, public docs
Founder / ops
Runbooks, secrets tooling, licence diligence
Marketing polish
Team / community
The house style — theirs, not yours
Your personal conventions
Open source with users
Everything: tests, CI matrix, docs, release policy
Nothing
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
What problem, measured how? If you can't name the metric it moves, it's a hobby.
Who will own it in a year? Every tool is an on-call rota, an upgrade path, and a security surface.
What does it replace? If the answer is "nothing", you're adding complexity, not removing it.
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 track
Individual contributor track
Direction
Director of Platform → VP → CTO at scale
Principal → Distinguished → independent authority on sustainable platforms
Optimises for
Organisational scale
Leverage, depth, autonomy
Biggest gap
Managing managers
International visibility
Reversible?
Harder to swing back to deep IC
Back 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.
My books: GreenOps & GreenCoding (2025, free to read online, CC BY-NC-SA 4.0) and 10x Software Engineer (2019–2021, a week-by-week learning path). The tool whitepapers quoted in Chapters 9–17 and 27 cover publicly available tools only.