I Can't Write Code, but That Doesn't Mean I Don't Understand Systems
An Incomplete Sentence
I often say that I cannot write code.
I say it to correct a misunderstanding. When people see the mini-programs, ad-delivery system, and research tools I have built, it is easy for them to assume I am a programmer. I am not able to start from a blank file and independently design, implement, and review a large system. Most of the code in these projects was written by AI.
But the sentence creates another misunderstanding: that I merely throw a requirement at AI and happen to get back something that runs.
That is not what happened.
I have some knowledge of servers and architecture. I care about security, redundancy, latency, cost, and the resources at hand. But that knowledge is incomplete, and it has not been trained into the kind of ability a conventional engineer can independently apply to every line of code.
So a more accurate way to put it is this:
I cannot independently turn a system into code, but I can help decide why that system exists, where it must not fail, and what counts as evidence that it really works.
A Task That Could Not Be Settled by a Demo
At the beginning of 2026, I helped a friend build an ad-delivery system.
One part of it was called RTA. An ad platform sends a device identifier, and the system must answer very quickly: is this device worth bidding on? Another part, oCPC, receives click and conversion callbacks so the delivery system can learn which ads actually produced results.
At the start, I understood neither RTA nor oCPC. I did not know how to operate servers, and of course I could not write this system myself.
But the task was very specific: it had to enter production, carry real traffic, and keep response latency within the platform’s requirements. It was not a demo, nor was it built to produce an impressive load-test number. If the answer arrived too slowly, the traffic was gone. If a link in the chain broke, real business data could be lost.
My friend gave me a real, if relatively forgiving, business environment. Claude proposed the architecture, wrote the code, analyzed logs, and changed the connection-pool and concurrency models. I operated the cloud platform following its instructions, and kept asking at key points: which path had to be fastest, which services should be isolated, whether unknown devices should be allowed through or rejected, and whether adding machines would simply move the bottleneck downstream.
At one point, we needed to split the traffic. The existing domain and tracking links could not change, or all the earlier integrations would have had to be redone. We ultimately kept the entry point intact, sending only the latency-sensitive /rta requests to elastic servers while keeping notification and administration interfaces on the main server.
I did not write the routing code.
But what could not change, which path needed isolation, and what had to remain available in a failure were system questions, not questions of syntax.
Systems Do Not Listen to Stories
I soon ran into a counterintuitive result.
When handling an external API, raising concurrency from 100 to 300 seemed as though it should make things faster. In practice, at 300 concurrent requests, median latency rose to four or five seconds and throughput fell to only about 50 requests per second. Lowering concurrency to 100 brought median latency back to about one second, while throughput increased slightly.
More machines, more threads, and more concurrency do not automatically mean more capacity. Rate limits at an external API, connection overhead, and queue buildup can turn “stronger” into “slower.”
Another batch of real requests made the point even more clearly. About 400,000 requests entered the system over roughly eleven minutes—an average of about 600 per second. The entry point received them, but many cache-miss devices went into later processing; after the ads were turned off, the queue still took more than twenty minutes to clear.
If you looked only at the entry point, the system had succeeded.
If you looked at the whole chain, the real bottleneck was still downstream.
This kind of feedback is why I can work this way. AI can offer explanations, and I can keep asking questions, but neither of us gets to decide the answer by sounding more like an expert. Latency, throughput, backlog, and business results make that decision.
So we reduced concurrency, separated the cache from the queue, and moved audience data that had to be kept permanently into a database. Once real traffic fell, we scaled the elastic-server fleet from twenty machines down to two, while retaining a fallback path.
Scaling up is a decision; scaling down is one too. A system is not better because it is bigger. It should be just large enough for its current constraints.
What 64,000 QPS Proves
The number people most readily remember from this project is about 64,000 QPS.
The project record later noted, based on my own confirmation, that this was a peak observed in production—not a load-test result. But neither does it mean that the entire ad-delivery system sustained 64,000 completed business operations per second. The peak was mainly on RTA’s fast entry path: reading a cache, making a decision, and placing subsequent work on a queue. That is not the same kind of load as slow downstream APIs, conversion callbacks, or database writes.
In another period, the system’s typical traffic rate was only about 71 requests per second, which is why we reduced the fleet from twenty machines to two. A separately recorded request batch averaged about 600 requests per second.
Peak, average, duration, and scope of the path are four different things.
If they are compressed into one line—“I used AI to reach 64,000 QPS in two weeks”—the line is not entirely false, but it creates a story much cleaner than the facts. A closer account is this: the core RTA capability took shape quickly, in about two weeks, allowing an outsider with AI assistance to build a system that could enter real business use; over the following months, production continued to reveal problems, and the system continued to change.
64,000 QPS proves that this entry path handled a large amount of real traffic at that moment.
It does not prove that I had become an ad-systems expert, or that the entire system had no hidden problems.
Errors That Success Did Not Hide
The system did have problems.
At one point, the query interface and the main path used incompatible keys, while a secondary index was neither written nor queried correctly. The cache hit rate for one kind of data temporarily fell to zero. There were also data losses and callback replays; one audit found that function definitions were in the wrong order; and deployment brought network errors, 404s, and 502s.
These are not incidental blemishes beside the story. They show the limits of what I can do.
I can trace a zero hit rate back to two paths that are out of sync. I can require that unknown devices be rejected by default, ask that critical and non-critical services be isolated, and require a fallback path before a change is made.
But I cannot inspect every hidden risk in a large body of generated code by myself. I do not know how many errors have not yet been exposed by traffic, and I cannot prove that an architecture will remain sound over a longer period or under harsher conditions.
Feedback from reality can expose errors we have encountered; it cannot prove that there are no errors we have not encountered.
Production operation is more persuasive than a demo, but it is still not a complete professional review.
AI Has Not Made Engineering Disappear
AI has greatly lowered the cost of implementation. In the past, I would first have needed years to master a medium of expression before I could turn an idea into a system. Now a model can expand syntax, call APIs, refactor services, and analyze logs for me.
But it has lowered the threshold for entering engineering; it has not made engineering problems disappear.
If the requirements are wrong, AI will implement the wrong requirements efficiently. If a boundary is missing, it will generate an internally coherent answer beyond that boundary. If a test environment is not isolated, it may “validate” while consuming real APIs and real resources. Code that runs may only mean that the conditions that trigger its errors have not yet appeared.
So code written by AI does not mean engineering ability no longer matters. On the contrary, some responsibility has moved elsewhere:
- Are the goals clear?
- Are the constraints complete?
- Where are the system boundaries?
- Which failures are unacceptable?
- What evidence is enough to proceed, and what signals require stopping?
- When output exceeds one’s own understanding, who will check it?
These questions existed before. Code was simply a high barrier that kept untrained people from reaching them. Now that barrier is lower, more people can confront these questions directly—and more people can create these problems directly.
Which Part I Can Take Responsibility For
This project does not imply that programmers will no longer be needed, or that anyone who can describe a requirement can build a production system.
Its goal was clear. Feedback was fast. A friend provided a real but relatively forgiving business environment, and the cloud platform carried much of the infrastructure burden. In medicine, finance, safety-critical systems, or large infrastructure requiring years of maintenance, the same way of working might be far from sufficient.
What I actually have is not a complete understanding of code or advertising technology, but a limited ability to participate in systems: to bring real goals into the work, state unacceptable consequences, let AI generate and explain options, choose among resources, risks, and effects, and then allow operational results to overturn that choice.
I cannot write code. That is still true.
I cannot independently prove that every part of this system is correct. That is also true.
But I am not standing outside the system, waiting for AI to create a miracle. I am participating where goals, constraints, tradeoffs, feedback, and responsibility reside.
Technical ability is not only one thing: how much code someone wrote with their own hands. Being able to make code appear is not the same as possessing complete engineering ability.
As models take on more of the implementation, the question people ultimately need to answer may no longer be only, “Did I write this?” It may be:
What gives me the right to put it into reality, and how am I prepared to take responsibility for its consequences?