Phase Two Never Comes (Until It Does)
A support engineer was showing me an internal tool they’d built. Nobody had asked them to make it. It was a small frontend for one of our APIs, which had never had a UI because the original requirements didn’t call for one. They clicked into the account dropdown, and we waited. Thirty seconds. Closer to a minute before the list finally filled in.
That was the first sign that something was significantly wrong.
I’d been on this product for the better part of a decade by then. I started as an engineer, spent a couple of years as the unofficial tech lead while the engineering manager seat sat empty, and eventually became the manager. So I knew exactly where that dropdown got its data. I wrote the API behind it. Most people who write an API like that are long gone by the time it breaks. I was still here.
You Can’t Spell Assumption Without…
The API was a relatively straightforward CRUD service. It stored customer account information, and another app in our system periodically asked it for every active account so it could generate a file. When we built it, we assumed that whoever created an account would clean it up when the customer’s contract ended. That was our understanding from the PM and stakeholders at the time.
It didn’t happen. Years later, what should have been fewer than 500 active accounts had grown to tens of thousands. The endpoint returned all of them, every time, in one enormous JSON payload.
It wasn’t an emergency. Waiting a minute for a dropdown is annoying, not catastrophic. But nothing about it would improve on its own. More accounts would pile up every month, the wait would keep growing, and eventually the tool, and the app generating those files, would become unusable. It was a slow-moving train with a car stuck on the tracks.
Why Does It Hurt If It’s Funny?
As I sat with the support engineer, I didn’t feel especially guilty for being the source of the problem. It was a design choice made years ago. You can only design for what you know at the time and what you believe the future will look like, and there are always edge cases you can’t see. Most of the failure was in the process. The cleanup step lived in people’s assumptions instead of anyone’s workflow.
But I’d be lying if I said nobody saw it coming. It doesn’t take much reasoning to figure out that if you return every active account, and active accounts keep growing, the query keeps growing too. Pagination came up. And the answer from the PM and engineering manager back then was the one every engineer has heard: don’t worry about it, we’ll handle that in phase two.
Phase two almost never arrives. The next big feature ask shows up and the team gets pulled onto it. The next thing you know, a year has passed and phase two hasn’t been on anyone’s mind for months. There’s an old joke that your proof of concept is what ends up in production. Cue the laughter.
How The Tables Have Turned
My reaction to the situation still sticks with me. When I saw that dropdown spin, I didn’t drop everything to fix it. I grouped it with a few related issues under “we’ll address this in phase two.” Other priorities were more pressing, and a minute’s wait wasn’t dire.
In other words, I did exactly what had been done to me. Same sentence, same product, years apart, from the other side of the table.
I say “phase two” to my own engineers now, too, usually when a discussion starts heading down a rabbit hole of what-ifs. At some point you have to choose to ship the thing that meets the spec. That may also mean suboptimal design choices. You can’t build the perfect app and release it a year late.
Being on this side of the tradeoff didn’t make me resent the managers who told me “phase two” back then. They were dealing with the same pressures I deal with now. If anything, it gave me more respect for shipping. But it also taught me that phase two doesn’t arrive on its own schedule. Someone has to bring it into existence.
Phase Two API Two
Many moons later, phase two arrived sideways. While talking through upcoming work with the latest product manager, a feature they wanted to prioritize touched the same app. So instead of pitching a standalone technical-debt fix, we made the case to include the pagination fix as part of the overall feature’s solution. The existing API wouldn’t support what they wanted, so we needed a new version.
We built a second API with pagination baked in, and left the original in place so we wouldn’t break the support engineer’s tool, which depended on the old behavior. Cleaning up the old accounts would have been the most direct fix, but nobody could tell us which ones were still under contract. That’s another issue for another day.
Since v2 went live and the internal tool switched over, I’m pleased to report that it now receives paginated responses and the API responds dramatically faster. The main consumer of the API also benefits from the pagination.
If Only Teams Had A Time Machine
If I could talk to myself, or at least send a Teams message, I would say to push back on the things you can already see coming, even when you’re overloaded.
But don’t do it for everything. Building features nobody needs wastes time you never get back, and it bloats the product. At the same time, skipping something that turns out to be needed has its own cost. People start building workarounds, and you lose value every day it’s missing. If this taught me one deciding factor, it’s this: be wary of any plan that relies on a person manually doing something, with nothing to prompt or motivate them to do it.
Workarounds are a signal I watch for now. The support engineer’s tool wasn’t just a side project. It was proof that the UI we’d been told we didn’t need was, in fact, needed. It took a couple more years before a real UI became a priority (also a tale for another time).
In It For The Long Haul
I only learned this because I stayed. If I’d left after two years, like so many people do, I might have had an inkling of how these decisions would play out. I wouldn’t have felt it.
I think of it like a sculpture combined with a temporal game of Telephone. You start with a block of marble, rough out a shape, and leave. Someone else picks it up, decides what they think it’s supposed to be, and refines it. Then someone else takes over, and so on, four or six people deep. The final piece might meet today’s requirements, but it looks nothing like what the first person imagined, and everyone who sees it wonders why it has these strange, vestigial parts.
Staying long enough to watch your own rough shape get worked over is humbling. Time is the best teacher I’ve had, as long as you actually stop and look back at it.