<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet href="/feed.css?v=208f42b55cff" type="text/css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:site="https://lalitm.com/feed/ns#"><title>Lalit Maganti (Atom, Tag: Software-Engineering)</title><subtitle>Recent content tagged Software-Engineering on Lalit Maganti</subtitle><site:notice>This is a feed.
Feeds let you subscribe to updates from this site using a feed reader. Copy this page's URL from your address bar and paste it into your reader.
New to feeds? Read: https://aboutfeeds.com</site:notice><link href="https://lalitm.com/tags/software-engineering/atom.xml" rel="self" type="application/atom+xml"/><link href="https://lalitm.com/" rel="alternate" type="text/html"/><link href="https://aboutfeeds.com" rel="help" type="text/html"/><id>https://lalitm.com/tags/software-engineering/</id><updated>2026-07-17T05:47:11Z</updated><author><name>Lalit Maganti</name></author><generator>Hugo -- gohugo.io</generator><entry><title>Don't answer the first question</title><link href="https://lalitm.com/post/dont-answer-the-first-question/" rel="alternate" type="text/html"/><id>https://lalitm.com/post/dont-answer-the-first-question/</id><published>2026-05-16T14:19:00+01:00</published><updated>2026-05-16T14:19:00+01:00</updated><summary type="text">In my work on Perfetto, a performance debugging tool, one question I get often is: “how do I split a Perfetto trace into multiple files?” Instead of answering directly, I say: “there isn’t an easy way to do that, but what’s leading you to collect traces large enough to want to split?”
This is one of my golden rules at work. When a user asks me something “weird”: don’t answer the first version of the question.
On the surface this might appear like I’m talking about the XY problem, but that stops one step short. It treats the user’s stated question as a puzzle to decode: figure out what they really meant, answer that, move on. I think we can go much further.
Instead, the confusion that produced the wrong question is itself an opening, and the conversation it sparks is valuable to both sides. The user walks away with a better mental model of the tool. I walk away with a clearer picture of where the product confuses people. And sometimes, between us, we figure out that the product itself needs to change.</summary><content type="html">&lt;p&gt;In my work on Perfetto, a performance debugging tool, one question I get often
is: “how do I split a Perfetto trace into multiple files?” Instead of answering
directly, I say: “there isn’t an easy way to do that, but what’s leading you to
collect traces large enough to want to split?”&lt;/p&gt;
&lt;p&gt;This is one of my golden rules at work. When a user asks me something &amp;ldquo;weird&amp;rdquo;:
&lt;em&gt;don&amp;rsquo;t answer the first version of the question&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;On the surface this might appear like I&amp;rsquo;m talking about the
&lt;a href="https://en.wikipedia.org/wiki/XY_problem"&gt;XY problem&lt;/a&gt;, but that stops one step
short. It treats the user&amp;rsquo;s stated question as a puzzle to decode: figure out
what they really meant, answer that, move on. I think we can go much further.&lt;/p&gt;
&lt;p&gt;Instead, the confusion that produced the wrong question is itself an opening,
and the conversation it sparks is valuable to both sides. The user walks away
with a better mental model of the tool. I walk away with a clearer picture of
where the product confuses people. And sometimes, between us, we figure out that
the product itself needs to change.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve written before about how I can still be a successful engineer while
&lt;a href="https://lalitm.com/software-engineering-outside-the-spotlight/"&gt;avoiding the spotlight&lt;/a&gt;.
While that covered the general strategy, this is one of the concrete tactics
that makes it work. I should also say this post is aimed at people who build
things for other engineers. If you&amp;rsquo;re building a consumer product, or a B2B
service, it will translate less directly, but the underlying instinct might
still be useful.&lt;/p&gt;
&lt;h2 id="diagnosing-the-ask"&gt;Diagnosing the ask&lt;/h2&gt;
&lt;p&gt;Some questions are easy, routine, and purely a matter of pointing at
documentation; those don&amp;rsquo;t merit much discussion here. The interesting cases are
where something is out of the ordinary, and it&amp;rsquo;s rare that the user will have
given me enough information in their first ask&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;So I run a mental checklist to figure out where to go next:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Have I seen this before? If so, I might already have an answer to hand. If
not, it&amp;rsquo;s uncommon enough that I want to slow down.&lt;/li&gt;
&lt;li&gt;Does the question even sound reasonable compared to others I&amp;rsquo;ve seen? If not,
why might they be asking it, and is there a more normal question underneath?&lt;/li&gt;
&lt;li&gt;Does it fit the shape of the tool? Or is the user fighting the architecture
without realizing it?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once I&amp;rsquo;ve figured out what feels off, the next step is asking something that
will surface the missing context. I might say something like &amp;ldquo;well the answer to
your immediate question is X but that&amp;rsquo;s a pretty strange thing to ask for
because of reason Y. Can you tell me more about the wider problem you&amp;rsquo;re trying
to solve?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;This will probably be the start of a back and forth. How quickly it moves
depends on how well the user can communicate their thoughts. But we&amp;rsquo;ll usually
end up in one of a few places: they&amp;rsquo;re missing the philosophy of the tool, the
product is hiding the right path or the product itself needs to change.&lt;/p&gt;
&lt;h2 id="when-theyre-missing-the-philosophy"&gt;When they&amp;rsquo;re missing the philosophy&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s quite common for users to come to us not knowing what they want, or not
understanding the problem they&amp;rsquo;re trying to solve.&lt;/p&gt;
&lt;p&gt;To be clear, I&amp;rsquo;m not criticizing them for this; teams are often trying to solve
problems with limited time or resources, and they turn to new debugging tools
when they&amp;rsquo;re struggling to make progress. As a result, they often find the tool,
find it does most of what they want but doesn&amp;rsquo;t match their model of &amp;ldquo;how it
should work&amp;rdquo;. So they file a feature request.&lt;/p&gt;
&lt;p&gt;A common version of this: people come to Perfetto, see that a trace is a highly
detailed recording of what a device did over a window of time, realize you can
compute metrics from a Perfetto trace, and treat it as a holy grail solution to
all their problems. Want a frame rate? Count frames in the trace. Memory used by
an app? Look at the allocations and frees. In principle, any metric &lt;em&gt;could&lt;/em&gt; be
computed from a trace.&lt;/p&gt;
&lt;p&gt;But this is a bad idea for a simple reason: traces are expensive to collect and
process: you&amp;rsquo;re collecting all the data about the system rather than samply a
single number. You&amp;rsquo;re going to waste a lot of resources when instead, a
dedicated metric collection system would do the job much more
efficiently&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;My overarching point is that there&amp;rsquo;s a certain philosophy to how tools are
designed, and users often miss it because they&amp;rsquo;re focused on their immediate
problem.&lt;/p&gt;
&lt;p&gt;A big part of my job is teaching the team how to approach performance
engineering in the first place, not just explaining how to use Perfetto. It
means making people aware of the tools they have available, how to think about
things like startup, frame drops, memory, and power, and how to work with them
both in normal situations and when something goes wrong.&lt;/p&gt;
&lt;h2 id="when-the-right-path-is-hidden"&gt;When the right path is hidden&lt;/h2&gt;
&lt;p&gt;Other times the team understands the problem; they just don&amp;rsquo;t see how to put
existing tools together. Our tools are powerful by design, and we have to be
mindful that other teams might not understand the full range of what we&amp;rsquo;ve
built. It&amp;rsquo;s my job to figure out what they actually want. Often, something we
built for a different purpose can be repurposed to meet their needs.&lt;/p&gt;
&lt;p&gt;A perfect example here is what I already discussed: trace splitting. The
conversation goes something like, &amp;ldquo;&amp;hellip;what’s leading you to collect traces large
enough to want to split?&amp;rdquo; They say it&amp;rsquo;s because they have periods of interest in
a long trace and want to slice it up. Partly for performance, partly to make
visualizing easier.&lt;/p&gt;
&lt;p&gt;But then I point out that Perfetto already supports
&lt;a href="https://perfetto.dev/docs/getting-started/periodic-trace-snapshots"&gt;periodic trace snapshots&lt;/a&gt;,
short repeated recordings instead of one long one, which removes the need to
collect a long trace at all. They&amp;rsquo;re trying to solve a problem they shouldn&amp;rsquo;t be
having in the first place.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s always satisfying to see people say &amp;ldquo;that&amp;rsquo;s exactly what I needed!&amp;rdquo; even
though it&amp;rsquo;s not what they asked for. It means I successfully figured out what
they actually wanted rather than what they thought they did.&lt;/p&gt;
&lt;h2 id="when-the-product-needs-to-change"&gt;When the product needs to change&lt;/h2&gt;
&lt;p&gt;Occasionally, the response reveals something genuinely new, something that could
set us on the path to building something big. These cases are tricky: even when
the ask is novel, the asker often can&amp;rsquo;t tell you what they actually need.&lt;/p&gt;
&lt;p&gt;The cost of getting things wrong in foundational software is high, so I err on
the side of not building something until not having it hurts: multiple teams
have come to me saying &amp;ldquo;we want this.&amp;rdquo; Ideally by then we&amp;rsquo;ve found the essence
of what&amp;rsquo;s actually worth building. This is very unlikely to happen after just
one ask, so waiting is really powerful.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve made this mistake at Perfetto. Take ad-hoc UI customization. People wanted
to hack on the UI to suit their workflows, and they kept complaining about how
hard that was. So we let them, and immediately took on a huge amount of
technical debt. Every new feature had to interact with every existing one, and
the whole thing quickly became impossible to scale.&lt;/p&gt;
&lt;p&gt;It took us roughly one year to dig ourselves out of this hole by designing a
proper plugin API. The real need, which no one could articulate up front, was a
way to &lt;em&gt;personalize&lt;/em&gt; the UI to the needs of their team or use case without
affecting every other user. But of course no one was able to name this until it
was too late. So it was our responsibility to spot this early as the requests
flowed in.&lt;/p&gt;
&lt;p&gt;Allowing folks to &amp;ldquo;merge&amp;rdquo; Perfetto traces was one we got right. People asked
about it constantly, but we held off. We pointed people at workarounds and said
&amp;ldquo;we&amp;rsquo;ll see.&amp;rdquo; We knew doing it properly was a lot of work and easy to get wrong,
so we waited. We finally built it last year in a maintainable way, but only
because we understood the problem space so well in the first place.&lt;/p&gt;
&lt;h2 id="the-point"&gt;The point&lt;/h2&gt;
&lt;p&gt;The first version of a question is rarely the real one. Ask why before you
answer. Sometimes the answer teaches the user how the tool is meant to be used.
Sometimes it tells you the product is hiding the right path. Sometimes it tells
you there&amp;rsquo;s nothing worth building yet. And sometimes it sets you up to build
the next big thing once, not twice.&lt;/p&gt;
&lt;p&gt;The technique is simple, but easy to skip because the pull to be responsive is
constant, and every quick answer feels productive. Take the small step back
anyway. Both sides almost always walk away with more than they came in with.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;It&amp;rsquo;s always a pleasant surprise when that does happen!&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Computing metrics from traces works fine for local development and most lab
tests. It breaks down when you need fine-grained measurement with low noise,
or when you&amp;rsquo;re collecting in the field on real users&amp;rsquo; devices.&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content></entry><entry><title>Eight years of wanting, three months of building with AI</title><link href="https://lalitm.com/post/building-syntaqlite-ai/" rel="alternate" type="text/html"/><id>https://lalitm.com/post/building-syntaqlite-ai/</id><published>2026-04-05T13:00:00+01:00</published><updated>2026-04-05T13:00:00+01:00</updated><summary type="text">For eight years, I’ve wanted a high-quality set of devtools for working with SQLite. Given how important SQLite is to the industry1, I’ve long been puzzled that no one has invested in building a really good developer experience for it2.
A couple of weeks ago, after ~250 hours of effort over three months3 on evenings, weekends, and vacation days, I finally released syntaqlite (GitHub), fulfilling this long-held wish. And I believe the main reason this happened was because of AI coding agents4.
Of course, there’s no shortage of posts claiming that AI one-shot their project or pushing back and declaring that AI is all slop. I’m going to take a very different approach and, instead, systematically break down my experience building syntaqlite with AI, both where it helped and where it was detrimental.
I’ll do this while contextualizing the project and my background so you can independently assess how generalizable this experience was. And whenever I make a claim, I’ll try to back it up with evidence from my project journal, coding transcripts, or commit history5.</summary><content type="html">&lt;p&gt;For eight years, I&amp;rsquo;ve wanted a high-quality set of devtools for working with
SQLite. Given how important SQLite is to the industry&lt;sup class="sn-ref" id="sn-ref-sqlite-industry"&gt;&lt;a href="#sn-sqlite-industry"&gt;1&lt;/a&gt;&lt;/sup&gt;, I&amp;rsquo;ve long been puzzled that no one has invested in building
a really good developer experience for it&lt;sup class="sn-ref" id="sn-ref-devtools"&gt;&lt;a href="#sn-devtools"&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;A couple of weeks ago, after ~250 hours of effort over three months&lt;sup class="sn-ref" id="sn-ref-hours"&gt;&lt;a href="#sn-hours"&gt;3&lt;/a&gt;&lt;/sup&gt; on evenings, weekends, and vacation days, I finally
&lt;a href="/post/syntaqlite/"&gt;released syntaqlite&lt;/a&gt;
(&lt;a href="https://github.com/LalitMaganti/syntaqlite"&gt;GitHub&lt;/a&gt;), fulfilling this
long-held wish. And I believe the main reason this happened was because of AI
coding agents&lt;sup class="sn-ref" id="sn-ref-codingtools"&gt;&lt;a href="#sn-codingtools"&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Of course, there&amp;rsquo;s no shortage of posts claiming that AI one-shot their project
or pushing back and declaring that AI is all slop. I&amp;rsquo;m going to take a very
different approach and, instead, systematically break down my experience
building syntaqlite with AI, both where it helped &lt;em&gt;and&lt;/em&gt; where it was
detrimental.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll do this while contextualizing the project and my background so you can
independently assess how generalizable this experience was. And whenever I make
a claim, I&amp;rsquo;ll try to back it up with evidence from my project journal, coding
transcripts, or commit history&lt;sup class="sn-ref" id="sn-ref-evidence"&gt;&lt;a href="#sn-evidence"&gt;5&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h2 id="why-i-wanted-it"&gt;Why I wanted it&lt;/h2&gt;
&lt;p&gt;In my work on &lt;a href="https://docs.perfetto.dev"&gt;Perfetto&lt;/a&gt;, I maintain a SQLite-based
language for querying performance traces called
&lt;a href="https://perfetto.dev/docs/analysis/perfetto-sql-getting-started"&gt;PerfettoSQL&lt;/a&gt;.
It&amp;rsquo;s basically the same as SQLite but with a few extensions to make the trace
querying experience better. There are ~100K lines of PerfettoSQL internally in
Google and it&amp;rsquo;s used by a wide range of teams.&lt;/p&gt;
&lt;p&gt;Having a language which gets traction means your users also start expecting
things like formatters, linters, and editor extensions. I&amp;rsquo;d hoped that we could
adapt some SQLite tools from open source but the more I looked into it, the more
disappointed I was. What I found either wasn&amp;rsquo;t reliable enough, fast
enough&lt;sup class="sn-ref" id="sn-ref-speed-comparison"&gt;&lt;a href="#sn-speed-comparison"&gt;6&lt;/a&gt;&lt;/sup&gt;, or flexible enough to adapt to PerfettoSQL. There was
clearly an opportunity to build something from scratch, but it was never the
&amp;ldquo;most important thing we could work on&amp;rdquo;. We&amp;rsquo;ve been reluctantly making do with
the tools out there but always wishing for better.&lt;/p&gt;
&lt;p&gt;On the other hand, there &lt;em&gt;was&lt;/em&gt; the option to do something in my spare time. I
had built lots of open source projects in my teens&lt;sup class="sn-ref" id="sn-ref-holoirc"&gt;&lt;a href="#sn-holoirc"&gt;7&lt;/a&gt;&lt;/sup&gt; but this
had faded away during university when I felt that I just didn&amp;rsquo;t have the
motivation anymore. Being a maintainer is much more than just &amp;ldquo;throwing the code
out there&amp;rdquo; and seeing what happens. It&amp;rsquo;s triaging bugs, investigating crashes,
writing documentation, building a community, and, most importantly, having a
direction for the project.&lt;/p&gt;
&lt;p&gt;But the itch of open source (specifically freedom to work on what I wanted while
helping others) had never gone away. The SQLite devtools project was eternally
in my mind as &amp;ldquo;something I&amp;rsquo;d like to work on&amp;rdquo;. But there was another reason why
I kept putting it off: it sits at the intersection of being both hard &lt;em&gt;and&lt;/em&gt;
tedious.&lt;/p&gt;
&lt;h2 id="what-makes-it-hard-and-tedious"&gt;What makes it hard and tedious&lt;/h2&gt;
&lt;p&gt;If I was going to invest my personal time working on this project, I didn&amp;rsquo;t want
to build something that only helped Perfetto: I wanted to make it work for &lt;em&gt;any&lt;/em&gt;
SQLite user out there&lt;sup class="sn-ref" id="sn-ref-ambition"&gt;&lt;a href="#sn-ambition"&gt;8&lt;/a&gt;&lt;/sup&gt;. And this means parsing SQL &lt;em&gt;exactly&lt;/em&gt;
like SQLite.&lt;/p&gt;
&lt;p&gt;The heart of any language-oriented devtool is the parser. This is responsible
for turning the source code into a &amp;ldquo;parse tree&amp;rdquo; which acts as the central data
structure anything else is built on top of. If your parser isn&amp;rsquo;t accurate, then
your formatters and linters will inevitably inherit those inaccuracies; many of
the tools I found suffered from having parsers which approximated the SQLite
language rather than representing it precisely.&lt;/p&gt;
&lt;p&gt;Unfortunately, unlike many other languages, SQLite has no formal specification
describing how it should be parsed. It doesn&amp;rsquo;t expose a stable API for its
parser either. In fact, quite uniquely, in its implementation it doesn&amp;rsquo;t even
build a parse tree at all&lt;sup class="sn-ref" id="sn-ref-no-parse-tree"&gt;&lt;a href="#sn-no-parse-tree"&gt;9&lt;/a&gt;&lt;/sup&gt;! The only reasonable approach
left in my opinion is to carefully extract the relevant parts of SQLite&amp;rsquo;s source
code and adapt it to build the parser I wanted&lt;sup class="sn-ref" id="sn-ref-extraction"&gt;&lt;a href="#sn-extraction"&gt;10&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;This means getting into the weeds of SQLite source code, a fiendishly difficult
codebase to understand. The whole project is written in C in an
&lt;a href="https://sqlite.org/src/file?name=src/vdbe.c&amp;amp;ci=trunk"&gt;incredibly dense style&lt;/a&gt;;
I&amp;rsquo;ve spent days just understanding the virtual table
&lt;a href="https://www.sqlite.org/vtab.html"&gt;API&lt;/a&gt;&lt;sup class="sn-ref" id="sn-ref-vtab-nuance"&gt;&lt;a href="#sn-vtab-nuance"&gt;11&lt;/a&gt;&lt;/sup&gt; and
&lt;a href="https://sqlite.org/src/file?name=src/vtab.c&amp;amp;ci=trunk"&gt;implementation&lt;/a&gt;. Trying
to grasp the full parser stack was daunting.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s also the fact that there are &amp;gt;400 rules in SQLite which capture the full
surface area of its language. I&amp;rsquo;d have to specify in each of these &amp;ldquo;grammar
rules&amp;rdquo; how that part of the syntax maps to the matching node in the parse tree.
It&amp;rsquo;s extremely repetitive work; each rule is similar to all the ones around it
but also, by definition, different.&lt;/p&gt;
&lt;p&gt;And it&amp;rsquo;s not just the rules but also coming up with and writing tests to make
sure it&amp;rsquo;s correct, debugging if something is wrong, triaging and fixing the
inevitable bugs people filed when I got something wrong&amp;hellip;&lt;/p&gt;
&lt;p&gt;For years, this was where the idea died. Too hard for a side project&lt;sup class="sn-ref" id="sn-ref-complexity"&gt;&lt;a href="#sn-complexity"&gt;12&lt;/a&gt;&lt;/sup&gt;, too tedious to sustain motivation, too risky to invest months
into something that might not work.&lt;/p&gt;
&lt;h2 id="how-it-happened"&gt;How it happened&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been using coding agents since early 2025 (Aider, Roo Code, then Claude
Code since July) and they&amp;rsquo;d definitely been useful but never something I felt I
could trust a serious project to. But towards the end of 2025, the models seemed
to make a significant step forward in quality&lt;sup class="sn-ref" id="sn-ref-agents-got-good"&gt;&lt;a href="#sn-agents-got-good"&gt;13&lt;/a&gt;&lt;/sup&gt;. At the
same time, I kept hitting problems in Perfetto which would have been trivially
solved by having a reliable parser. Each workaround left the same thought in the
back of my mind: maybe it&amp;rsquo;s finally time to build it for real.&lt;/p&gt;
&lt;p&gt;I got some space to think and reflect over Christmas and decided to really
stress test the most maximalist version of AI: could I vibe-code the whole thing
using just Claude Code on the Max plan (£200/month)?&lt;/p&gt;
&lt;p&gt;Through most of January, I iterated, acting as semi-technical manager and
delegating almost all the design and all the implementation to Claude.
Functionally, I ended up in a reasonable place: a parser in C extracted from
SQLite sources using a bunch of Python scripts, a formatter built on top,
support for both the SQLite language and the PerfettoSQL extensions, all exposed
in a web playground.&lt;/p&gt;
&lt;p&gt;But when I reviewed the codebase in detail in late January, the downside was
obvious: the codebase was complete spaghetti&lt;sup class="sn-ref" id="sn-ref-spaghetti"&gt;&lt;a href="#sn-spaghetti"&gt;14&lt;/a&gt;&lt;/sup&gt;. I didn&amp;rsquo;t
understand large parts of the Python source extraction pipeline, functions were
scattered in random files without a clear shape, and a few files had grown to
several thousand lines. It was &lt;em&gt;extremely&lt;/em&gt; fragile; it solved the immediate
problem &lt;em&gt;but&lt;/em&gt; it was never going to cope with my larger vision, never mind
integrating it into the Perfetto tools. The saving grace was that it had proved
the approach was viable and generated more than 500 tests, many of which I felt
I could reuse.&lt;/p&gt;
&lt;p&gt;I decided to throw away everything and start from scratch while also switching
most of the codebase to Rust&lt;sup class="sn-ref" id="sn-ref-rust-not-c"&gt;&lt;a href="#sn-rust-not-c"&gt;15&lt;/a&gt;&lt;/sup&gt;. I could see that C was going
to make it difficult to build the higher level components like the validator and
the language server implementation. And as a bonus, it would also let me use the
same language for both the extraction and runtime instead of splitting it across
C and Python.&lt;/p&gt;
&lt;p&gt;More importantly, I completely changed my role in the project. I took ownership
of all decisions&lt;sup class="sn-ref" id="sn-ref-took-control"&gt;&lt;a href="#sn-took-control"&gt;16&lt;/a&gt;&lt;/sup&gt; and used it more as &amp;ldquo;autocomplete on
steroids&amp;rdquo; inside a much tighter process: opinionated design upfront, reviewing
every change thoroughly, fixing problems eagerly as I spotted them, and
investing in scaffolding (like linting, validation, and non-trivial
testing&lt;sup class="sn-ref" id="sn-ref-scaffolding"&gt;&lt;a href="#sn-scaffolding"&gt;17&lt;/a&gt;&lt;/sup&gt;) to check AI output automatically.&lt;/p&gt;
&lt;p&gt;The core features came together through February and the final stretch (upstream
test validation, editor extensions, packaging, docs) led to a 0.1 launch in
mid-March.&lt;/p&gt;
&lt;p&gt;But in my opinion, this timeline is the least interesting part of this story.
What I really want to talk about is what wouldn&amp;rsquo;t have happened without AI and
also the toll it took on me as I used it.&lt;/p&gt;
&lt;h2 id="ai-is-why-this-project-exists-and-why-its-as-complete-as-it-is"&gt;AI is why this project exists, and why it&amp;rsquo;s as complete as it is&lt;/h2&gt;
&lt;h3 id="overcoming-inertia"&gt;Overcoming inertia&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve &lt;a href="https://lalitm.com/llm-motivation-via-emotions/"&gt;written in the past&lt;/a&gt;
about how one of my biggest weaknesses as a software engineer is my tendency to
procrastinate when facing a big new project. Though I didn&amp;rsquo;t realize it at the
time, it could not have applied more perfectly to building syntaqlite.&lt;/p&gt;
&lt;p&gt;AI basically let me put aside all my doubts on technical calls, my uncertainty
of building the right thing and my reluctance to get started by giving me very
concrete problems to work on. Instead of &amp;ldquo;I need to understand how SQLite&amp;rsquo;s
parsing works&amp;rdquo;, it was &amp;ldquo;I need to get AI to suggest an approach for me so I can
tear it up and build something better&amp;quot;&lt;sup class="sn-ref" id="sn-ref-inertia-journal"&gt;&lt;a href="#sn-inertia-journal"&gt;18&lt;/a&gt;&lt;/sup&gt;. I work so much
better with concrete prototypes to play with and code to look at than endlessly
thinking about designs in my head, and AI lets me get to that point at a pace I
could not have dreamed about before. Once I took the first step, every step
after that was so much easier.&lt;/p&gt;
&lt;h3 id="faster-at-churning-code"&gt;Faster at churning code&lt;/h3&gt;
&lt;p&gt;AI turned out to be better than me at the act of writing code itself, assuming
that code is obvious. If I can break a problem down to &amp;ldquo;write a function with
this behaviour and parameters&amp;rdquo; or &amp;ldquo;write a class matching this interface,&amp;rdquo; AI
will build it faster than I would and, crucially, in a style that might well be
more intuitive to a future reader. It documents things I&amp;rsquo;d skip, lays out code
consistently with the rest of the project, and sticks to what you might call the
&amp;ldquo;standard dialect&amp;rdquo; of whatever language you&amp;rsquo;re working
in&lt;sup class="sn-ref" id="sn-ref-standard-dialect"&gt;&lt;a href="#sn-standard-dialect"&gt;19&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;That standardness is a double-edged sword. For the vast majority of code in any
project, standard is exactly what you want: predictable, readable, unsurprising.
But every project has pieces that are its edge, the parts where the value comes
from doing something non-obvious. For syntaqlite, that was the extraction
pipeline and the parser architecture. AI&amp;rsquo;s instinct to normalize was actively
harmful there, and those were the parts I had to design in depth and often
resorted to just writing myself.&lt;/p&gt;
&lt;p&gt;But here&amp;rsquo;s the flip side: the same speed that makes AI great at obvious code
also makes it great at refactoring. If you&amp;rsquo;re using AI to generate code at
industrial scale, you &lt;em&gt;have&lt;/em&gt; to refactor constantly and
continuously&lt;sup class="sn-ref" id="sn-ref-refactoring-journal"&gt;&lt;a href="#sn-refactoring-journal"&gt;20&lt;/a&gt;&lt;/sup&gt;. If you don&amp;rsquo;t, things immediately get
out of hand. This was the central lesson of the vibe-coding month: I didn&amp;rsquo;t
refactor enough, the codebase became something I couldn&amp;rsquo;t reason about, and I
had to throw it all away. In the rewrite, refactoring became the core of my
workflow. After every large batch of generated code, I&amp;rsquo;d step back and ask &amp;ldquo;is
this ugly?&amp;rdquo; Sometimes AI could clean it up. Other times there was a large-scale
abstraction that AI couldn&amp;rsquo;t see but I could; I&amp;rsquo;d give it the direction and let
it execute&lt;sup class="sn-ref" id="sn-ref-refactor-pattern"&gt;&lt;a href="#sn-refactor-pattern"&gt;21&lt;/a&gt;&lt;/sup&gt;. If you have taste, the cost of a wrong
approach drops dramatically because you can restructure
quickly&lt;sup class="sn-ref" id="sn-ref-refactor-taste"&gt;&lt;a href="#sn-refactor-taste"&gt;22&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h3 id="teaching-assistant"&gt;Teaching assistant&lt;/h3&gt;
&lt;p&gt;Of all the ways I used AI, research had by far the highest ratio of value
delivered to time spent.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve worked with interpreters and parsers before but I had never heard of
Wadler-Lindig pretty printing&lt;sup class="sn-ref" id="sn-ref-wadler-lindig"&gt;&lt;a href="#sn-wadler-lindig"&gt;23&lt;/a&gt;&lt;/sup&gt;. When I needed to build
the formatter, AI gave me a concrete and actionable lesson from a point of view
I could understand and pointed me to the papers to learn more. I could have
found this myself eventually, but AI compressed what might have been a day or
two of reading into a focused conversation where I could ask &amp;ldquo;but why does this
work?&amp;rdquo; until I actually got it.&lt;/p&gt;
&lt;p&gt;This extended to entire domains I&amp;rsquo;d never worked in. I have deep C++ and Android
performance expertise but had barely touched Rust tooling or editor extension
APIs. With AI, it wasn&amp;rsquo;t a problem: the fundamentals are the same, the
terminology is similar, and AI bridges the gap&lt;sup class="sn-ref" id="sn-ref-lateral-moves"&gt;&lt;a href="#sn-lateral-moves"&gt;24&lt;/a&gt;&lt;/sup&gt;. The VS
Code extension would have taken me a day or two of learning the API before I
could even start. With AI, I had a working extension within an hour.&lt;/p&gt;
&lt;p&gt;It was also invaluable for reacquainting myself with parts of the project I
hadn&amp;rsquo;t looked at for a few days&lt;sup class="sn-ref" id="sn-ref-context-reacquisition"&gt;&lt;a href="#sn-context-reacquisition"&gt;25&lt;/a&gt;&lt;/sup&gt;. I could control
how deep to go: &amp;ldquo;tell me about this component&amp;rdquo; for a surface-level refresher,
&amp;ldquo;give me a detailed linear walkthrough&amp;rdquo; for a deeper dive, &amp;ldquo;audit unsafe usages
in this repo&amp;rdquo; to go hunting for problems. When you&amp;rsquo;re context switching a lot,
you lose context fast. AI let me reacquire it on demand.&lt;/p&gt;
&lt;h3 id="more-than-id-have-built-alone"&gt;More than I&amp;rsquo;d have built alone&lt;/h3&gt;
&lt;p&gt;Beyond making the project exist at all, AI is also the reason it shipped as
complete as it did. Every open source project has a long tail of features that
are important but not critical: the things you know theoretically how to do but
keep deprioritizing because the core work is more pressing. For syntaqlite, that
list was long: editor extensions, Python bindings, a WASM playground, a docs
site, packaging for multiple ecosystems&lt;sup class="sn-ref" id="sn-ref-last-mile-list"&gt;&lt;a href="#sn-last-mile-list"&gt;26&lt;/a&gt;&lt;/sup&gt;. AI made these
cheap enough that skipping them felt like the wrong trade-off.&lt;/p&gt;
&lt;p&gt;It also freed up mental energy for UX&lt;sup class="sn-ref" id="sn-ref-ux-focus"&gt;&lt;a href="#sn-ux-focus"&gt;27&lt;/a&gt;&lt;/sup&gt;. Instead of spending
all my time on implementation, I could think about what a user&amp;rsquo;s first
experience should feel like: what error messages would actually help them fix
their SQL, how the formatter output should look by default, whether the CLI
flags were intuitive. These are the things that separate a tool people try once
from one they keep using, and AI gave me the headroom to care about them.
Without AI, I would have built something much smaller, probably no editor
extensions or docs site. AI didn&amp;rsquo;t just make the same project faster. It changed
what the project &lt;em&gt;was&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id="where-ai-had-its-costs"&gt;Where AI had its costs&lt;/h2&gt;
&lt;h3 id="the-addiction"&gt;The addiction&lt;/h3&gt;
&lt;p&gt;There&amp;rsquo;s an uncomfortable parallel between using AI coding tools and playing slot
machines&lt;sup class="sn-ref" id="sn-ref-addiction"&gt;&lt;a href="#sn-addiction"&gt;28&lt;/a&gt;&lt;/sup&gt;. You send a prompt, wait, and either get something
great or something useless. I found myself up late at night wanting to do &amp;ldquo;just
one more prompt,&amp;rdquo; constantly trying AI just to see what would happen even when I
knew it probably wouldn&amp;rsquo;t work. The sunk cost fallacy kicked in too: I&amp;rsquo;d keep at
it even in tasks it was clearly ill-suited for, telling myself &amp;ldquo;maybe if I
phrase it differently this time.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The tiredness feedback loop made it worse&lt;sup class="sn-ref" id="sn-ref-tiredness-loop"&gt;&lt;a href="#sn-tiredness-loop"&gt;29&lt;/a&gt;&lt;/sup&gt;. When I had
energy, I could write precise, well-scoped prompts and be genuinely productive.
But when I was tired, my prompts became vague, the output got worse, and I&amp;rsquo;d try
again, getting more tired in the process. In these cases, AI was probably slower
than just implementing something myself, but it was too hard to break out of the
loop&lt;sup class="sn-ref" id="sn-ref-ai-slower"&gt;&lt;a href="#sn-ai-slower"&gt;30&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h3 id="losing-touch"&gt;Losing touch&lt;/h3&gt;
&lt;p&gt;Several times during the project, I lost my mental model of the
codebase&lt;sup class="sn-ref" id="sn-ref-losing-touch"&gt;&lt;a href="#sn-losing-touch"&gt;31&lt;/a&gt;&lt;/sup&gt;. Not the overall architecture or how things
fitted together. But the day-to-day details of what lived where, which functions
called which, the small decisions that accumulate into a working system. When
that happened, surprising issues would appear and I&amp;rsquo;d find myself at a total
loss to understand what was going wrong. I hated that feeling.&lt;/p&gt;
&lt;p&gt;The deeper problem was that losing touch created a communication
breakdown&lt;sup class="sn-ref" id="sn-ref-communication-breakdown"&gt;&lt;a href="#sn-communication-breakdown"&gt;32&lt;/a&gt;&lt;/sup&gt;. When you don&amp;rsquo;t have the mental
thread of what&amp;rsquo;s going on, it becomes impossible to communicate meaningfully
with the agent. Every exchange gets longer and more verbose. Instead of &amp;ldquo;change
FooClass to do X,&amp;rdquo; you end up saying &amp;ldquo;change the thing which does Bar to do X&amp;rdquo;.
Then the agent has to figure out what Bar is, how that maps to FooClass, and
sometimes it gets it wrong&lt;sup class="sn-ref" id="sn-ref-manager-analogy"&gt;&lt;a href="#sn-manager-analogy"&gt;33&lt;/a&gt;&lt;/sup&gt;. It&amp;rsquo;s exactly the same
complaint engineers have always had about managers who don&amp;rsquo;t understand the code
asking for fanciful or impossible things. Except now you&amp;rsquo;ve become that manager.&lt;/p&gt;
&lt;p&gt;The fix was deliberate: I made it a habit to read through the code immediately
after it was implemented and actively engage to see &amp;ldquo;how would I have done this
differently?&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Of course, in some sense all of the above is also true of code I wrote a few
months ago (hence the
&lt;a href="https://text-incubation.com/AI+code+is+legacy+code+from+day+one"&gt;sentiment that AI code is legacy code&lt;/a&gt;),
but AI makes the drift happen faster because you&amp;rsquo;re not building the same muscle
memory that comes from originally typing it out.&lt;/p&gt;
&lt;h3 id="the-slow-corrosion"&gt;The slow corrosion&lt;/h3&gt;
&lt;p&gt;There were some other problems I only discovered incrementally over the three
months.&lt;/p&gt;
&lt;p&gt;I found that AI made me procrastinate on key design
decisions&lt;sup class="sn-ref" id="sn-ref-procrastination"&gt;&lt;a href="#sn-procrastination"&gt;34&lt;/a&gt;&lt;/sup&gt;. Because refactoring was cheap, I could
always say &amp;ldquo;I&amp;rsquo;ll deal with this later.&amp;rdquo; And because AI could refactor at the
same industrial scale it generated code, the cost of deferring felt low. But it
wasn&amp;rsquo;t: deferring decisions corroded my ability to think clearly because the
codebase stayed confusing in the meantime. The vibe-coding month was the most
extreme version of this. Yes, I understood the problem, but if I had been more
disciplined about making hard design calls earlier, I could have converged on
the right architecture much faster.&lt;/p&gt;
&lt;p&gt;Tests created a similar false comfort&lt;sup class="sn-ref" id="sn-ref-tests-insufficient"&gt;&lt;a href="#sn-tests-insufficient"&gt;35&lt;/a&gt;&lt;/sup&gt;. Having 500+
tests felt reassuring, and AI made it easy to generate more. But neither humans
nor AI are creative enough to foresee every edge case you&amp;rsquo;ll hit in the future;
there are several times in the vibe-coding phase where I&amp;rsquo;d come up with a test
case and realise the design of some component was completely wrong and needed to
be totally reworked. This was a significant contributor to my lack of trust and
the decision to scrap everything and start from scratch.&lt;/p&gt;
&lt;p&gt;Basically, I learned that the &amp;ldquo;normal rules&amp;rdquo; of software still apply in the AI
age: if you don&amp;rsquo;t have a fundamental foundation (clear architecture,
well-defined boundaries) you&amp;rsquo;ll be left eternally chasing bugs as they appear.&lt;/p&gt;
&lt;h3 id="no-sense-of-time"&gt;No sense of time&lt;/h3&gt;
&lt;p&gt;Something I kept coming back to was how little AI understood about the passage
of time&lt;sup class="sn-ref" id="sn-ref-no-sense-of-time"&gt;&lt;a href="#sn-no-sense-of-time"&gt;36&lt;/a&gt;&lt;/sup&gt;. It sees a codebase in a certain state but
doesn&amp;rsquo;t &lt;em&gt;feel&lt;/em&gt; time the way humans do. I can tell you what it feels like to use
an API, how it evolved over months or years, why certain decisions were made and
later reversed.&lt;/p&gt;
&lt;p&gt;The natural problem from this lack of understanding is that you either make the
same mistakes you made in the past and have to relearn the lessons &lt;em&gt;or&lt;/em&gt; you fall
into new traps which were successfully avoided the first time, slowing you down
in the long run. In my opinion, this is a similar problem to why losing a
high-quality senior engineer hurts a team so much: they carry history and
context that doesn&amp;rsquo;t exist anywhere else and act as a guide for others around
them.&lt;/p&gt;
&lt;p&gt;In theory, you can try to preserve this context by keeping specs and docs up to
date. But there&amp;rsquo;s a reason we didn&amp;rsquo;t do this before AI: capturing implicit
design decisions exhaustively is incredibly expensive and time-consuming to
write down. AI can help draft these docs, but because there&amp;rsquo;s no way to
automatically verify that it accurately captured what matters, a human still has
to manually audit the result. And that&amp;rsquo;s still time-consuming.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s also the context pollution problem. You never know when a design note
about API A will echo in API B. Consistency is a huge part of what makes
codebases work, and for that you don&amp;rsquo;t just need context about what you&amp;rsquo;re
working on right now but also about other things which were designed in a
similar way. Deciding what&amp;rsquo;s relevant requires exactly the kind of judgement
that institutional knowledge provides in the first place.&lt;/p&gt;
&lt;h2 id="relativity"&gt;Relativity&lt;/h2&gt;
&lt;p&gt;Reflecting on the above, the pattern of when AI helped and when it hurt was
fairly consistent.&lt;/p&gt;
&lt;p&gt;When I was working on something I already understood deeply, AI was excellent. I
could review its output instantly, catch mistakes before they landed and move at
a pace I&amp;rsquo;d never have managed alone. The parser rule generation is the clearest
example&lt;sup class="sn-ref" id="sn-ref-parser-rules"&gt;&lt;a href="#sn-parser-rules"&gt;37&lt;/a&gt;&lt;/sup&gt;: I knew exactly what each rule should produce, so
I could review AI&amp;rsquo;s output within a minute or two and iterate fast.&lt;/p&gt;
&lt;p&gt;When I was working on something I could describe but didn&amp;rsquo;t yet know, AI was
good but required more care. Learning Wadler-Lindig for the formatter was like
this: I could articulate what I wanted, evaluate whether the output was heading
in the right direction, and learn from what AI explained. But I had to stay
engaged and couldn&amp;rsquo;t just accept what it gave me.&lt;/p&gt;
&lt;p&gt;When I was working on something where I didn&amp;rsquo;t even know what I wanted, AI was
somewhere between unhelpful and harmful. The architecture of the project was the
clearest case: I spent weeks in the early days following AI down dead ends,
exploring designs that felt productive in the moment but collapsed under
scrutiny. In hindsight, I have to wonder if it would have been faster just
thinking it through without AI in the loop at all.&lt;/p&gt;
&lt;p&gt;But expertise alone isn&amp;rsquo;t enough. Even when I understood a problem deeply, AI
still struggled if the task had no objectively checkable answer&lt;sup class="sn-ref" id="sn-ref-verifiability"&gt;&lt;a href="#sn-verifiability"&gt;38&lt;/a&gt;&lt;/sup&gt;. Implementation has a right answer, at least at a local level:
the code compiles, the tests pass, the output matches what you asked for. Design
doesn&amp;rsquo;t. We&amp;rsquo;re still arguing about OOP decades after it first took off.&lt;/p&gt;
&lt;p&gt;Concretely, I found that designing the public API of syntaqlite was where this
hit home the hardest. I spent several days in early March doing nothing but API
refactoring, manually fixing things any experienced engineer would have
instinctively avoided but AI made a total mess of. There&amp;rsquo;s no test or objective
metric for &amp;ldquo;is this API pleasant to use&amp;rdquo; and &amp;ldquo;will this API help users solve
the problems they have&amp;rdquo; and that&amp;rsquo;s exactly why the coding agents did &lt;em&gt;so badly&lt;/em&gt;
at it.&lt;/p&gt;
&lt;p&gt;This takes me back to the days I was obsessed with physics and, specifically,
relativity. The laws of physics look simple and Newtonian in any small local
area, but zoom out and spacetime curves in ways you can&amp;rsquo;t predict from the local
picture alone. Code is the same: at the level of a function or a class, there&amp;rsquo;s
usually a clear right answer, and AI is excellent there. But architecture is
what happens when all those local pieces interact, and you can&amp;rsquo;t get good global
behaviour by stitching together locally correct components.&lt;/p&gt;
&lt;p&gt;Knowing where you are on these axes at any given moment is, I think, the core
skill of working with AI effectively.&lt;/p&gt;
&lt;h2 id="wrap-up"&gt;Wrap-up&lt;/h2&gt;
&lt;p&gt;Eight years is a long time to carry a project in your head. Seeing these SQLite
tools actually exist and function after only three months of work is a massive
win, and I’m fully aware they wouldn&amp;rsquo;t be here without AI.&lt;/p&gt;
&lt;p&gt;But the process wasn&amp;rsquo;t the clean, linear success story people usually post. I
lost an entire month to vibe-coding. I fell into the trap of managing a codebase
I didn&amp;rsquo;t actually understand, and I paid for that with a total rewrite.&lt;/p&gt;
&lt;p&gt;The takeaway for me is simple: AI is an incredible force multiplier for
implementation, but it’s a dangerous substitute for design. It’s brilliant at
giving you the right answer to a specific technical question, but it has no
sense of history, taste, or how a human will actually feel using your API. If
you rely on it for the &amp;ldquo;soul&amp;rdquo; of your software, you’ll just end up hitting a
wall faster than you ever have before.&lt;/p&gt;
&lt;p&gt;What I&amp;rsquo;d like to see more of from others is exactly what I&amp;rsquo;ve tried to do here:
honest, detailed accounts of building real software with these tools; not
weekend toys or one-off scripts but the kind of software that has to survive
contact with users, bug reports, and your own changing mind.&lt;/p&gt;</content></entry><entry><title>Why Senior Engineers Let Bad Projects Fail</title><link href="https://lalitm.com/post/why-senior-engineers-let-bad-projects-fail/" rel="alternate" type="text/html"/><id>https://lalitm.com/post/why-senior-engineers-let-bad-projects-fail/</id><published>2026-01-13T10:48:00Z</published><updated>2026-01-13T10:48:00Z</updated><summary type="text">When I was a junior engineer, my manager would occasionally confide his frustrations to me in our weekly 1:1s. He would point out a project another team was working on and say, “I don’t believe that project will go anywhere, they’re solving the wrong problem.” I used to wonder, “But you are very senior, why don’t you just go and speak to them about your concerns?” It felt like a waste of his influence to not say anything.
So it’s quite ironic that I found myself last week explaining to a mentee why I thought a sister team’s project would have to pivot because they’d made a poor early design choice. And he rightfully asked me the same question I had years ago: “why don’t you just tell them your opinion?” It’s been on my mind ever since because I realized I’d changed my stance on it a lot over the years.</summary><content type="html">&lt;p&gt;When I was a junior engineer, my manager would occasionally confide his frustrations to me in our weekly 1:1s. He would point out a project another team was working on and say, &amp;ldquo;I don&amp;rsquo;t believe that project will go anywhere, they&amp;rsquo;re solving the wrong problem.&amp;rdquo; I used to wonder, &amp;ldquo;But you are very senior, why don&amp;rsquo;t you just go and speak to them about your concerns?&amp;rdquo; It felt like a waste of his influence to not say anything.&lt;/p&gt;
&lt;p&gt;So it&amp;rsquo;s quite ironic that I found myself last week explaining to a mentee why I thought a sister team&amp;rsquo;s project would have to pivot because they&amp;rsquo;d made a poor early design choice. And he rightfully asked me the same question I had years ago: &amp;ldquo;why don&amp;rsquo;t you just tell them your opinion?&amp;rdquo; It’s been on my mind ever since because I realized I’d changed my stance on it a lot over the years.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The answer is that being right and being effective are different.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In large companies, speaking up about what you see as a &amp;ldquo;bad project&amp;rdquo; is a good thing. But only in moderation. Sometimes the mark of seniority is realizing that arguing with people who won’t listen isn’t worth it; it’s better to save your counsel.&lt;/p&gt;
&lt;h2 id="bad-projects"&gt;Bad projects&lt;/h2&gt;
&lt;p&gt;What I mean by a &amp;ldquo;bad project&amp;rdquo; is many things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;UX&lt;/strong&gt;: making product complicated, solving a problem which doesn&amp;rsquo;t exist, breaking existing workflows&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Technical&lt;/strong&gt;: overcomplicated design, wrong library, poor performing architecture&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Political&lt;/strong&gt;: chasing hype cycles, exists primarily to justify a promotion&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&amp;rsquo;s important to point out that for much of the lifecycle of a project, whether it&amp;rsquo;s &amp;ldquo;bad&amp;rdquo; is &lt;em&gt;highly&lt;/em&gt; subjective. Software engineering is largely a game of tradeoffs and making decisions which are not perfect but the best possible with the information available. There often can be disagreements on whether correct choices are made and it only becomes obvious much later on, potentially years after a project has shipped.&lt;/p&gt;
&lt;p&gt;But as you become more senior, you&amp;rsquo;ll start to have &amp;ldquo;taste&amp;rdquo; when it comes to software projects and that will cause you to look at some fraction of the software projects and feel &amp;ldquo;this doesn&amp;rsquo;t make sense&amp;rdquo;. And this gut feeling is the sign to me of a &amp;ldquo;bad project&amp;rdquo;, one which you can see in advance of when it&amp;rsquo;s obvious to everyone.&lt;/p&gt;
&lt;p&gt;Drawing on my personal experience, the most memorable example was a few years ago at Google . There was a high-profile announcement internally of a &amp;ldquo;game changer&amp;rdquo; project that sat right at the intersection of two extremely large organizations. It was technically amazing and elegant, and full of clever ideas for really hard problems.&lt;/p&gt;
&lt;p&gt;But I distinctly remember sitting in the room for the announcement, turning to my lead and whispering, &amp;ldquo;This project has no chance of succeeding, right?&amp;rdquo; He turned to me and just said, &amp;ldquo;Yup.&amp;rdquo; We both realized the problem immediately. The project was entirely based on a platform team asking a flagship product team to give up control of their core user flow: technically the right move, but no lead or PM would ever cede ownership of something that central to another team. Politically, this project was a total fantasy.&lt;/p&gt;
&lt;p&gt;The project kept quietly chugging away in the background for almost two years. Every time it got close to launch, it would get pushed back as &amp;ldquo;not ready yet.&amp;rdquo; Over time, we heard less and less about it until, eventually, the inevitable &amp;ldquo;strategic pivot&amp;rdquo; email appeared in my inbox. Resources were reallocated and the code was deleted. We were told the company &amp;ldquo;learned a lot from the effort,&amp;rdquo; but to me it felt like it was doomed from the beginning. Politics and solving the correct problem matter just as much as technical beauty.&lt;/p&gt;
&lt;h2 id="why-you-cannot-stop-them-all"&gt;Why you cannot stop them all&lt;/h2&gt;
&lt;p&gt;When I started noticing &amp;ldquo;bad projects&amp;rdquo; and I felt that I had some expertise to share, the temptation for me was to start calling them out. Reach out to the team doing it, tell them &amp;ldquo;this doesn&amp;rsquo;t make sense&amp;rdquo; and explain to them why. Use facts and logic to persuade.&lt;/p&gt;
&lt;p&gt;And I did do this. But only for a very short time before I realized that there are a lot of costs to doing this that I just wasn&amp;rsquo;t thinking about.&lt;/p&gt;
&lt;p&gt;Firstly, software companies have an inherent bias for action. They value speed and shipping highly. Concerns, by definition, &lt;em&gt;slow things down&lt;/em&gt; and mean people have to look at things which they hadn&amp;rsquo;t budgeted for. And so unless your concern is big enough to overcome the &amp;ldquo;push for landing&amp;rdquo;, there&amp;rsquo;s little chance for any meaningful change to come from you saying something. In fact, it&amp;rsquo;s very likely that you&amp;rsquo;ll be largely ignored.&lt;/p&gt;
&lt;p&gt;Related to this, even if the team &lt;em&gt;does&lt;/em&gt; take your concern seriously, you have to be careful not to do it too often. Once or twice, you might be seen as someone who is upholding &amp;ldquo;quality&amp;rdquo;. But do it too often and you quickly move to being seen as a &amp;ldquo;negative person&amp;rdquo;, someone who is constantly a problem maker, not a problem &amp;ldquo;fixer&amp;rdquo;. You rarely get credit for the disasters you prevented. Because nothing happened, people forget about it quickly.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s also the problem that every time you push back, you are potentially harming someone’s promotion packet or a VP’s &amp;ldquo;pet project.&amp;rdquo; You are at risk of burning bridges and creating &amp;ldquo;enemies&amp;rdquo;, at least of a sort. Having a few people who disagree in a big company with you is the cost of doing business, but if you have too many, it starts affecting your main work too.&lt;/p&gt;
&lt;p&gt;Finally, there is also the psychological impact. There is one of you and hundreds of engineers working in spaces that your expertise might help with. Your attention is finite, but the capacity for a large company to generate bad ideas is infinite. Speaking from experience, getting too involved in stopping these quickly can make you &lt;em&gt;very&lt;/em&gt; cynical about the state of the world. And this is really not a good place to be.&lt;/p&gt;
&lt;h2 id="manage-influence-like-a-bank-account"&gt;Manage influence like a bank account&lt;/h2&gt;
&lt;p&gt;So if you cannot stop all the bad projects, what do you do? You get strategic. Instead of trying to fix everything, view your influence as a bank account. You have a certain amount of &amp;ldquo;influence&amp;rdquo; coming in every month as you do your job, help people, ship successful projects, and generally remain low friction.&lt;/p&gt;
&lt;p&gt;Then, when it matters, you should be ready to make &amp;ldquo;withdrawals.&amp;rdquo; Every time you block something or raise concerns, no matter how small, you are writing a check against your balance. But not all checks are the same size:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The $5 Check:&lt;/strong&gt; A nitpick on a code review. Cheap, daily expense.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The $500 Check:&lt;/strong&gt; Challenging an architectural decision or pushing back on a timeline. Requires some savings.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The $50,000 Check:&lt;/strong&gt; Trying to kill a VP&amp;rsquo;s pet project. This is a massive spend. You might only afford this once every few years.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The problem comes if you spend $5 on every minor inefficiency you see. If you are constantly saying &amp;ldquo;no&amp;rdquo; to small things, your account will be empty when you need to write the big check to stop a true disaster.&lt;/p&gt;
&lt;p&gt;If you &amp;ldquo;go overdrawn,&amp;rdquo; you enter political bankruptcy. People stop inviting you to meetings, they stop asking for your opinion, they essentially start working around you. Once you are bankrupt, your influence drops to zero and you not only harm your ability to influence things but also start hurting your own ability to get things done.&lt;/p&gt;
&lt;h2 id="when-to-spend-influence"&gt;When to spend influence&lt;/h2&gt;
&lt;p&gt;Given that we&amp;rsquo;ve now accepted that we cannot weigh in on everything, we need to figure out when it &lt;em&gt;does&lt;/em&gt; make sense to do so.&lt;/p&gt;
&lt;p&gt;The most important thing to do first is to be humble and evaluate whether you actually have the expertise to make a judgment. Seniority often brings opinions, but those are not always informed opinions. For example, while I have some frontend experience, I do not feel qualified to give deep advice on it because my knowledge is &amp;ldquo;enough to get by&amp;rdquo; rather than deep expertise that comes from long term ownership. It is easy to lose sight of the fact that high-quality judgments require informed opinions. If you find yourself in this position, see yourself as an opinionated observer and stop there.&lt;/p&gt;
&lt;p&gt;You must also internalize the fact that just because you say something does not make it the truth. You are raising awareness of a point of view, not issuing a decree. So if some team doesn&amp;rsquo;t listen to your concerns and decides to go ahead with what they were doing anyway, then you have to accept that and move on: at the end of the day, you&amp;rsquo;re an engineer, not a CEO with authority over them!&lt;/p&gt;
&lt;p&gt;Given these points, I use three main factors to decide when to speak up:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;How close is the project to my team?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If it goes wrong, how much impact will it have on my team?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If it goes wrong, how big will the problem be for the company?&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Proximity.&lt;/strong&gt; If a project is close to you, the &amp;ldquo;price tag&amp;rdquo; of saying something is lower. If it is within your own team, the cost is near zero because you have high trust and a quick conversation often solves it. If it is in your broader organization, the price goes up; you have to spend social capital and potentially stake your reputation. If it is outside your org? The cost is often prohibitive. You have zero leverage, different reporting chains, and stopping it would require a massive withdrawal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Team Impact.&lt;/strong&gt; Sometimes another org does something that deeply affects your work. For example, because &lt;a href="https://perfetto.dev/"&gt;Perfetto&lt;/a&gt; (the performance tool I work on) has users throughout Google, sometimes a team will ask us to sign off on a very complex integration. This is a classic risk: if things go right, they get the credit, but if things go wrong, your leadership might expect &lt;em&gt;you&lt;/em&gt; to help solve a problem you didn&amp;rsquo;t create. In these cases, the payoff of speaking up is high because you are protecting your team.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Company Scale.&lt;/strong&gt; Finally, consider the blast radius. Some projects are self-contained; if they fail, they only take themselves down. Others are so intertwined with core systems that their failure causes widespread damage or creates technical debt that persists for years. These can be deadly to the long-term health of a project.&lt;/p&gt;
&lt;h2 id="how-to-act-with-bad-projects"&gt;How to act with bad projects&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s also not just about when you put your opinions forward but how you do it. There&amp;rsquo;s a very wide range of actions you can take depending on what you&amp;rsquo;re facing.&lt;/p&gt;
&lt;h3 id="when-you-intervene"&gt;When you intervene&lt;/h3&gt;
&lt;p&gt;The nuclear option is to directly say &amp;ldquo;we should not do this&amp;rdquo; and try to shut the project down. This almost always requires escalation to your leads and the leads of the owning team, requiring great conviction in both the fact that you&amp;rsquo;re right and that this project will be actively harmful. But on some occasions, this is the right thing to do, especially if the cost of not saying something can be existential to your project or team.&lt;/p&gt;
&lt;p&gt;A slightly softer but still quite risky variant of this is, instead of doing a direct escalation, you raise concerns in directly with the team. Usually this is done with a meeting with the team or a strongly worded &amp;ldquo;concern&amp;rdquo; or &amp;ldquo;rebuttal&amp;rdquo; doc. The goal is to speak in strong enough terms that the team themselves conclude that this the project might not be a good idea.&lt;/p&gt;
&lt;p&gt;Then there are the smaller interventions, nudging things in the right direction. These are perfect for when a team is about to do something that makes sense from a high level but they are going about this the wrong way. I see this often with Perfetto: a team sends a design doc proposing a complex use of Perfetto that I know will cause them pain later. I sit down with them, understand their actual problem, and guide them to a better solution. It costs an hour but saves them months. If you do it right, you can even be seen as a helper rather than a hindrance, even if you do slow down the team.&lt;/p&gt;
&lt;h3 id="when-you-dont"&gt;When you don&amp;rsquo;t&lt;/h3&gt;
&lt;p&gt;Sometimes you conclude that the ROI just isn&amp;rsquo;t there to do anything direct: the political momentum is too strong, or the issue is too small to justify spending any influence. At this point, what you do depends on how much your team is involved.&lt;/p&gt;
&lt;p&gt;If it overlaps with your team&amp;rsquo;s work heavily then it might be best to make some subtle contingency plans: reducing your dependency on it or building abstractions to cope if it goes away. There is also a long game trick here. Even a bad project usually has an &amp;ldquo;essence&amp;rdquo; of a good idea, a specific problem it was trying to solve or an insight it was based on. If it fits with your job, it&amp;rsquo;s often a good idea to take that essence and see if you can naturally incorporate a better version of that specific solution into your own project. That way, if the bad project stalls or gets canceled, you can be proactive instead of reactive to the fallout.&lt;/p&gt;
&lt;p&gt;Alternatively, if you&amp;rsquo;re not involved, it&amp;rsquo;s easy: just stay out of the picture. Vent to friendly colleagues in private, commiserate, but in public, live with the reality.&lt;/p&gt;
&lt;h3 id="managing-your-team-through-it"&gt;Managing your team through it&lt;/h3&gt;
&lt;p&gt;Finally, you must manage your own team through the process. If you can see the flaws in a project, other senior engineers probably see them too. Don&amp;rsquo;t try to gaslight them or &amp;ldquo;walk the company line&amp;rdquo; by pretending a bad project is actually good. It destroys trust.&lt;/p&gt;
&lt;p&gt;Instead, be honest about the facts on the ground without going into unnecessary political details. Tell them that you will do the best you can under these constraints.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;So what did I tell my mentee? &amp;ldquo;I&amp;rsquo;ve learned that being right and being effective are different things. I could go tell them my concerns. They probably wouldn&amp;rsquo;t listen. I&amp;rsquo;d burn some goodwill. And in six months, nobody will remember that I called it, they&amp;rsquo;ll just remember I was the guy who tried to block their work&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;When you&amp;rsquo;re earlier in your career, you want to believe that good ideas win on merit, that if you just explain clearly enough, people will see reason. It took me quite some time to accept that big companies don&amp;rsquo;t work that way.&lt;/p&gt;
&lt;p&gt;But this doesn&amp;rsquo;t mean you stop caring. It means you get strategic about when to spend your credibility. Pick the battles where you can actually change the outcome, where your team will be hurt if you stay silent, where the cost of being wrong is low but the cost of the project failing is high.&lt;/p&gt;
&lt;p&gt;And for everything else? You vent to colleagues, you make quiet contingency plans, and you watch. Sometimes you learn something. Sometimes you&amp;rsquo;re wrong and the project actually works. And sometimes you get to feel that grim satisfaction of predicting exactly how things would fall apart.&lt;/p&gt;
&lt;p&gt;None of this is as satisfying as fixing everything. But it works and keeps me sane.&lt;/p&gt;</content></entry><entry><title>Why I Ignore The Spotlight as a Staff Engineer</title><link href="https://lalitm.com/software-engineering-outside-the-spotlight/" rel="alternate" type="text/html"/><id>https://lalitm.com/software-engineering-outside-the-spotlight/</id><published>2025-12-04T00:15:00Z</published><updated>2025-12-04T00:15:00Z</updated><summary type="text">Lately I’ve been reading Sean Goedecke’s essays on being a Staff+ engineer. His work (particularly Software engineering under the spotlight and It’s Not Your Codebase) is razor-sharp and feels painfully familiar to anyone in Big Tech.
On paper, I fit the mold he describes: I’m a Senior Staff engineer at Google. Yet, reading his work left me with a lingering sense of unease. At first, I dismissed this as cynicism. After reflecting, however, I realized the problem wasn’t Sean’s writing but my reading.
Sean isn’t being bleak; he is accurately describing how to deal with a world where engineers are fungible assets and priorities shift quarterly. But my job looks nothing like that and I know deep down that if I tried to operate in that environment or in the way he described I’d burn out within months.
Instead I’ve followed an alternate path, one that optimizes for systems over spotlights, and stewardship over fungibility.</summary><content type="html">&lt;p&gt;Lately I’ve been reading &lt;a href="https://www.seangoedecke.com/"&gt;Sean Goedecke’s&lt;/a&gt; essays on being a Staff+ engineer. His work (particularly &lt;a href="https://www.seangoedecke.com/the-spotlight/"&gt;Software engineering under the spotlight&lt;/a&gt; and &lt;a href="https://www.seangoedecke.com/not-your-codebase/"&gt;It&amp;rsquo;s Not Your Codebase&lt;/a&gt;) is razor-sharp and feels painfully familiar to anyone in Big Tech.&lt;/p&gt;
&lt;p&gt;On paper, I fit the mold he describes: I&amp;rsquo;m a Senior Staff engineer at Google. Yet, reading his work left me with a lingering sense of unease. At first, I dismissed this as cynicism. After reflecting, however, I realized the problem wasn’t Sean’s writing but my reading.&lt;/p&gt;
&lt;p&gt;Sean isn&amp;rsquo;t being bleak; he is accurately describing how to deal with a world where engineers are fungible assets and priorities shift quarterly. But my job looks nothing like that and I know deep down that if I tried to operate in that environment or in the way he described I’d burn out &lt;strong&gt;within months&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Instead I&amp;rsquo;ve followed an alternate path, one that optimizes for &lt;strong&gt;systems over spotlights&lt;/strong&gt;, and &lt;strong&gt;stewardship over fungibility&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id="we-live-in-different-worlds"&gt;We Live in Different Worlds&lt;/h2&gt;
&lt;p&gt;The foundational reason for our diverging paths is that Sean and I operate in entirely different worlds with different laws governing them.&lt;/p&gt;
&lt;p&gt;From &lt;a href="https://www.seangoedecke.com/about"&gt;Sean&amp;rsquo;s resume&lt;/a&gt;, my understanding is that he has primarily worked in &lt;strong&gt;product&lt;/strong&gt; teams &lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; building for external customers. Business goals pivot quarterly, and success is measured by revenue or MAU. Optimizing for the &amp;ldquo;Spotlight&amp;rdquo; makes complete sense in this environment. Product development at big tech scale is a crowded room: VPs, PMs and UX designers all have strong opinions. To succeed, you &lt;em&gt;have&lt;/em&gt; to be agile and ensure you are working specifically on what executives are currently looking at.&lt;/p&gt;
&lt;p&gt;On the other hand, I&amp;rsquo;ve spent my entire career much more behind the scenes: in &lt;strong&gt;developer tools and infra&lt;/strong&gt; teams.&lt;/p&gt;
&lt;p&gt;My team&amp;rsquo;s customers are thousands of engineers in Android, Chrome, and throughout Google &lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;. End users of Google products don&amp;rsquo;t even know we exist; our focus is on making sure developers have the tools to collect product and performance metrics and debug issues using detailed traces.&lt;/p&gt;
&lt;p&gt;In this environment, our relationship with leadership is very different. We&amp;rsquo;re never the &amp;ldquo;hot project everyone wants,&amp;rdquo; so execs are not fighting to work with us. In fact, my team has historically struggled to hire PMs. The PM career ladder at Google incentivizes splashy external launches so we cannot provide good &amp;ldquo;promotion material&amp;rdquo; for them. Also, our feedback comes directly from engineers. Adding a PM in the middle causes a loss in translation, slowing down a tight, high-bandwidth feedback loop.&lt;/p&gt;
&lt;p&gt;All of this together means our team operates &amp;ldquo;bottom-up&amp;rdquo;: instead of execs telling us &amp;ldquo;you should do X&amp;rdquo;, we figure out what we think will have the most impact to our customers and work on building those features and tools. Execs ensure that we&amp;rsquo;re &lt;em&gt;actually&lt;/em&gt; solving these problems by considering our impact on more product facing teams.&lt;/p&gt;
&lt;h2 id="compounding-returns-of-stewardship"&gt;Compounding Returns of Stewardship&lt;/h2&gt;
&lt;p&gt;In the product environments Sean describes, where goals pivot quarterly and features are often experimental, &lt;strong&gt;speed&lt;/strong&gt; is the ultimate currency. You need to ship, iterate, and often move on before the market shifts. But in Infrastructure and Developer Experience, &lt;strong&gt;context&lt;/strong&gt; is the currency.&lt;/p&gt;
&lt;p&gt;Treating engineers as fungible assets destroys context. You might gain fresh eyes, but you lose the implicit knowledge of how systems actually break. Stewardship, staying with a system long-term, unlocks compounding returns that are impossible to achieve on a short rotation.&lt;/p&gt;
&lt;p&gt;The first is efficiency via &lt;strong&gt;pattern matching&lt;/strong&gt;. When you stay in one domain for years, new requests are rarely truly &amp;ldquo;new.&amp;rdquo; I am not just debugging code; I am debugging the intersection of my tools and hundreds of diverse engineering teams. When a new team comes to me with a &amp;ldquo;unique&amp;rdquo; problem, I can often reach back in time: &lt;em&gt;“We tried this approach in 2021 with the Camera team; here is exactly why it failed, and here is the architecture that actually works”.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;But the more powerful return is &lt;strong&gt;systemic innovation&lt;/strong&gt;. If you rotate teams every year, you are limited to solving acute bugs that are visible &lt;em&gt;right now&lt;/em&gt;. Some problems, however, only reveal their shape over long horizons.&lt;/p&gt;
&lt;p&gt;Take &lt;strong&gt;Bigtrace&lt;/strong&gt;, a project I recently led; it was a solution that emerged solely because I stuck around long enough to see the shape of the problem:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Start of 2023 (Observation):&lt;/strong&gt; I began noticing a pattern. Teams across Google were collecting terabytes or even petabytes of performance traces, but they were struggling to process them. Engineers were writing brittle, custom pipelines to parse data, often complaining about how slow and painful it was to iterate on their analysis.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Most of 2023 (Research):&lt;/strong&gt; I didn&amp;rsquo;t jump to build a production system. Instead, I spent the best part of a year prototyping quietly in the background while working on other projects. I gathered feedback from these same engineers who had complained and because I had established long-term relationships, they gave me honest and introspective feedback. I learned what sort of UX, latency and throughput requirements they had and figured out how I could meet them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;End of 2023 to Start of 2024 (Execution):&lt;/strong&gt; We built and launched Bigtrace, a distributed big data query engine for traces. Today, it processes over &lt;strong&gt;2 billion traces a month&lt;/strong&gt; and is a critical part of the daily workflow for 100+ engineers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If I had followed the advice to &amp;ldquo;optimize for fungibility&amp;rdquo; (i.e. if I had switched teams in 2023 to chase a new project) &lt;strong&gt;Bigtrace would not exist.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Instead, I would have left during the research phase and my successor would have seen the same &amp;ldquo;noise&amp;rdquo; of engineers complaining. But without the historical context to recognize a missing puzzle piece, I think they would have struggled to build something like Bigtrace.&lt;/p&gt;
&lt;h2 id="the-power-of-no"&gt;The Power of &amp;ldquo;No&amp;rdquo;&lt;/h2&gt;
&lt;p&gt;One of the most seductive arguments for chasing the &amp;ldquo;Spotlight&amp;rdquo; is that it guarantees resources and executive attention. But that attention is a double-edged sword.&lt;/p&gt;
&lt;p&gt;High-visibility projects are often volatile. They come with shifting executive whims, political maneuvering, and often end up in situations where long-term quality is sacrificed for short-term survival. For some engineers, navigating this chaos is a thrill. For those of us who care about system stability, it feels like a trap.&lt;/p&gt;
&lt;p&gt;The advantage of stewardship is that it generates a different kind of capital: &lt;strong&gt;trust&lt;/strong&gt;. When you have spent years delivering reliable tools, you earn the political capital to say &amp;ldquo;No&amp;rdquo; to the spotlight when it threatens the product.&lt;/p&gt;
&lt;p&gt;Recently, the spotlight has been on AI. Every team is under pressure to incorporate it. We have been asked repeatedly: &lt;em&gt;&amp;ldquo;Why don&amp;rsquo;t you integrate LLMs into Perfetto?&amp;rdquo;&lt;/em&gt; If I were optimizing for visibility, the answer would be obvious: build an LLM wrapper, demo it to leadership, and claim we are &amp;ldquo;AI-first.&amp;rdquo; It would be an easy win for my career.&lt;/p&gt;
&lt;p&gt;But as a steward of the system, I know that one of Perfetto’s core values is &lt;strong&gt;precision&lt;/strong&gt;. When a kernel developer is debugging a race condition, they need exact timestamps, not a hallucination. Users trust that when we tell them &amp;ldquo;X is the problem&amp;rdquo; that it actually &lt;em&gt;is&lt;/em&gt; the problem and they&amp;rsquo;re not going to go chasing their tail for the next week, debugging an issue which doesn&amp;rsquo;t exist.&lt;/p&gt;
&lt;p&gt;But it&amp;rsquo;s important not to take this too far: skepticism shouldn&amp;rsquo;t become obstructionism. With AI, it&amp;rsquo;s not &amp;ldquo;no forever&amp;rdquo; but &amp;ldquo;not until it can be done right&amp;rdquo; &lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;A spotlight-seeking engineer might view this approach as a missed opportunity; I view it as protecting what makes our product great: user trust.&lt;/p&gt;
&lt;h2 id="the-alternate-currency-of-impact"&gt;The Alternate Currency of Impact&lt;/h2&gt;
&lt;p&gt;The most common fear engineers have about leaving the &amp;ldquo;Spotlight&amp;rdquo; is career stagnation. The logic goes: &lt;em&gt;If I’m not launching flashy features at Google I/O, and my work isn&amp;rsquo;t on my VP&amp;rsquo;s top 5 list, how will I ever get promoted to Staff+?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;It is true that you lose the currency of &amp;ldquo;Executive Visibility.&amp;rdquo; But in infrastructure, you gain two alternate currencies that are just as valuable, and potentially more stable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Shadow Hierarchy&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In a product organization, you often need to impress your manager’s manager. In an infrastructure organization, you need to impress &lt;strong&gt;your customers’ managers&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I call this the &lt;strong&gt;Shadow Hierarchy.&lt;/strong&gt; You don&amp;rsquo;t need &lt;em&gt;your&lt;/em&gt; VP to understand the intricacies of your code. You need the Staff+ Engineers in &lt;em&gt;other&lt;/em&gt; critical organizations to &lt;strong&gt;need&lt;/strong&gt; your tools.&lt;/p&gt;
&lt;p&gt;When a Senior Staff Engineer in Pixel tells their VP, &lt;em&gt;&amp;ldquo;We literally cannot debug the next Pixel phone without Perfetto&amp;rdquo;&lt;/em&gt;, that statement carries immense weight. It travels up their reporting chain, crosses over at the Director/VP level, and comes back down to your manager.&lt;/p&gt;
&lt;p&gt;This kind of advocacy is powerful because it is technical, not political. It is hard to fake. When you are a steward of a critical system, your promotion packet is filled with testimonials from the most respected engineers in the company saying, &lt;em&gt;&amp;ldquo;This person&amp;rsquo;s work enabled our success&amp;rdquo;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Utility Ledger&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;While product teams might be poring over daily active users or revenue, we rely on metrics tracking &lt;strong&gt;engineering health&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Utility:&lt;/strong&gt; Every bug fixed using our tools is an engineer finding us useful. It is the purest measure of utility.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Criticality:&lt;/strong&gt; If the Pixel team uses Perfetto to debug a launch-blocking stutter, or Chrome uses it to fix a memory leak, our impact is implicitly tied to their success.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ubiquity:&lt;/strong&gt; Capturing a significant percentage of the engineering population proves you&amp;rsquo;ve created a technical &amp;ldquo;lingua franca&amp;rdquo;. This becomes especially obvious when you see disconnected parts of the company collaborating with each other, using shared Perfetto traces as a &amp;ldquo;reference everyone understands&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scale:&lt;/strong&gt; Ingesting petabytes of data or processing billions of traces proves architectural resilience better than any design doc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When you combine &lt;strong&gt;Criticality&lt;/strong&gt; (VIP teams need this) with &lt;strong&gt;Utility&lt;/strong&gt; (bugs are being fixed), you create a promotion case that is immune to executive reorganizations.&lt;/p&gt;
&lt;h2 id="archetypes-and-agency"&gt;Archetypes and Agency&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Staff Archetypes&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I am far from the first to notice the idea of &amp;ldquo;there are multiple ways to be a staff software engineer&amp;rdquo;. In his book &lt;em&gt;&lt;a href="https://staffeng.com/guides/staff-archetypes/"&gt;Staff Engineer&lt;/a&gt;&lt;/em&gt;, Will Larson categorizes Staff-plus engineers into four distinct archetypes.&lt;/p&gt;
&lt;p&gt;Sean describes the &lt;strong&gt;Solver&lt;/strong&gt; or the &lt;strong&gt;Right Hand&lt;/strong&gt;: engineers who act as agents of executive will, dropping into fires and moving on once the problem is stabilized. I am describing the &lt;strong&gt;Architect&lt;/strong&gt; or the &lt;strong&gt;Tech Lead&lt;/strong&gt;: roles defined by long-term ownership of a specific domain and deep technical context.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The &amp;ldquo;Luck&amp;rdquo; Rebuttal&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I can hear the criticism already: &lt;em&gt;&amp;ldquo;You just got lucky finding your team. Most of us don&amp;rsquo;t have that luxury.&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;There are two caveats to all my advice in this post. First, the strategy I have employed so far requires a company profitable enough to sustain long-term infrastructure. This path generally does not exist in startups or early growth companies; it is optimized for Big Tech.&lt;/p&gt;
&lt;p&gt;Second, luck &lt;em&gt;does&lt;/em&gt; play a role in landing on a good team. It is very hard to accurately evaluate team and company culture from the outside. But while finding the team might have involved luck, staying there for almost a decade was a &lt;strong&gt;choice&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;And, at least in my experience, my team is not particularly special: I can name five other teams in Android alone &lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;. Sure, they might have a director change here or a VP change there, but the core mission and the engineering team remained stable.&lt;/p&gt;
&lt;p&gt;The reason these teams seem rare is not that they don&amp;rsquo;t exist, but that they are often ignored. Because they don&amp;rsquo;t offer the rapid, visible &amp;ldquo;wins&amp;rdquo; of a product launch nor are they working on the &amp;ldquo;shiny cool features&amp;rdquo;, they attract less competition. If you are motivated by &amp;ldquo;shipping to billions of users&amp;rdquo; or seeing your friends and family use something you built, you won&amp;rsquo;t find that satisfaction here. That is the price of admission.&lt;/p&gt;
&lt;p&gt;But if you want to build long-term systems and are willing to trade external validation for deep technical ownership, you just need to look behind the curtain.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The tech industry loves to tell you to move fast. But there is another path. It is a path where leverage comes from depth, patience, and the quiet satisfaction of building the foundation that others stand on.&lt;/p&gt;
&lt;p&gt;You don&amp;rsquo;t have to chase the spotlight to have a meaningful, high-impact career at a big company. Sometimes, the most ambitious thing you can do is stay put, dig in, and build something that lasts. To sit with a problem space for years until you understand it well enough to build a Bigtrace.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;By product team I &lt;em&gt;don&amp;rsquo;t&lt;/em&gt; mean &amp;ldquo;frontend team&amp;rdquo;: even as a backend engineer, you are still working on some part of what is being served directly to end users.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;This is not exhaustive, &lt;a href="https://docs.perfetto.dev"&gt;Perfetto&lt;/a&gt; is open source and we &lt;em&gt;do&lt;/em&gt; also care about external developers but that&amp;rsquo;s &lt;em&gt;not&lt;/em&gt; why we get paid. From the company perspective, time we spent on open source bugs is &amp;ldquo;wasted&amp;rdquo; time but we do it because we believe in the mission of open source. I talked about this more in a recent post, &lt;a href="/perfetto-oss-company-prio/"&gt;On Perfetto, Open Source, and Company Priorities&lt;/a&gt;.&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;For what it&amp;rsquo;s worth, LLMs might not even be the best solution to &amp;ldquo;let&amp;rsquo;s put AI into Perfetto&amp;rdquo;: in my opinion there is lots of value with &amp;ldquo;old school&amp;rdquo; machine learning techniques like neural networks. A lot of trace analysis is just pattern matching. This is something I&amp;rsquo;m hoping to explore more in the coming year!&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;Android Kernel, Android System Health, Android Runtime, Android Camera HAL, Android Bionic&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content></entry></feed>