Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

oren@ravendb.net +972 52-548-6969

Posts: 7,640
|
Comments: 51,255
Privacy Policy · Terms
filter by tags archive
time to read 7 min | 1339 words

I still remember the bookstore. I was holding a 600-page brick of a book on how to build Windows applications, trying to convince my mother that I really needed it. This was 1994 or 1995. A book was how you learned to program at that time. You took it home, you read it cover to cover, you typed the examples by hand, and somewhere along the way, the ideas sank in.

From there, the tools for learning kept evolving. Printed books gave way to CD-ROMs and then to online documentation. Then came the explosion of blogs and RSS feeds. I started this blog at that time, and I still consider that era to be one of the best ones in terms of having amazing access to smart and knowledgeable people, freely sharing their insights and experiences.

Google killed Google Reader (yes, I am still angry about that) and a lot of the new people learned via Stack Overflow. The world entered a strange equilibrium that lasted, honestly, more than a decade. If you learned to code any time between roughly 2010 and 2022, you probably learned through some combination of Google, Stack Overflow, and maybe YouTube.

Then the floor moved again. First it was ChatGPT, where you copy-pasted code back and forth. Then the models were integrated into the IDE. Now, with Claude Code and Codex, it is something else entirely: an agent that just runs, makes decisions, and does the thing.

The arc is striking when you lay it out. You used to have to go to a physical library, pick up a physical book, read it, digest it, and think about it. Today, the prevailing message to a new developer is essentially: you do not need to know any of that. Just describe what you want, and it happens.

Hidden costs for reduced conceptual depth

This shift is not just about convenience. It changes the depth of knowledge a developer carries, and that has consequences. Here is the example I keep coming back to. Imagine you ask a developer to show you a website that they built.

If you asked that in the late nineties, it meant something. To do that, you had to purchase a domain. Understand DNS well enough to wire it up correctly. Set up a web server, which meant getting Apache to actually run. Successfully configure PHP and deploy scripts to production.

By the time you could point to a working URL, you had to touch every layer of the stack. There was no other choice. Therefore, you were at least passingly familiar with a lot more than you would be today.

Ask that same question of many developers today, and the answer is a Vercel subdomain. That is not a dig at Vercel, mind you - it is a great product, and abstraction is the whole point. But some of these developers genuinely do not know what DNS is. They do not know what is running on the server versus the client. They do not know that there is even a meaningful distinction. And we have seen real security incidents come out of exactly that gap — secrets leaking into client bundles, auth logic running where it should not, and CORS misconfigurations that nobody understood well enough to notice.

Now extend that same dynamic one more step. Take the cohort of developers who will learn to program primarily through this new generation of agentic tools. The abstraction is no longer just over DNS or deployment. It is over the act of writing the code itself.

What is the role of a junior developer now?

I think we are going to end up with a genuinely different type of engineer and, as a result, a genuinely different type of system.

“If men learn this, it will implant forgetfulness in their souls; they will cease to exercise memory because they rely on that which is written, calling things to remembrance no longer from within themselves, but by means of external marks”.

  • Plato, Phaedrus (c. 429-347 BCE)  

Every generation has been accused of being softer than the previous generation, as the quote above can testify. In this case, Plato is decrying writing as a corrupting influence on youth who no longer bother to just remember things.

Without the attribution, I don’t think you would have realized that this isn’t me talking about developers utilizing coding agents instead of learning on their own.

In software, we see much the same pattern. The person who wrote assembly looked down on the C programmer. The C programmer looked down on the Java programmer. The Java programmer looked down on the person gluing libraries together in Python. Each step up the abstraction ladder lets people build bigger, more ambitious things with less effort. That is mostly good.

But there is a real asymmetry this time. The earlier steps abstracted away mechanical work — memory management, boilerplate, deployment plumbing. This step abstracts away the reasoning itself. And reasoning is what you need when the abstraction leaks, which it always eventually does.

The question I am actually struggling with, day to day, is much more practical: how do I evaluate a junior developer in this sort of world?

The classic move was a take-home task. Build a small feature. Show me your thinking. The problem is that a capable model will produce a perfectly clean solution to any reasonable take-home in a few minutes. What you see in the submission tells you almost nothing about what the candidate actually understands. It tells you they can prompt well, which is a real skill, but it is not the skill I am trying to measure.

I can also ask them to solve a task while they are in our offices, so I can verify no AI use. But that is also stupid; I want them to use AI. After all, that is a great productivity enhancer. So I need a way to test understanding, not just the output.

The signals I care about are the ones that are hardest to fake in an agent-assisted world. Can you debug something when the model is wrong? Can you explain why a piece of generated code is subtly unsafe, or slow, or wrong in a way that only matters at the hundredth user? Can you make a reasoned call about which abstraction to reach for and which one to reject? When the system behaves unexpectedly, do you know where to look?

At the same time, those aren’t usually qualities that you can look for in a junior developer. Having those qualities usually means that they aren’t junior anymore.

People used to train on LeetCode tests as a way to show how good they were in interviews. That was a good stand-in to see what they knew and understood. What is the next stage here?

What does a junior do to exercise their skills and show that they can bring value to the team? I don’t know if I have good answers to those questions. But that is something we, as an industry, need to consider carefully.

I do not want to be the old man yelling at the cloud. The tools are genuinely great, and refusing to use them is its own kind of malpractice. AI coding agents can make you meaningfully more productive.

But when I talk to developers just starting out, the thing I keep pushing is this: use the tools, and also, on a regular basis, go down a layer. Set up a server yourself. Deploy something without a platform holding your hand. Read the DNS records. Look at what your framework is actually generating. Write something in a language without a package manager that hides the sharp edges.

Not because you will do it that way at work. But because the next time something breaks in a way the agent cannot fix you will have a mental model to fall back on. You will know where the seams are. You will know what to look at.

That mental model is, I suspect, going to be the thing that separates the engineers who compound over a career from the ones who get stuck the first time the abstraction leaks.

time to read 5 min | 817 words

In the 2000s, the hottest move in software was offshoring. You'd ship your requirements to a development shop in India, Vietnam, or Bangladesh, pay a fraction of Western developer rates, and wait. The cost savings were real, every spreadsheet said so. The failure modes were also real, every CTO said so.

Even assuming that the teams working on your code were smart, motivated, and hardworking, the distance, communication overhead, the time zone mismatch, and misaligned incentives created a brutal set of constraints. If you wanted to get good results from offshoring,  you needed to be able to clearly specify what you wanted and be good at validating that you got what you expected.

You couldn't just say "I need a login system." You had to write detailed specs, break work into reviewable chunks, define acceptance criteria, and actually read the code that came back. Not rubber-stamp it. Read it, make sure that it passed muster and could be accepted internally, because the delta between "looks right" and "is right" could cost you six months of production incidents.

Sound familiar? Today, instead of shipping my requirements to a dev shop overseas, I'm shipping them to a GPU somewhere. I get something back. It looks like code. It might be code. It might be a very convincing facsimile of code that will quietly fail in production under load. I genuinely don't know until I sit down and read it carefully.

The same discipline that separated successful offshore engagements from expensive disasters applies here as well:

  • Specification quality determines output quality. Vague prompts return vague code. The ability to articulate exactly what you want — at the right level of abstraction — is now a core engineering skill.
  • Validation is non-negotiable. "It passed the vibe check" is not a code review. The reviewer needs to understand what the code is doing and why, not just that it compiles and the tests are green.
  • Iterative delivery beats big-bang delivery. Nobody who survived offshoring tried to outsource an entire product in one shot. You stage it. You review at each stage. You course-correct before mistakes compound.

The Bottleneck Has Moved

Here's what I think is the deeper shift: for most of software history, the bottleneck was writing the code. That took time and required expensive humans. So the industry optimized heavily around it, better editors, better frameworks, and better abstractions. All in service of making the act of writing code faster and less error-prone.

That bottleneck is collapsing. What once took six months might take six hours. When the cost of implementation approaches zero, the bottleneck moves upstream: to design, specification, and verification. The expensive parts are now:

  1. Understanding the problem clearly enough to describe it precisely.
  2. Decomposing it into well-scoped, independently verifiable pieces.
  3. Reviewing what comes back and actually understanding it.

These are skills we largely deprioritized during the era when coding itself was the hard part. They're about to become the most valuable things a technical person can do.

A lot of that used to be done “along the way” when you wrote the code. You would explore the problem and gain depth of understanding as you wrote the code. Now that just doesn’t happen, but you still need to do that work explicitly.

A note about the importance of proper architecture

There is this idea that the path to building big systems with AI is to spin up a swarm of specialized agents (a frontend agent, a backend agent, a database administrator agent, etc.) and somehow orchestrate them into a coherent product.

I find this baffling, because we already have a well-established protocol for coordinating the work of specialized, partially independent contributors on a complex system. It's called software design.

Module boundaries. Interface contracts. Separation of concerns. Dependency management. SOLID principles and more. These patterns exist precisely because complex systems built by multiple contributors without clear interfaces turn into unmaintainable messes. This is true whether those contributors are humans, offshore teams, or language models.

The instinct to throw orchestration complexity at a coordination problem is exactly backwards. The answer isn't a smarter message bus between your agents. The answer is better system design that minimizes how much the pieces need to talk to each other in the first place.

We have literally decades of experience in how to build large software systems (and thousands of years of experience in how to handle large projects in general). There isn’t anything inherently new here to deal with.

The developers who will thrive in this environment aren't necessarily the ones who write the most elegant code. They're the ones who can hold a complex system design in their head and communicate it clearly, break the work into well-specified, verifiable increments, and actually read the code that comes back and hold it to a real standard of quality.

These are, in large part, the same skills that made the best engineering leads effective during the offshoring era. The context has changed completely. The discipline hasn't.

The GPU is the new Bangalore. Time to dust off the playbook.

FUTURE POSTS

No future posts left, oh my!

RECENT SERIES

  1. API Design (10):
    29 Jan 2026 - Don't try to guess
  2. Recording (20):
    05 Dec 2025 - Build AI that understands your business
  3. Webinar (8):
    16 Sep 2025 - Building AI Agents in RavenDB
  4. RavenDB 7.1 (7):
    11 Jul 2025 - The Gen AI release
  5. Production postmorterm (2):
    11 Jun 2025 - The rookie server's untimely promotion
View all series

Syndication

Main feed ... ...
Comments feed   ... ...