The Efficiency Trap

"You have reached your specified API usage limits..."

I’ve been staring at this message for ten minutes now. Not because I don’t understand what it means—I hit my Claude Code API limit while building some throwaway project for fun. But because something about it bothers me in a way I can’t quite articulate.

That’s exactly what’s weird about this. That kind of programming doesn’t exist anymore.

I started thinking about what just happened. I was coding, sure, but I wasn’t really coding alone. I had an AI pair programmer that could write functions faster than I could think of them, suggest architectures I’d never considered, and debug problems that would have taken me hours to solve. When it got cut off, I didn’t just lose a tool—I lost a collaborator that had become an extension of my own thinking.

And then I realized: I couldn’t really continue without it. Not in any meaningful way.

That’s when it hit me. This isn’t just about AI. This is about everything now.

When was the last time you built something that worked entirely on your own machine? I mean really worked, not just a hello world app, but something you could show to users? Think about it. You probably need AWS to host it, Stripe for payments, Auth0 for users, and on and on.

We’ve created this incredibly complex web of dependencies, and we call it progress. And it is progress, in a way. I can build in a weekend what would have taken a team months just a few years ago. But I can only build it if all these services are up, working, and willing to take my money.

There’s something almost feudal about it. We’re all tenant farmers now, working land we don’t own, using tools we can’t repair, selling crops we don’t control the price of.

I keep thinking about this idea of efficiency versus resilience. In biology, the most specialized organisms are often the most efficient at their particular niche, but also the most fragile when conditions change. An organism that evolves to thrive in one specific environment often struggles when that environment disappears.

We’ve done the same thing with our technology stack. We’ve optimized for the happy path so completely that we’ve forgotten what the sad path even looks like.

My grandfather used to tell stories about working in machine shops where each shop could make almost anything. They had lathes, mills, welders, and machinists who knew how to use all of them. If you needed a part, they could make it. If a machine broke, they could fix it. The whole operation was antifragile in a way that seems almost quaint now.

I remember my first startup wasn’t that different, in its own way. We racked and stacked our own servers in the office. Bought our own router, ran our own cables, configured our own firewall. When something broke at 2am, I’d drive to the office with a screwdriver and a spare hard drive. It was a pain, sure, but we owned the whole stack. We understood every piece of it because we’d touched every piece of it. That wasn’t that long ago—maybe fifteen years?

Now I work in an industry where we celebrate removing dependencies on our own infrastructure. “Don’t roll your own authentication” has evolved into “don’t roll your own anything.” And mostly, this is good advice. The security engineers at your startup probably aren’t better than the ones at Auth0. Your database probably isn’t more reliable than the one AWS manages.

But what happens when Auth0 goes down?

I remember the great AWS outage of 2017. We’d built a civilization on top of a few data centers in Northern Virginia, and we didn’t even realize it until it stopped working.

The weird part is that this fragility is a choice. We could build systems that work offline, that degrade gracefully, that have real redundancy. But we don’t, because it’s slower and more expensive and the market rewards shipping fast over shipping robust.

There’s this concept in economics called “optimization for local maxima.” You keep making the system better according to your current metrics, but you might be climbing the wrong hill entirely. I wonder if we’ve optimized so hard for development velocity that we’ve created a local maximum we can’t easily escape from.

Because here’s the thing: everyone is making the same trade-offs. Your competitors aren’t building resilient systems either. They’re using the same cloud providers, the same SaaS tools, the same APIs. When those services have problems, everyone has problems at the same time.

And it’s not just the money. It’s the cognitive overhead. You need to understand dozens of different APIs, dozens of different billing models, dozens of different outage patterns. You need to know which services play nicely together and which ones have subtle incompatibilities. You need to monitor the status pages of services you didn’t even know you depended on.

We’ve traded the complexity of building things for the complexity of integrating things, and I’m not sure we got a good deal.

But then I think about what I actually accomplished in those few hours before hitting the API limit. I built something that would have taken me weeks to build five years ago. The AI helped me think through problems I didn’t even know I had.

Maybe this is just what progress looks like. The printing press made us dependent on paper mills. The assembly line made us dependent on supply chains. The internet made us dependent on packet routing. Each time, we traded independence for capability, and mostly, it worked out.

But this time feels different. The dependencies are deeper and more concentrated. A handful of companies control the infrastructure that everything else depends on. And the speed of change means we’re building new dependencies faster than we can understand the implications.

When that API limit message appeared, it wasn’t just telling me I’d hit a usage limit. It was reminding me that I’d become dependent on systems I don’t control, built by people I’ll never meet, running in data centers I’ll never see.

And maybe that’s fine. Maybe that’s just how things work now. But it’s worth noticing.