Photo by Ben Griffiths on Unsplash


This is a short story detailing one of my successful projects, which I hope I’ll never need to repeat.

I happened in the older times, in the pre-COVID era.

SEO had an old PHP script

The script was in fact a small PHP server running on a Windows server. It served a single unattractive HTML form allowing users to upload a SVC file and receive another CSV file in response.

The input CSV was a report generated by an SEO tool whose name escapes my memory. It had too many lines to manually sift through for insights, resembling a raw SQL response after multiple joins.

The output CSV was an aggregation of the input CSV. The script counted the frequency of keywords and URLs and ordered them by them most likely to succeed.

The specifics of what the script did are not crucial to this post. The noteworthy thing is that this script operated in a completely stateless way.

Just as a side note - It was written a few years prior by the head of SEO, who, despite having some PHP experience, did not identify as a developer.

Management said to shut it down

The Windows server was not properly maintained because the SEO team didn’t know how. The IT and Infra teams didn’t know either - it was the only Windows based system in the company.

The SEO team wanted a replacement, but the tech team didn’t have the resources to develop something right at that moment.

However, I had an idea for quick solution. I requested a few days to rewrite and deploy it within our existing Linux infrastructure.

I blindly TDD’ed it in three days

I asked the SEO team for sample input CSVs, downloaded the responses, and stored them in my new project’s “testing” directory. I then wrote a small test function to compare the CSV I returned with the responses generated by the original script.

I’m not an avid supporter of TDD. It’s hard for me to focus on problem solving while doing TDD. But in this case, I didn’t want to solve a problem; I simply wanted to rewrite an existing solution. It seemed like a good fit.

If you think that what I did is not truly TDD, I’d would probably agree but I’d love to hear the arguments

I then went over the PHP code, line by line, and tried to translate it to Go. It went by pretty smoothly. The PHP script didn’t use some cool metaprogramming or weird quirks of PHP. After I translated it, I could immediately run my test to find some bugs I had.

The end result was an ugly and huge function like the original. But it did the job, and I’m a lazy optimizer.

Now I had a function and Go, but no infra

Soon, I understood I won’t be able to get a new service deployment from the infra team. I remind you that this all happened when K8s was a mostly experimental thing, done by bigger companies than us. We were still in the age of shell scripts and manual clicking in a UI to spin up VM.

So I took another random backend API service I was working on, and just added an endpoint for the new Go function I had written.

As they say, “there’s no such thing as a temporary solution.” That endpoint served my SEO teams for years, even outlasting the entire original SEO team.

So, why did I do all of this work?

Why not just redeploy the PHP script elsewhere?

We had a bottleneck of creating new services in our microservices infra. Getting a new deployment from the infra team took more than two weeks, so rewriting it in Go means I could save the time of waiting for a new service infra.

I was happy to help the SEO team keep their tool alive, but the whole process would have been done in a few minutes if, as a developer, I could independently, safely spin up an app from a container image without needing help from the Infra team.

Why am I telling you this?

Because this story is just one of many experiences I had that lead me to believe that investing in developer experience actually increases our ability to put our efforts where they count. Instead of wasting time on rewriting a php script, we should have been spinning up small a PHP container to run that script. To clarify, no one intentionally delayed things. Kubernetes was still new, lacking stable plugins. It was a time of adaptation and learning what mattered most.

Shifting left on infra is a new concept in the world of SE. I felt something that many others in the industry had felt at the time, which is that we need to treat developers as human users, who could use better UX.

To me, the ideas of K8s are a continuation for Bret Victor’s lecture “The Future of Programming”, which I strongly recommend!