
CONFLICT started in 2012. The iPhone 5 was new. Docker did not exist. AWS had about a tenth of the services it has today. The idea that software could be delivered continuously, that infrastructure could be declared in code, that machine learning could be deployed as an API call, these were either nascent ideas or outright fantasies.
Thirteen years later, we have shipped software for Google, Backcountry, Skullcandy, Grindr, Zonos, SteadyMD, and dozens of other companies across industries we never expected to work in. We have built mobile applications, cloud platforms, eCommerce systems, voice AI products, chaos engineering tools, and AI workbenches. We have survived the mobile era, the cloud migration wave, the DevOps revolution, the microservices movement, the serverless hype cycle, and now the AI transformation.
Some of what we learned is specific to those eras and no longer relevant. But certain lessons have stayed constant across every technology shift, every client engagement, and every product we have built. These are the things that stayed true when everything else changed.
In 2012, the question was: do we use Backbone or Angular? In 2015, it was React or Angular 2? In 2018, it was Vue or React? In 2021, it was Next.js or Remix? In 2024, it was which AI framework? The frameworks change every two to three years. The fundamentals do not change at all.
Data structures, algorithms, systems design, networking, security principles, and testing methodology have been the same for decades. Every engineer who struggled on our projects struggled not because they did not know the framework. They struggled because they did not understand the fundamentals underneath the framework.
The engineer who understands HTTP can debug any web framework. The engineer who understands relational algebra can use any ORM. The engineer who understands distributed systems can design for any cloud provider. The framework is syntax. The fundamentals are the language.
We hire for fundamentals. We can teach anyone a new framework in two weeks. We cannot teach systems thinking in two weeks. This has been true since 2012, and it is even more true now that AI can write the framework-specific code for you. What AI cannot do is decide the right architecture, debug a distributed system, or reason about the tradeoffs between consistency and availability. Those require the fundamentals.
Every technology hype cycle follows the same pattern. A new technology appears that is genuinely useful. Early adopters demonstrate impressive results. The industry extrapolates those results to every possible use case. Companies adopt the technology for problems it does not solve. Projects fail. The backlash begins. Eventually, the technology finds its appropriate niche, which is smaller than the hype predicted but larger than the backlash suggested.
We have lived through this cycle multiple times. Mobile-first was the right strategy for consumer applications and the wrong strategy for enterprise tools. Microservices solved real scaling problems for large organizations and created unnecessary complexity for small teams. Serverless eliminated operational burden for event-driven workloads and created debugging nightmares for stateful applications.
AI is in the hype phase right now. The technology is genuinely transformative. It is also being applied to problems where simpler solutions work better. We have had conversations with potential clients who wanted to use large language models for tasks that a regular expression could handle. We have seen companies invest in custom model training when a well-crafted prompt on a commercial model would suffice.
The lesson: adopt technology because it solves a specific problem you have, not because the industry says you should. The companies that benefited most from each technology wave were the ones that adopted deliberately, for clear reasons, at the right time. The companies that suffered were the ones that adopted because they were afraid of being left behind.
Move fast and break things was a philosophy that made sense when the thing being built was a social network with no revenue and unlimited tolerance for bugs. It does not make sense when the thing being built processes medical records, handles financial transactions, or manages supply chains.
But the alternative is not move slowly and build perfectly. Perfect is the enemy of shipped. The teams that win move fast with discipline: they ship quickly, but with tests, with monitoring, with rollback capability, and with clear boundaries around what is acceptable to break.
We formalized this into our HiVE methodology, High-Velocity Engineering, because we needed a way to articulate how we work to clients who had been burned by shops that moved fast and left a mess, and by shops that moved so carefully that nothing ever shipped.
The specific practices that enable speed with discipline:
Automated testing that runs on every commit. Not comprehensive testing, fast testing that catches the most common categories of bugs. Comprehensive testing runs in the background.
Feature flags that decouple deployment from release. You can deploy to production ten times a day if the new code is behind a flag. The risk is in the release, not the deployment.
Monitoring that detects problems in minutes, not days. When you can detect and roll back a bad deployment in five minutes, the cost of a mistake is five minutes of degraded service, not a week of customer complaints.
Clear architectural boundaries that limit blast radius. When a service fails, only that service’s functionality is affected. The rest of the system continues operating.
These practices have been constant across every era. The tools change. The principle does not: you can move fast if you have the safety nets in place.
The best technology decisions are the ones nobody notices. The database that handles ten times the expected load without anyone worrying about it. The deployment pipeline that ships code to production without anyone thinking about it. The monitoring system that detects problems before users report them.
The worst technology decisions are the ones everyone notices. The custom framework that requires specialized knowledge to maintain. The clever optimization that nobody understands six months later. The novel architecture that works beautifully in the presentation and breaks in production.
We have learned to be boring on purpose. Use Postgres unless there is a specific reason not to. Use standard HTTP unless you need WebSockets. Use monolithic architecture unless you have a scaling problem that requires services. Use the most common library for the task, not the most technically interesting one.
This is not anti-innovation. Innovation should be directed at the problem you are solving for your client, not at the infrastructure you are solving it with. When the infrastructure is boring, predictable, and well-understood, the team can focus all its creative energy on the actual problem. When the infrastructure is novel and exciting, the team spends its energy maintaining the infrastructure instead of building the product.
The projects that shipped on time and ran reliably in production were, without exception, the projects that made boring technology choices. The projects that struggled were the ones where the team got excited about a new technology and used the client’s project as a testing ground.
In thirteen years of client work, not a single client has praised us for our choice of programming language. Not one has expressed excitement about our deployment pipeline. Not one has asked about our database architecture for the pleasure of knowing.
Clients care about outcomes. Did the project ship on time? Does the system work reliably? Can their team maintain it after we leave? Does it solve the problem they hired us to solve?
This sounds obvious. It is not. Engineers, ourselves included, are naturally drawn to technical elegance. We want to use the best tools, build the cleanest architectures, and solve problems in the most intellectually satisfying way. These instincts are good when they align with client outcomes. They are dangerous when they diverge.
We have learned to lead with impact. Not “we use Kubernetes for container orchestration” but “your system scales automatically to handle Black Friday traffic without manual intervention.” Not “we implemented event sourcing” but “you have a complete audit trail of every transaction for compliance purposes.” Not “we built a multi-model AI pipeline” but “your document processing time dropped from six hours to twenty minutes.”
The technology serves the outcome. The outcome is what the client is paying for. This framing has changed how we scope projects, how we write proposals, and how we report progress. It has also changed which technology choices we make, because when you optimize for outcome rather than elegance, you make different decisions.
The hardest part of every project is not the technology. It is the people. Communication failures cause more project failures than technical failures. Misaligned expectations cause more budget overruns than scope creep. Organizational politics derail more timelines than technical challenges.
We have built technically excellent systems that failed because the client’s organization was not ready to adopt them. We have built simple systems that succeeded because the client’s team was aligned, engaged, and committed to making it work.
The specific people problems that recur:
Stakeholders who cannot agree on requirements, not because the requirements are unclear, but because the stakeholders have conflicting priorities they have not resolved.
Teams that resist change because the new system threatens their expertise, their workflow, or their sense of value in the organization.
Decision-makers who are too far from the work to make timely decisions, creating bottlenecks that delay the project by weeks.
Organizations where the person who approved the project is not the person who will use the system, and the person who will use the system was never consulted.
We have gotten better at identifying these problems early and addressing them directly. We include organizational readiness assessment in our project planning. We identify stakeholder conflicts before they become delivery blockers. We build relationships with the people who will actually use the system, not just the people who signed the contract.
This is not soft skills. This is project delivery. The best engineers in the world cannot deliver a successful project if the organizational context is not aligned.
The most valuable skill in software engineering is not knowing how to build something. It is knowing when not to build it.
Every feature you build needs maintenance. Every line of code is a liability. Every integration is a potential failure point. The projects that succeed are the ones that build exactly what is needed and nothing more.
We have gotten better at this over thirteen years. Better at saying “you do not need that feature” when the feature adds complexity without adding proportional value. Better at saying “use an existing service” when building a custom solution is not justified. Better at saying “this is not the right time for this” when a capability would be valuable eventually but is not worth the investment now.
This discipline is harder in the AI era because AI makes building things faster. When it takes three days to build a feature instead of three weeks, the temptation to build it is stronger. But the maintenance cost does not change proportionally. A feature that takes a day to build with AI still takes the same amount of effort to maintain, monitor, and support as a feature built in a week without AI.
Build less. Build the right things. Build them well. This has been true since 2012, and faster tools have not changed it.
The next thirteen years will bring changes we cannot predict. The mobile revolution, the cloud migration, the AI transformation, none of these were obvious in 2012. Whatever comes next will be equally unexpected.
But the lessons will hold. Fundamentals over frameworks. Deliberate adoption over hype-driven adoption. Speed with discipline. Boring technology for infrastructure. Outcomes over elegance. People over processes. Restraint over capability.
These are not lessons about software engineering. They are lessons about building things that work, in a world that keeps changing, for people who care about results more than technology. Thirteen years is a long time in this industry. Long enough to see every trend come and go. Long enough to learn that the things that matter are the things that do not change.