Insights from 8+ years of engineering high-concurrency systems. Exploring the intersection of traditional backend architecture and the evolving world of Generative AI.
Topics: Kubernetes, Distributed Systems, and Go.
Insights from 8+ years of engineering high-concurrency systems. Exploring the intersection of traditional backend architecture and the evolving world of Generative AI.
Topics: Kubernetes, Distributed Systems, and Go.
Kubernetes has spent years getting very good at answering one fundamental question: Where should this Pod run? For a large class of traditional applications, that is exactly the right question. A stateless Deployment with ten API replicas usually does not care if replica seven starts 20 seconds after replica six. Each Pod makes progress independently. The scheduler evaluates them one at a time, finds a feasible Node, binds the Pod, and moves to the next item in its queue....
For most of software history, we knew what untrusted input looked like. Request parameters, form submissions, and user uploads are untrusted. External data requires validation before we use it. Application security revolves around maintaining this separation. User input provides values to the application. It must not redefine what the application is allowed to do. SQL, command, and template injections are dangerous for this exact reason. They break the assumption of separation and allow data to influence execution....
Most backend systems eventually grow a hidden workflow engine. It rarely starts that way. It usually begins with a simple cron job that wakes up every ten minutes, queries the database for pending records, processes them, and updates a status column. It seems simple enough, until production happens. A downstream API times out. A worker crashes halfway through processing. A deployment abruptly kills the process. A customer asks why their job is stuck....
For decades, software engineering had a fairly predictable constraint. Writing software was expensive. Every feature required engineers, every system required implementation, and every new capability required time, effort, and people. That constraint shaped how we built software. Today, it is disappearing. AI can generate code faster than most teams can review it, and that changes something fundamental about the job. The Old Bottleneck For most of software history, engineering organizations optimized for output....
Walk into any AI infrastructure discussion and you’ll hear the same question: What’s your GPU utilization? It’s become the infrastructure equivalent of asking a web service for its CPU utilization. The assumption is simple: higher utilization is better. After all, GPUs are expensive, and a cluster running at 90% utilization sounds far more impressive than one running at 50%. For a long time, I believed that too. Then I spent more time working on GPU scheduling and multi-tenant AI workloads....
I used to think DNS was boring. You ask for a name, you get an IP, the application connects. That was my entire mental model, until a bug dismantled it completely. The service worked when addressed by IP but failed with a hostname. It worked from one machine and failed from another. Then, oddly, it started working the moment I added a trailing dot to the domain name. That day I learned that DNS is never simple, not because it is poorly designed, but because decades of accumulated behaviour are hiding behind what looks like a plain string....
For the past two years, the tech world has insisted that mastering prompt engineering is the path to better AI outcomes. Entire courses, newsletters, and YouTube channels promise a magic phrase that will unlock more useful answers from models. After thousands of interactions with Claude, ChatGPT, and other systems, I have a different take: most prompt problems are actually requirement problems. This distinction matters. Prompt engineering is primarily about how you ask; requirement engineering is about what you actually want....
Most developers know how to branch in Git. Far fewer know how to work on multiple branches without constantly disrupting themselves. That problem used to be mostly about human workflow. You were in the middle of a feature, an urgent bug came in, a teammate asked you to review something, and suddenly your clean local state was gone behind a mix of branch switching, stashing, and half-finished changes. It was annoying, but manageable....
Distributed systems rarely fail in clean, obvious ways. They degrade. They stall. They partially succeed. They retry half a request, lose the response, and leave you wondering whether the operation happened once, twice, or not at all. In production, reliability is rarely about whether the code works on a happy path. It is about how the system behaves when dependencies are slow, networks are unreliable, and clients do not get a clear answer....
The software industry has a habit of celebrating novelty. New frameworks, new abstractions, new patterns, and new promises of developer productivity show up every few months. Production systems, however, rarely fail because they were not modern enough. They fail because they were difficult to reason about, fragile under stress, and painful to operate. Over time, I have become much less interested in clever backend services and much more interested in boring ones....