<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Edgar Nahama Alochi</title>
    <description>The latest articles on DEV Community by Edgar Nahama Alochi (@nahamaalochi).</description>
    <link>https://dev.to/nahamaalochi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4017885%2F79abbb49-c4c8-4a4c-96ca-82feca0d1ffd.jpg</url>
      <title>DEV Community: Edgar Nahama Alochi</title>
      <link>https://dev.to/nahamaalochi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nahamaalochi"/>
    <language>en</language>
    <item>
      <title>The Role of Clear Documentation in Team Velocity</title>
      <dc:creator>Edgar Nahama Alochi</dc:creator>
      <pubDate>Sat, 01 Aug 2026 06:07:50 +0000</pubDate>
      <link>https://dev.to/nahamaalochi/the-role-of-clear-documentation-in-team-velocity-ihd</link>
      <guid>https://dev.to/nahamaalochi/the-role-of-clear-documentation-in-team-velocity-ihd</guid>
      <description>&lt;p&gt;Most teams treat documentation like a speed bump.&lt;/p&gt;

&lt;p&gt;They are wrong.&lt;/p&gt;

&lt;p&gt;Documentation is engine oil.&lt;/p&gt;

&lt;p&gt;When a team says &lt;em&gt;“we don't have time to document,”&lt;/em&gt; what they are really saying is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“We prefer to finance our progress with high-interest technical debt.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Velocity is not about how fast you can type.&lt;/p&gt;

&lt;p&gt;It is about how rarely you stop, stare at a function, and wonder what the developer who wrote it six months ago was trying to accomplish.&lt;/p&gt;

&lt;p&gt;Documentation is not paperwork.&lt;/p&gt;

&lt;p&gt;It is the preservation of intent.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Speed Trap
&lt;/h1&gt;

&lt;p&gt;There is a persistent myth in engineering:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“The code is the documentation.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is partially true.&lt;/p&gt;

&lt;p&gt;Code explains &lt;strong&gt;what the system does&lt;/strong&gt;. It is the ultimate source of truth for implementation.&lt;/p&gt;

&lt;p&gt;But code is silent about &lt;strong&gt;why&lt;/strong&gt; it does it that way.&lt;/p&gt;

&lt;p&gt;Code tells you the implementation.&lt;/p&gt;

&lt;p&gt;Documentation tells you the trade-offs.&lt;/p&gt;

&lt;p&gt;When the &lt;em&gt;why&lt;/em&gt; disappears, velocity disappears with it.&lt;/p&gt;

&lt;p&gt;Every time a new engineer joins the team — or an old engineer returns to a forgotten module — they must perform digital archaeology. They dig through commit history, Slack threads, and half-remembered conversations trying to reconstruct the missing context.&lt;/p&gt;

&lt;p&gt;This is not speed.&lt;/p&gt;

&lt;p&gt;It is friction disguised as progress.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why Velocity Actually Stalls
&lt;/h1&gt;

&lt;p&gt;Velocity rarely dies because engineers type slowly.&lt;/p&gt;

&lt;p&gt;Velocity dies because of &lt;strong&gt;uncertainty&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It shows up in predictable ways.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Tribal Knowledge Tax
&lt;/h3&gt;

&lt;p&gt;Critical information exists only in the heads of three senior engineers.&lt;/p&gt;

&lt;p&gt;To move forward, you must interrupt them.&lt;/p&gt;

&lt;p&gt;Your progress comes at the cost of their focus. The team slows down while pretending to move faster.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Regression Loop
&lt;/h3&gt;

&lt;p&gt;You see a line of code that looks redundant.&lt;/p&gt;

&lt;p&gt;You remove it.&lt;/p&gt;

&lt;p&gt;Two days later production breaks because that “redundant” line was quietly preventing an edge case discovered during a 2022 incident.&lt;/p&gt;

&lt;p&gt;Documentation would have saved you two days and a few grey hairs.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Decision Re-Run
&lt;/h3&gt;

&lt;p&gt;The team spends three hours debating an architectural decision.&lt;/p&gt;

&lt;p&gt;Six months later, the exact same meeting happens again.&lt;/p&gt;

&lt;p&gt;No one remembers why the first decision was made.&lt;/p&gt;

&lt;p&gt;So the debate starts from zero.&lt;/p&gt;

&lt;p&gt;Again.&lt;/p&gt;

&lt;p&gt;Documentation shrinks the &lt;strong&gt;time-to-understanding&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If a system takes ten minutes to understand instead of two hours, the team does not just move faster.&lt;/p&gt;

&lt;p&gt;It moves &lt;strong&gt;confidently&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  What to Document (And What to Ignore)
&lt;/h1&gt;

&lt;p&gt;Most documentation fails because it documents the wrong things.&lt;/p&gt;

&lt;p&gt;It explains syntax instead of decisions.&lt;/p&gt;

&lt;p&gt;Useful documentation follows three simple rules.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Context Over Syntax
&lt;/h3&gt;

&lt;p&gt;Do not explain that a loop iterates over an array.&lt;/p&gt;

&lt;p&gt;Engineers already know that.&lt;/p&gt;

&lt;p&gt;Explain &lt;strong&gt;why the system uses an array instead of a stream&lt;/strong&gt;, or why a synchronous call was chosen over an asynchronous one.&lt;/p&gt;

&lt;p&gt;The value of documentation is not repeating the code.&lt;/p&gt;

&lt;p&gt;It is explaining the reasoning behind it.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Record Decisions (ADRs)
&lt;/h3&gt;

&lt;p&gt;Architectural Decision Records are one of the highest leverage tools in engineering teams.&lt;/p&gt;

&lt;p&gt;Every significant design decision should answer three questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What did we choose?&lt;/li&gt;
&lt;li&gt;What alternatives did we consider?&lt;/li&gt;
&lt;li&gt;Why did we reject them?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without this, every new engineer eventually believes they have discovered a brilliant idea.&lt;/p&gt;

&lt;p&gt;Often it is simply the &lt;strong&gt;same idea the team rejected two years ago&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The README Is a Map
&lt;/h3&gt;

&lt;p&gt;A good README should get a new engineer from:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git clone&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;to a &lt;strong&gt;running, tested environment in five minutes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If onboarding takes an hour, the documentation is broken.&lt;/p&gt;

&lt;p&gt;If it takes two days, the architecture probably is too.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Discipline of the Grown Engineer
&lt;/h1&gt;

&lt;p&gt;Writing good documentation feels like a chore.&lt;/p&gt;

&lt;p&gt;That is because it forces clarity.&lt;/p&gt;

&lt;p&gt;You can hide confusion inside complicated code.&lt;/p&gt;

&lt;p&gt;You cannot hide it inside a clear sentence.&lt;/p&gt;

&lt;p&gt;If you cannot explain the intent of your system in writing, there is a good chance you do not fully understand it yet.&lt;/p&gt;

&lt;p&gt;Documentation is not busywork.&lt;/p&gt;

&lt;p&gt;It is an act of empathy for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your future self&lt;/li&gt;
&lt;li&gt;your teammates&lt;/li&gt;
&lt;li&gt;the engineer who will inherit the system three years from now&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Who, statistically speaking, might also be you.)&lt;/p&gt;

&lt;h1&gt;
  
  
  The Uncomfortable Conclusion
&lt;/h1&gt;

&lt;p&gt;Velocity is a function of clarity.&lt;/p&gt;

&lt;p&gt;If your team claims to be moving fast but:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the architecture is a mystery&lt;/li&gt;
&lt;li&gt;onboarding feels like a two-week hazing ritual&lt;/li&gt;
&lt;li&gt;and every change requires consulting the “one person who knows the system”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;then the team is not fast.&lt;/p&gt;

&lt;p&gt;It is fragile.&lt;/p&gt;

&lt;p&gt;Real velocity is sustainable.&lt;/p&gt;

&lt;p&gt;It comes from a shared, written understanding of the system — one that survives beyond any individual developer.&lt;/p&gt;

&lt;p&gt;Stop thinking of documentation as &lt;strong&gt;extra work&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Documentation &lt;em&gt;is&lt;/em&gt; the work.&lt;/p&gt;

&lt;p&gt;Everything else is just typing.&lt;/p&gt;

</description>
      <category>note</category>
      <category>architecture</category>
      <category>bestpractices</category>
      <category>documentation</category>
    </item>
    <item>
      <title>Designing for Change, Not Control</title>
      <dc:creator>Edgar Nahama Alochi</dc:creator>
      <pubDate>Fri, 31 Jul 2026 17:21:11 +0000</pubDate>
      <link>https://dev.to/nahamaalochi/designing-for-change-not-control-275e</link>
      <guid>https://dev.to/nahamaalochi/designing-for-change-not-control-275e</guid>
      <description>&lt;p&gt;There is a quiet lie we tell ourselves when we design systems.&lt;/p&gt;

&lt;p&gt;We call it structure. We call it governance. We call it standards, frameworks, alignment. But beneath all those respectable words is a single desire: control.&lt;/p&gt;

&lt;p&gt;I understand the temptation. I have felt it myself. When you are responsible for a system, a product, a team, or an organisation, you want predictability. You want to believe that if you think hard enough and design carefully enough, you can eliminate surprises. You want the future to behave.&lt;/p&gt;

&lt;p&gt;It never does.&lt;/p&gt;

&lt;p&gt;Architecture, whether technical or organisational, is temporal. A decision that is correct today can become a liability tomorrow. What solves a constraint at one stage often becomes the bottleneck at the next. That is not failure. That is the nature of growth.&lt;/p&gt;

&lt;p&gt;The problem begins when we design as though today’s constraints will last forever.&lt;/p&gt;

&lt;p&gt;Control is a snapshot. It captures the present and freezes it. But the world is not static. Markets move. Teams change. Customers evolve. Technology ages. Even our own understanding matures. Designing for control assumes stability. Designing for change assumes movement.&lt;/p&gt;

&lt;p&gt;And movement is the more honest assumption.&lt;/p&gt;

&lt;p&gt;When I design systems now, I do not ask, “How do I make this perfect?” I ask, “How will this need to evolve?” The first question leads to rigidity. The second leads to resilience.&lt;/p&gt;

&lt;p&gt;Perfection is brittle. Resilience bends.&lt;/p&gt;

&lt;p&gt;There is a particular kind of comfort that comes from tightly coupling everything. When components depend deeply on each other, when processes are heavily standardised, when decisions must pass through a single authority, things appear orderly. It feels safe. But that safety is deceptive. It works beautifully until the first significant change arrives. Then the cost of altering one part ripples through the entire structure.&lt;/p&gt;

&lt;p&gt;Loose coupling, on the other hand, can feel untidy. It requires trust. It requires clarity at the boundaries rather than micromanagement at the centre. But when change inevitably comes, the system absorbs it rather than shattering under it.&lt;/p&gt;

&lt;p&gt;Designing for change also demands humility. It means admitting that we do not fully understand the future. It means recognising that our current models are provisional. I have seen teams spend months polishing a grand design, only to discover that real users behave in ways no whiteboard session predicted. Feedback is not an interruption to design. It is design.&lt;/p&gt;

&lt;p&gt;The deeper lesson is human. Systems do not change themselves. People change them. If the people inside a system do not understand it, cannot question it, or are afraid to adjust it, then no amount of architectural elegance will save it. Real adaptability comes from shared understanding, not from tighter control mechanisms.&lt;/p&gt;

&lt;p&gt;There is a difference between clarity and control. Clarity defines purpose, principles, and constraints. Control dictates every action. The former enables autonomy. The latter suffocates it.&lt;/p&gt;

&lt;p&gt;When I think about architecture over time, I see phases. Early on, we optimise for speed. Later, we optimise for stability. Eventually, we must optimise for adaptability. The mistake is assuming one optimisation strategy works forever. It does not. Every stage of growth creates new pressures. The structures that enabled momentum in one phase can quietly inhibit it in the next.&lt;/p&gt;

&lt;p&gt;The irony is that designing for change often results in calmer systems. When flexibility is built in, emergencies decrease. When experimentation is safe, innovation becomes routine rather than disruptive. When failure is expected and contained, it does not escalate into catastrophe.&lt;/p&gt;

&lt;p&gt;Control, by contrast, creates fragility. The tighter we grip, the more dramatic the break when something slips through.&lt;/p&gt;

&lt;p&gt;This does not mean abandoning discipline. Designing for change is not the same as chaos. It requires clear interfaces, explicit assumptions, measurable outcomes, and thoughtful boundaries. It demands observability so that when the system shifts, we can see it. It demands modularity so that change in one area does not infect the whole. It demands continuous reflection so that decisions are revisited rather than fossilised.&lt;/p&gt;

&lt;p&gt;In practice, this means making decisions that are reversible where possible. It means favouring principles over prescriptions. It means documenting intent, not just implementation. It means building teams capable of evolving the system rather than depending on a single architect to guard it.&lt;/p&gt;

&lt;p&gt;Most importantly, it means letting go of the illusion that control equals competence.&lt;/p&gt;

&lt;p&gt;Competence is the ability to adapt.&lt;/p&gt;

&lt;p&gt;When I look back at systems I am proud of, they share a common trait. They survived change. They were not flawless. They were not static. They evolved without collapsing. The decisions within them were not perfect, but they were adjustable.&lt;/p&gt;

&lt;p&gt;That is the standard I aim for now. Not control, but capacity. Not rigidity, but resilience. Not permanence, but progression.&lt;/p&gt;

&lt;p&gt;The tide will always come in. The only real question is whether what we have built can endure its arrival and reshape itself when it does.&lt;/p&gt;

&lt;p&gt;Design for that.&lt;/p&gt;

</description>
      <category>article</category>
      <category>architecture</category>
      <category>backend</category>
      <category>frontend</category>
    </item>
    <item>
      <title>How to write technical posts that survive AI noise</title>
      <dc:creator>Edgar Nahama Alochi</dc:creator>
      <pubDate>Wed, 29 Jul 2026 23:08:29 +0000</pubDate>
      <link>https://dev.to/nahamaalochi/how-to-write-technical-posts-that-survive-ai-noise-875</link>
      <guid>https://dev.to/nahamaalochi/how-to-write-technical-posts-that-survive-ai-noise-875</guid>
      <description>&lt;p&gt;There is a new kind of content pollution on the internet.&lt;/p&gt;

&lt;p&gt;It is clean looking.&lt;br&gt;
It is fast.&lt;br&gt;
It is confident.&lt;br&gt;
It is usually correct in the same way instant noodles are usually a meal.&lt;/p&gt;

&lt;p&gt;You have seen it.&lt;/p&gt;

&lt;p&gt;Twenty posts explaining distributed systems with suspiciously identical examples.&lt;br&gt;
Thirty threads about performance that all end with the same advice about caching.&lt;br&gt;
A flood of technical content that sounds useful until you try to build anything from it and realize you were given a polished summary of someone else’s summary of someone else’s blog post from 2018.&lt;/p&gt;

&lt;p&gt;This is the AI noise era.&lt;/p&gt;

&lt;p&gt;Which is not the same thing as saying AI is bad.&lt;br&gt;
It is not.&lt;br&gt;
It is useful.&lt;br&gt;
It is fast.&lt;br&gt;
It can help good writers think better and move faster.&lt;/p&gt;

&lt;p&gt;But it has changed the publishing environment in one important way.&lt;/p&gt;

&lt;p&gt;Average content is now almost free.&lt;/p&gt;

&lt;p&gt;That means the old strategy of writing a technically correct post with generic advice is no longer enough. If your post can be recreated in six seconds by a prompt and a decent model, your post is competing in a commodity market. Commodity markets are not kind to authors.&lt;/p&gt;

&lt;p&gt;So the question is not how to write more posts.&lt;/p&gt;

&lt;p&gt;The question is how to write technical posts that still matter when everyone can publish instantly.&lt;/p&gt;

&lt;p&gt;The answer is depth.&lt;br&gt;
But not the fake kind.&lt;/p&gt;

&lt;p&gt;Real depth.&lt;/p&gt;

&lt;p&gt;The kind that comes from contact with reality.&lt;/p&gt;

&lt;h3&gt;
  
  
  The first rule is simple
&lt;/h3&gt;

&lt;p&gt;Write from experience before you write from explanation.&lt;/p&gt;

&lt;p&gt;Most technical posts fail because they start with the concept and never arrive at the problem.&lt;/p&gt;

&lt;p&gt;They explain what a thing is.&lt;br&gt;
They list benefits.&lt;br&gt;
They define terms.&lt;br&gt;
They sound educational.&lt;br&gt;
They leave the reader unchanged.&lt;/p&gt;

&lt;p&gt;People do not remember definitions.&lt;br&gt;
They remember tension.&lt;/p&gt;

&lt;p&gt;A post survives AI noise when it begins with something the model cannot fake well on its own.&lt;br&gt;
A real incident.&lt;br&gt;
A painful trade off.&lt;br&gt;
A mistake that cost time.&lt;br&gt;
A decision that looked smart and later failed in production.&lt;br&gt;
A problem that refused to behave the way the docs promised.&lt;/p&gt;

&lt;p&gt;This does not mean every post needs a war story.&lt;/p&gt;

&lt;p&gt;It means every post needs friction.&lt;/p&gt;

&lt;p&gt;If you are writing about retries, do not begin with a textbook explanation of retries.&lt;/p&gt;

&lt;p&gt;Begin with the duplicate payout incident.&lt;br&gt;
Begin with the customer who got charged twice.&lt;br&gt;
Begin with the queue that politely melted your downstream service because you retried immediately and at scale.&lt;br&gt;
Now the reader cares.&lt;/p&gt;

&lt;p&gt;AI can summarize concepts.&lt;br&gt;
It struggles to replace earned judgment.&lt;/p&gt;

&lt;p&gt;That is your advantage.&lt;br&gt;
Use it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Write for people who have to make decisions
&lt;/h3&gt;

&lt;p&gt;A lot of technical writing is written for imaginary readers who have infinite time, full context, and no budget pressure.&lt;/p&gt;

&lt;p&gt;That reader does not exist.&lt;/p&gt;

&lt;p&gt;Real readers are trying to decide something.&lt;/p&gt;

&lt;p&gt;Should we adopt this tool.&lt;br&gt;
Should we refactor this service.&lt;br&gt;
Should we split the database.&lt;br&gt;
Should we introduce a queue.&lt;br&gt;
Should we keep the monolith another year.&lt;br&gt;
Should we trust this benchmark.&lt;br&gt;
Should we hire for this skill.&lt;/p&gt;

&lt;p&gt;If your post does not help someone make a decision, it will be skimmed, bookmarked, and forgotten. Which is a very polite way of saying ignored forever.&lt;/p&gt;

&lt;p&gt;Strong technical posts are decision support documents disguised as articles.&lt;/p&gt;

&lt;p&gt;They help the reader answer questions like these.&lt;/p&gt;

&lt;p&gt;What problem is this actually good at solving.&lt;br&gt;
What does it cost to run in the real world.&lt;br&gt;
What breaks first.&lt;br&gt;
What team maturity is required.&lt;br&gt;
What signs tell me I am too early.&lt;br&gt;
What signs tell me I am already late.&lt;/p&gt;

&lt;p&gt;This is where experience shows.&lt;/p&gt;

&lt;p&gt;A junior writer often explains what is possible.&lt;br&gt;
A seasoned writer explains what is advisable.&lt;/p&gt;

&lt;p&gt;That second one survives.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stop writing encyclopedias
&lt;/h3&gt;

&lt;p&gt;One of the easiest ways to sound intelligent and be useless is to write the complete guide.&lt;/p&gt;

&lt;p&gt;The complete guide is often just a long apology for not making choices.&lt;/p&gt;

&lt;p&gt;It includes everything.&lt;br&gt;
It excludes judgment.&lt;br&gt;
It is impossible to disagree with because it refuses to commit.&lt;/p&gt;

&lt;p&gt;In an AI heavy internet, completeness is no longer a moat.&lt;br&gt;
Machines are very good at exhaustive overviews.&lt;/p&gt;

&lt;p&gt;What they are worse at is useful reduction.&lt;/p&gt;

&lt;p&gt;Readers do not need more information.&lt;br&gt;
They need better compression.&lt;/p&gt;

&lt;p&gt;Write narrower.&lt;br&gt;
Cut harder.&lt;br&gt;
Choose a point of view.&lt;/p&gt;

&lt;p&gt;Not this.&lt;/p&gt;

&lt;p&gt;This article explains everything about observability.&lt;/p&gt;

&lt;p&gt;Write this.&lt;/p&gt;

&lt;p&gt;If your team has fewer than ten engineers, start observability with latency, error rate, and one business metric before buying a dashboard that requires its own onboarding ceremony.&lt;/p&gt;

&lt;p&gt;That sentence has blood pressure.&lt;br&gt;
It has a user.&lt;br&gt;
It has constraints.&lt;br&gt;
It has a recommendation.&lt;br&gt;
Someone can disagree with it.&lt;br&gt;
Good.&lt;br&gt;
Now you are writing.&lt;/p&gt;

&lt;p&gt;A post that survives AI noise usually has a spine.&lt;br&gt;
It stands for something.&lt;/p&gt;

&lt;h3&gt;
  
  
  Originality is not being weird
&lt;/h3&gt;

&lt;p&gt;Many people hear originality and immediately produce chaos.&lt;/p&gt;

&lt;p&gt;No.&lt;br&gt;
That is not originality.&lt;br&gt;
That is just caffeine with formatting.&lt;/p&gt;

&lt;p&gt;Original technical writing is usually familiar truth described with sharper honesty.&lt;/p&gt;

&lt;p&gt;You do not need a revolutionary theory.&lt;br&gt;
You need a real observation stated clearly.&lt;/p&gt;

&lt;p&gt;For example.&lt;/p&gt;

&lt;p&gt;Most teams do not have a scaling problem. They have a coordination problem wearing a scaling costume.&lt;/p&gt;

&lt;p&gt;That is not a new law of physics.&lt;br&gt;
But it is useful.&lt;br&gt;
It is pointed.&lt;br&gt;
It reflects reality many engineers have seen and few say out loud.&lt;/p&gt;

&lt;p&gt;Originality often comes from pattern recognition.&lt;/p&gt;

&lt;p&gt;After enough years, you notice that the same failure keeps returning in different clothes.&lt;br&gt;
Different stack.&lt;br&gt;
Same mistake.&lt;br&gt;
Different logo.&lt;br&gt;
Same organizational issue.&lt;br&gt;
Different tooling.&lt;br&gt;
Same missing ownership.&lt;/p&gt;

&lt;p&gt;Write that pattern down.&lt;/p&gt;

&lt;p&gt;That is the work.&lt;/p&gt;

&lt;p&gt;AI can recombine language.&lt;br&gt;
It cannot easily replace years of noticing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Be specific where it matters and abstract where it helps
&lt;/h3&gt;

&lt;p&gt;This is a craft skill and it changes everything.&lt;/p&gt;

&lt;p&gt;Weak technical posts stay abstract for too long.&lt;br&gt;
Strong ones move between concrete detail and general principle at the right moments.&lt;/p&gt;

&lt;p&gt;If you stay abstract, the post feels airy.&lt;br&gt;
If you stay too concrete, the post becomes a diary entry no one else can use.&lt;/p&gt;

&lt;p&gt;You want both.&lt;/p&gt;

&lt;p&gt;Show the concrete case.&lt;br&gt;
Then extract the principle.&lt;br&gt;
Then show where the principle breaks.&lt;/p&gt;

&lt;p&gt;Example rhythm.&lt;/p&gt;

&lt;p&gt;We moved retries into the worker and accidentally multiplied load during provider degradation.&lt;/p&gt;

&lt;p&gt;The principle is that resilience mechanisms can increase failure pressure if they are not bounded.&lt;/p&gt;

&lt;p&gt;The practical fix was backoff, jitter, idempotency keys, and a hard retry budget tied to business value.&lt;/p&gt;

&lt;p&gt;Now the reader gets story, lesson, and implementation direction in one pass.&lt;/p&gt;

&lt;p&gt;That survives because it teaches more than facts.&lt;br&gt;
It teaches thinking.&lt;/p&gt;

&lt;h3&gt;
  
  
  Explain trade offs like an adult
&lt;/h3&gt;

&lt;p&gt;AI generated technical content often has a familiar smell.&lt;br&gt;
Everything is beneficial.&lt;br&gt;
Every tool is powerful.&lt;br&gt;
Every pattern improves scalability, reliability, developer experience, and perhaps your posture.&lt;/p&gt;

&lt;p&gt;Real systems do not work like that.&lt;/p&gt;

&lt;p&gt;Every technical decision creates winners and losers.&lt;br&gt;
Every abstraction moves complexity somewhere.&lt;br&gt;
Every convenience has a bill.&lt;br&gt;
Usually monthly.&lt;/p&gt;

&lt;p&gt;If you want your writing to survive, be the person who names the bill.&lt;/p&gt;

&lt;p&gt;Do not just say event driven systems improve decoupling.&lt;/p&gt;

&lt;p&gt;Say they also make debugging harder, make data consistency more social than technical, and require teams to care about contracts long after the launch excitement is gone.&lt;/p&gt;

&lt;p&gt;Do not just say microservices improve scalability.&lt;/p&gt;

&lt;p&gt;Say they can improve scaling for parts of the system while making ownership, testing, and incident response dramatically worse if your team structure is still operating like one monolith with more meetings.&lt;/p&gt;

&lt;p&gt;This is what mature readers trust.&lt;/p&gt;

&lt;p&gt;Not optimism.&lt;br&gt;
Calibration.&lt;/p&gt;

&lt;p&gt;A good technical post should feel like advice from someone who has paid for at least one bad decision.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add the things AI usually leaves out
&lt;/h3&gt;

&lt;p&gt;If you compare a lot of human technical writing with AI generated writing, one pattern appears quickly.&lt;/p&gt;

&lt;p&gt;The machine often covers the what and the why.&lt;br&gt;
It is much weaker on the when, the if, and the what happens next.&lt;/p&gt;

&lt;p&gt;That gap is where your writing can become durable.&lt;/p&gt;

&lt;p&gt;Include timing.&lt;/p&gt;

&lt;p&gt;When should a team adopt this.&lt;br&gt;
What stage is too early.&lt;br&gt;
What symptoms suggest readiness.&lt;/p&gt;

&lt;p&gt;Include prerequisites.&lt;/p&gt;

&lt;p&gt;What must already be true for this approach to work.&lt;br&gt;
Team skills.&lt;br&gt;
Operational maturity.&lt;br&gt;
Traffic patterns.&lt;br&gt;
Business constraints.&lt;/p&gt;

&lt;p&gt;Include failure modes.&lt;/p&gt;

&lt;p&gt;How this goes wrong in practice.&lt;br&gt;
What people underestimate.&lt;br&gt;
What breaks during incidents.&lt;br&gt;
What gets expensive quietly.&lt;/p&gt;

&lt;p&gt;Include maintenance reality.&lt;/p&gt;

&lt;p&gt;Who owns it in month nine.&lt;br&gt;
How upgrades happen.&lt;br&gt;
What knowledge becomes concentrated in one person and ruins everyone’s weekend when that person is offline.&lt;/p&gt;

&lt;p&gt;Include reversibility.&lt;/p&gt;

&lt;p&gt;Can the team back out.&lt;br&gt;
How expensive is rollback.&lt;br&gt;
What decisions become sticky.&lt;/p&gt;

&lt;p&gt;These are not decorative details.&lt;br&gt;
They are the difference between technical writing and technical marketing.&lt;/p&gt;

&lt;p&gt;Your readers know the difference, even if they cannot always explain why one felt more trustworthy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use examples that reveal judgment, not just syntax
&lt;/h3&gt;

&lt;p&gt;Code examples are good.&lt;br&gt;
Tiny toy snippets with no context are often not.&lt;/p&gt;

&lt;p&gt;There is a place for syntax teaching, but if the goal is a post that survives noise, examples should do more than compile.&lt;/p&gt;

&lt;p&gt;They should expose design choices.&lt;/p&gt;

&lt;p&gt;Instead of showing only how to implement a retry loop, show why you capped retries at a low number for non critical operations and used a dead letter queue for the rest.&lt;/p&gt;

&lt;p&gt;Instead of showing only a cache wrapper, show how stale data tolerance changes by domain.&lt;br&gt;
A product catalog can tolerate minutes.&lt;br&gt;
A wallet balance cannot.&lt;br&gt;
Now the reader learns architecture, not just code.&lt;/p&gt;

&lt;p&gt;The most valuable examples are the ones that answer the hidden question in every engineer’s mind.&lt;/p&gt;

&lt;p&gt;Yes, but how would you do this in a system that people actually use.&lt;/p&gt;

&lt;p&gt;Write for that question.&lt;/p&gt;

&lt;h3&gt;
  
  
  Make your writing falsifiable
&lt;/h3&gt;

&lt;p&gt;This sounds academic.&lt;br&gt;
It is actually practical.&lt;/p&gt;

&lt;p&gt;A lot of forgettable content survives only because it says nothing testable.&lt;br&gt;
It is all vibes and verbs.&lt;/p&gt;

&lt;p&gt;Robust technical writing makes claims that can be challenged.&lt;/p&gt;

&lt;p&gt;For small teams, adding a service mesh before basic observability usually increases operational complexity faster than it increases reliability.&lt;/p&gt;

&lt;p&gt;That is a claim.&lt;br&gt;
People can debate it.&lt;br&gt;
People can test it against experience.&lt;br&gt;
People can add nuance.&lt;br&gt;
That is healthy.&lt;/p&gt;

&lt;p&gt;When your writing can be disagreed with, it has shape.&lt;br&gt;
When it has shape, it gets remembered.&lt;/p&gt;

&lt;p&gt;Do not hide behind endless caveats.&lt;br&gt;
Yes, context matters.&lt;br&gt;
It always matters.&lt;br&gt;
You still have to say something.&lt;/p&gt;

&lt;p&gt;The job is not to be impossible to criticize.&lt;br&gt;
The job is to be useful enough to risk criticism.&lt;/p&gt;

&lt;h3&gt;
  
  
  Write like a human who has met other humans
&lt;/h3&gt;

&lt;p&gt;There is a strange trend in technical writing where people remove all personality in order to sound serious.&lt;/p&gt;

&lt;p&gt;This usually produces text that sounds like a compliance document explaining a toaster.&lt;/p&gt;

&lt;p&gt;You do not need stand up comedy.&lt;br&gt;
You do need a voice.&lt;/p&gt;

&lt;p&gt;Humour helps because it compresses shared pain.&lt;/p&gt;

&lt;p&gt;Everyone who has maintained a legacy system understands a line like this.&lt;/p&gt;

&lt;p&gt;The code worked perfectly until we looked at it.&lt;/p&gt;

&lt;p&gt;That line does work.&lt;br&gt;
It creates rapport.&lt;br&gt;
It signals experience.&lt;br&gt;
It gives the reader a reason to continue.&lt;/p&gt;

&lt;p&gt;Sarcasm helps too, in controlled doses.&lt;br&gt;
The keyword is controlled.&lt;br&gt;
You are seasoning a meal, not setting the kitchen on fire.&lt;/p&gt;

&lt;p&gt;The goal is not to perform personality.&lt;br&gt;
The goal is to sound like a competent person thinking clearly in public.&lt;/p&gt;

&lt;p&gt;That tone survives because readers can feel the difference between a writer and a generator.&lt;/p&gt;

&lt;h3&gt;
  
  
  Structure matters more now than before
&lt;/h3&gt;

&lt;p&gt;AI noise has trained readers to scan aggressively.&lt;/p&gt;

&lt;p&gt;They are not rude.&lt;br&gt;
They are adapting.&lt;/p&gt;

&lt;p&gt;If your post has no shape, they will leave before your best point appears.&lt;/p&gt;

&lt;p&gt;Give the reader a path.&lt;/p&gt;

&lt;p&gt;Open with tension.&lt;br&gt;
Name the problem.&lt;br&gt;
State the claim.&lt;br&gt;
Walk through reasoning.&lt;br&gt;
Show examples.&lt;br&gt;
Acknowledge trade offs.&lt;br&gt;
End with a practical takeaway.&lt;/p&gt;

&lt;p&gt;Good structure is not decoration.&lt;br&gt;
It is respect.&lt;/p&gt;

&lt;p&gt;It tells the reader you did the sorting before asking for their time.&lt;/p&gt;

&lt;p&gt;A useful test is this.&lt;/p&gt;

&lt;p&gt;If someone reads only your headings and first sentence of each section, do they still learn something meaningful.&lt;/p&gt;

&lt;p&gt;If not, the post may be full of words and low on signal.&lt;/p&gt;

&lt;h3&gt;
  
  
  The strongest moat is lived specificity
&lt;/h3&gt;

&lt;p&gt;There is a type of detail that instantly increases trust.&lt;/p&gt;

&lt;p&gt;Not random detail.&lt;br&gt;
Relevant detail.&lt;/p&gt;

&lt;p&gt;We discovered the issue because checkout success rate dropped while API error rate looked normal, which meant the failure was happening in a dependency path our alerting did not treat as critical.&lt;/p&gt;

&lt;p&gt;That sentence tells me the writer has been inside a real system.&lt;/p&gt;

&lt;p&gt;It tells me they measure the right things.&lt;br&gt;
It tells me they noticed a mismatch.&lt;br&gt;
It tells me the lesson came from operations, not just reading.&lt;/p&gt;

&lt;p&gt;This kind of specificity is hard to mass produce at scale.&lt;br&gt;
Which is exactly why it works.&lt;/p&gt;

&lt;p&gt;If you want durable writing, keep a notebook of incidents, decisions, and mistakes.&lt;br&gt;
Not just outcomes.&lt;br&gt;
Context too.&lt;/p&gt;

&lt;p&gt;What you believed at the time.&lt;br&gt;
What data you had.&lt;br&gt;
What pressure existed.&lt;br&gt;
What trade off you accepted.&lt;br&gt;
What changed your mind.&lt;/p&gt;

&lt;p&gt;That notebook becomes future articles.&lt;br&gt;
More importantly, it becomes evidence.&lt;/p&gt;

&lt;p&gt;Evidence beats volume.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do not fight AI by pretending it does not exist
&lt;/h3&gt;

&lt;p&gt;The winning move is not purity.&lt;br&gt;
It is leverage.&lt;/p&gt;

&lt;p&gt;Use AI for roughing out outlines.&lt;br&gt;
Use it to challenge your blind spots.&lt;br&gt;
Use it to generate counterarguments.&lt;br&gt;
Use it to find gaps in your explanation.&lt;br&gt;
Use it to clean phrasing after the thinking is done.&lt;/p&gt;

&lt;p&gt;But do not outsource judgment.&lt;/p&gt;

&lt;p&gt;If the model writes the core argument and you lightly edit it, you may publish faster.&lt;br&gt;
You will also sound like everyone else publishing faster.&lt;/p&gt;

&lt;p&gt;The right workflow for technical writing now is something like this.&lt;/p&gt;

&lt;p&gt;Think from experience.&lt;br&gt;
Draft from judgment.&lt;br&gt;
Use tools for refinement.&lt;br&gt;
Return with taste.&lt;br&gt;
Cut aggressively.&lt;br&gt;
Add reality.&lt;br&gt;
Publish.&lt;/p&gt;

&lt;p&gt;AI can increase your speed.&lt;br&gt;
Only you can increase your signal.&lt;/p&gt;

&lt;h3&gt;
  
  
  A practical checklist before you publish
&lt;/h3&gt;

&lt;p&gt;Read your draft and ask these questions.&lt;/p&gt;

&lt;p&gt;Is there a real problem in the opening or did I start with generic explanation&lt;/p&gt;

&lt;p&gt;Have I made at least one clear claim that someone could disagree with&lt;/p&gt;

&lt;p&gt;Did I include trade offs or only benefits&lt;/p&gt;

&lt;p&gt;Did I write for a decision maker or for an imaginary student of everything&lt;/p&gt;

&lt;p&gt;Is there a section that could only come from direct experience&lt;/p&gt;

&lt;p&gt;Did I include timing, prerequisites, and failure modes&lt;/p&gt;

&lt;p&gt;Did I reduce the scope enough to be useful&lt;/p&gt;

&lt;p&gt;Does the post sound like me or like a very polite documentation bot&lt;/p&gt;

&lt;p&gt;If the answer to the last one hurts a little, good.&lt;br&gt;
That means the test is working.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final thought
&lt;/h3&gt;

&lt;p&gt;AI noise is not the end of technical writing.&lt;/p&gt;

&lt;p&gt;It is the end of lazy technical writing getting rewarded for existing.&lt;/p&gt;

&lt;p&gt;Which is honestly fair.&lt;/p&gt;

&lt;p&gt;The bar is different now.&lt;br&gt;
Higher in some ways.&lt;br&gt;
Better in others.&lt;/p&gt;

&lt;p&gt;If average content is free, then judgment becomes premium.&lt;br&gt;
If summaries are instant, then lived insight becomes scarce.&lt;br&gt;
If everyone can publish, then the people who last will be the ones who can still say something real.&lt;/p&gt;

&lt;p&gt;Write the post only you can write.&lt;/p&gt;

&lt;p&gt;Not because it is precious.&lt;br&gt;
Because it is useful.&lt;/p&gt;

&lt;p&gt;And useful is still very hard to automate.&lt;/p&gt;

</description>
      <category>article</category>
      <category>ai</category>
      <category>mistakes</category>
    </item>
    <item>
      <title>The Weekend Gold Rush and the Graveyard It Leaves Behind</title>
      <dc:creator>Edgar Nahama Alochi</dc:creator>
      <pubDate>Wed, 29 Jul 2026 04:20:32 +0000</pubDate>
      <link>https://dev.to/nahamaalochi/the-weekend-gold-rush-and-the-graveyard-it-leaves-behind-5a51</link>
      <guid>https://dev.to/nahamaalochi/the-weekend-gold-rush-and-the-graveyard-it-leaves-behind-5a51</guid>
      <description>&lt;p&gt;I have seen this movie before. Several times. The actors change. The soundtrack improves. The promises get louder. The ending stays the same.&lt;/p&gt;

&lt;p&gt;Around 2000 it was this.&lt;/p&gt;

&lt;p&gt;Everyone needs a website. Learn HTML in a weekend.&lt;/p&gt;

&lt;p&gt;Suddenly the internet was full of blinking text, broken navigation, tables inside tables inside more tables, and a mysterious visitor counter at the bottom proudly displaying the number 7. Most of those sites died quietly. Some are still out there, fossilized in forgotten hosting accounts, whispering in Comic Sans.&lt;/p&gt;

&lt;p&gt;Then 2008 arrived.&lt;/p&gt;

&lt;p&gt;Mobile apps are printing money. Just learn iOS development.&lt;/p&gt;

&lt;p&gt;Every developer with a MacBook became a visionary founder. To do lists. Flashlight apps. Another to do list but this one is social. The App Store filled up. So did the graveyard. Turns out shipping version one is easy. Maintaining version twelve while Apple changes everything and users demand perfection is not.&lt;/p&gt;

&lt;p&gt;Then 2015.&lt;/p&gt;

&lt;p&gt;Blockchain will change everything. Smart contracts. Decentralize the world.&lt;/p&gt;

&lt;p&gt;Whitepapers were written. Tokens were minted. Conferences were attended. Most projects never launched. Many quietly shut down. The few that survived did so not because of hype, but because someone somewhere treated it like real engineering instead of a lottery ticket.&lt;/p&gt;

&lt;p&gt;Now it is 2024.&lt;/p&gt;

&lt;p&gt;AI will replace developers. Build a GPT wrapper this weekend. Launch an AI SaaS by Sunday. Retire by Wednesday.&lt;/p&gt;

&lt;p&gt;Result?&lt;/p&gt;

&lt;p&gt;Still loading.&lt;/p&gt;

&lt;p&gt;The pattern is so predictable it should come with documentation.&lt;/p&gt;

&lt;p&gt;First, a new technology emerges. It is genuinely powerful. It solves something real. It unlocks new capability.&lt;/p&gt;

&lt;p&gt;Early adopters see opportunity. They experiment. They struggle. They learn the sharp edges. They build things that actually work.&lt;/p&gt;

&lt;p&gt;Then the get rich quick crowd floods in.&lt;/p&gt;

&lt;p&gt;Tutorials appear. Build X in 30 minutes. Ship your AI startup in a day. Passive income while you sleep.&lt;/p&gt;

&lt;p&gt;Reality, as it always does, shows up uninvited.&lt;/p&gt;

&lt;p&gt;Infrastructure costs are not passive. Hallucinations are not a feature. Latency is not just a vibe. Security matters. Data privacy matters. Customers do not care that you used the latest model if their invoice is wrong.&lt;/p&gt;

&lt;p&gt;Then 90 percent fail. Not because the technology was useless. Because they skipped the fundamentals.&lt;/p&gt;

&lt;p&gt;This is the part that is boring and therefore ignored.&lt;/p&gt;

&lt;p&gt;What actually succeeds is deeply unfashionable.&lt;/p&gt;

&lt;p&gt;People who understand the technology, not just the API.&lt;/p&gt;

&lt;p&gt;People who solve a real problem instead of wrapping a model around a landing page.&lt;/p&gt;

&lt;p&gt;People who build maintainable systems that survive version two.&lt;/p&gt;

&lt;p&gt;People who think about cost before the first viral tweet.&lt;/p&gt;

&lt;p&gt;People who apply engineering principles that worked before the hype cycle and will work long after it.&lt;/p&gt;

&lt;p&gt;Clean architecture still matters.&lt;/p&gt;

&lt;p&gt;Proper error handling still matters.&lt;/p&gt;

&lt;p&gt;Cost management matters even more when your variable expense is a model that charges per token.&lt;/p&gt;

&lt;p&gt;Security matters when your system is literally generating output from user input.&lt;/p&gt;

&lt;p&gt;Testing matters. Monitoring matters. Observability matters. Especially when the output is probabilistic and your users expect determinism.&lt;/p&gt;

&lt;p&gt;And perhaps most controversial of all, talking to customers still matters.&lt;/p&gt;

&lt;p&gt;You cannot prompt engineer your way out of building something nobody wants.&lt;/p&gt;

&lt;p&gt;I am not saying AI is not transformative. It is. It changes what is possible. It changes how we work. It changes the leverage a small team can have.&lt;/p&gt;

&lt;p&gt;What it does not change is the physics of building durable systems.&lt;/p&gt;

&lt;p&gt;After twenty years of watching waves come and go, here is the lesson.&lt;/p&gt;

&lt;p&gt;New technology does not obsolete good engineering.&lt;/p&gt;

&lt;p&gt;It makes it more important.&lt;/p&gt;

&lt;p&gt;Because when the barrier to building drops, the barrier to competing drops with it. When anyone can launch in a weekend, the only thing that differentiates you is depth. Discipline. Taste. Restraint.&lt;/p&gt;

&lt;p&gt;The gold rush is always loud.&lt;/p&gt;

&lt;p&gt;The people who last are usually quiet.&lt;/p&gt;

&lt;p&gt;So the question is simple.&lt;/p&gt;

&lt;p&gt;Are you building for the long term.&lt;/p&gt;

&lt;p&gt;Or are you building for the demo.&lt;/p&gt;

</description>
      <category>casestudy</category>
      <category>ai</category>
      <category>career</category>
      <category>writing</category>
    </item>
    <item>
      <title>Chaos engineering essentials for small teams</title>
      <dc:creator>Edgar Nahama Alochi</dc:creator>
      <pubDate>Tue, 28 Jul 2026 05:58:19 +0000</pubDate>
      <link>https://dev.to/nahamaalochi/chaos-engineering-essentials-for-small-teams-34hd</link>
      <guid>https://dev.to/nahamaalochi/chaos-engineering-essentials-for-small-teams-34hd</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjnr7zas9gf4xor0dtpma.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjnr7zas9gf4xor0dtpma.jpeg" alt="image" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  You do not need Netflix scale to deserve failure
&lt;/h2&gt;

&lt;p&gt;Chaos engineering sounds like something only companies with thousands of microservices and a platform team the size of a small country should care about.&lt;/p&gt;

&lt;p&gt;That is a myth.&lt;/p&gt;

&lt;p&gt;Small teams break in quieter ways.&lt;/p&gt;

&lt;p&gt;A background job silently retries forever.&lt;br&gt;
A webhook endpoint times out and no one notices.&lt;br&gt;
A database connection pool saturates under a traffic spike.&lt;br&gt;
An external payment provider starts returning 502 and your system politely collapses.&lt;/p&gt;

&lt;p&gt;Chaos engineering is not about drama.&lt;br&gt;
It is about humility.&lt;/p&gt;

&lt;p&gt;It is the discipline of admitting your system will fail and choosing to learn that on a Tuesday afternoon instead of during your biggest customer demo.&lt;/p&gt;




&lt;h2&gt;
  
  
  What chaos engineering actually is
&lt;/h2&gt;

&lt;p&gt;It is not random destruction.&lt;br&gt;
It is not breaking production for fun.&lt;br&gt;
It is not deleting databases to prove you are brave.&lt;/p&gt;

&lt;p&gt;Chaos engineering is controlled failure experimentation.&lt;/p&gt;

&lt;p&gt;You form a hypothesis about how your system behaves under stress.&lt;br&gt;
You introduce a small, reversible failure.&lt;br&gt;
You observe.&lt;br&gt;
You learn.&lt;br&gt;
You improve.&lt;/p&gt;

&lt;p&gt;That is it.&lt;/p&gt;

&lt;p&gt;The goal is confidence.&lt;br&gt;
Not coverage.&lt;br&gt;
Not hero stories.&lt;br&gt;
Confidence.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why small teams need it more than big ones
&lt;/h2&gt;

&lt;p&gt;Large companies have redundancy in people.&lt;/p&gt;

&lt;p&gt;You probably do not.&lt;/p&gt;

&lt;p&gt;If one senior engineer is on vacation and the system degrades in a weird way, you do not have a war room. You have Slack messages and mild panic.&lt;/p&gt;

&lt;p&gt;Small teams usually have:&lt;/p&gt;

&lt;p&gt;Limited observability.&lt;br&gt;
Shared infrastructure.&lt;br&gt;
One database doing everything.&lt;br&gt;
A few critical integrations that must work.&lt;br&gt;
Very little operational slack.&lt;/p&gt;

&lt;p&gt;This is exactly the environment where hidden failure modes thrive.&lt;/p&gt;

&lt;p&gt;Chaos engineering for small teams is less about sophistication and more about survival.&lt;/p&gt;




&lt;h2&gt;
  
  
  Essential principle one: start with failure modes, not tools
&lt;/h2&gt;

&lt;p&gt;Before you install anything, answer this question.&lt;/p&gt;

&lt;p&gt;How does this system actually die?&lt;/p&gt;

&lt;p&gt;Not in theory.&lt;br&gt;
In reality.&lt;/p&gt;

&lt;p&gt;Make a simple list.&lt;/p&gt;

&lt;p&gt;What happens if the database becomes slow.&lt;br&gt;
What happens if Redis disappears.&lt;br&gt;
What happens if Stripe times out.&lt;br&gt;
What happens if DNS resolution fails.&lt;br&gt;
What happens if one pod runs out of memory.&lt;br&gt;
What happens if a background worker crashes mid job.&lt;/p&gt;

&lt;p&gt;If you cannot answer these confidently, you have your starting point.&lt;/p&gt;

&lt;p&gt;Chaos begins with thoughtfulness.&lt;/p&gt;




&lt;h2&gt;
  
  
  Essential principle two: write a steady state definition
&lt;/h2&gt;

&lt;p&gt;You cannot detect degradation if you do not define normal.&lt;/p&gt;

&lt;p&gt;What does healthy mean for your system?&lt;/p&gt;

&lt;p&gt;It might be:&lt;/p&gt;

&lt;p&gt;Ninety nine percent of requests complete under 300 milliseconds.&lt;br&gt;
Error rate stays under one percent.&lt;br&gt;
Checkout success rate stays above a defined threshold.&lt;br&gt;
Background jobs do not accumulate beyond a certain depth.&lt;/p&gt;

&lt;p&gt;Write this down.&lt;/p&gt;

&lt;p&gt;Chaos engineering without a steady state definition is just creative vandalism.&lt;/p&gt;




&lt;h2&gt;
  
  
  Essential principle three: start small and reversible
&lt;/h2&gt;

&lt;p&gt;You do not need a chaos platform.&lt;br&gt;
You need discipline.&lt;/p&gt;

&lt;p&gt;Examples a small team can run safely:&lt;/p&gt;

&lt;p&gt;Introduce artificial latency in a single dependency.&lt;br&gt;
Temporarily block outbound traffic to one third party service.&lt;br&gt;
Kill one application instance.&lt;br&gt;
Throttle CPU on a staging node.&lt;br&gt;
Simulate a failed webhook response.&lt;/p&gt;

&lt;p&gt;Do this in staging first.&lt;br&gt;
Then do it in production with tight scope and clear rollback.&lt;/p&gt;

&lt;p&gt;If your heart rate is too high while running the experiment, it is too large.&lt;/p&gt;




&lt;h2&gt;
  
  
  Essential principle four: observability is not optional
&lt;/h2&gt;

&lt;p&gt;If you cannot see it, you cannot learn from it.&lt;/p&gt;

&lt;p&gt;At minimum you need:&lt;/p&gt;

&lt;p&gt;Request latency metrics.&lt;br&gt;
Error rate metrics.&lt;br&gt;
Basic logs with correlation IDs.&lt;br&gt;
Health indicators for external dependencies.&lt;br&gt;
Alerting tied to real user impact, not infrastructure noise.&lt;/p&gt;

&lt;p&gt;Many small teams think they are not ready for chaos engineering.&lt;/p&gt;

&lt;p&gt;In reality they are not ready for ignorance.&lt;/p&gt;

&lt;p&gt;Even basic metrics change everything.&lt;/p&gt;




&lt;h2&gt;
  
  
  Essential principle five: automate the lessons
&lt;/h2&gt;

&lt;p&gt;The point of running experiments is not to feel clever.&lt;/p&gt;

&lt;p&gt;It is to harden the system.&lt;/p&gt;

&lt;p&gt;After every experiment ask:&lt;/p&gt;

&lt;p&gt;Did our alerts trigger.&lt;br&gt;
Did we detect the issue quickly.&lt;br&gt;
Did the system degrade gracefully.&lt;br&gt;
Did users notice.&lt;br&gt;
Did recovery require manual heroics.&lt;/p&gt;

&lt;p&gt;If the answer includes the word hero, you have work to do.&lt;/p&gt;

&lt;p&gt;Add timeouts.&lt;br&gt;
Add circuit breakers.&lt;br&gt;
Add retries with backoff.&lt;br&gt;
Add idempotency.&lt;br&gt;
Add clearer alerts.&lt;br&gt;
Add runbooks.&lt;/p&gt;

&lt;p&gt;Small teams win by building systems that fail predictably.&lt;/p&gt;




&lt;h2&gt;
  
  
  Essential principle six: design for graceful degradation
&lt;/h2&gt;

&lt;p&gt;Perfection is unrealistic.&lt;br&gt;
Grace is achievable.&lt;/p&gt;

&lt;p&gt;If a recommendation service fails, the product page should still load.&lt;br&gt;
If an analytics endpoint times out, the checkout must still complete.&lt;br&gt;
If one payment provider fails, another should take over.&lt;br&gt;
If email delivery fails, the core transaction should still succeed.&lt;/p&gt;

&lt;p&gt;This is architectural thinking.&lt;br&gt;
Chaos engineering simply reveals where you forgot it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Essential principle seven: avoid chaos theater
&lt;/h2&gt;

&lt;p&gt;There is a trap here.&lt;/p&gt;

&lt;p&gt;You can make chaos engineering look impressive.&lt;/p&gt;

&lt;p&gt;Fancy dashboards.&lt;br&gt;
Dramatic experiments.&lt;br&gt;
Big internal presentations.&lt;/p&gt;

&lt;p&gt;None of that matters if your system still collapses under simple pressure.&lt;/p&gt;

&lt;p&gt;For small teams, chaos engineering should feel boring.&lt;/p&gt;

&lt;p&gt;Routine.&lt;br&gt;
Predictable.&lt;br&gt;
Methodical.&lt;/p&gt;

&lt;p&gt;If it feels theatrical, you are optimizing for attention.&lt;/p&gt;




&lt;h2&gt;
  
  
  A practical starter plan for small teams
&lt;/h2&gt;

&lt;p&gt;Here is a calm, realistic roadmap.&lt;/p&gt;

&lt;p&gt;Month one.&lt;br&gt;
Define steady state.&lt;br&gt;
Add missing metrics.&lt;br&gt;
Identify top five failure modes.&lt;/p&gt;

&lt;p&gt;Month two.&lt;br&gt;
Run one controlled experiment in staging.&lt;br&gt;
Improve alerts and logging.&lt;br&gt;
Document findings.&lt;/p&gt;

&lt;p&gt;Month three.&lt;br&gt;
Run one small scoped production experiment.&lt;br&gt;
Fix the weakest resilience gap discovered.&lt;br&gt;
Write a runbook.&lt;/p&gt;

&lt;p&gt;Repeat quarterly.&lt;/p&gt;

&lt;p&gt;You do not need to be aggressive.&lt;br&gt;
You need to be consistent.&lt;/p&gt;




&lt;h2&gt;
  
  
  The uncomfortable truth
&lt;/h2&gt;

&lt;p&gt;Your system is already chaotic.&lt;/p&gt;

&lt;p&gt;You just have not observed it under stress yet.&lt;/p&gt;

&lt;p&gt;Hardware fails.&lt;br&gt;
Networks partition.&lt;br&gt;
Cloud providers degrade.&lt;br&gt;
External APIs rate limit.&lt;br&gt;
Human operators make mistakes.&lt;/p&gt;

&lt;p&gt;Chaos engineering is not introducing instability.&lt;/p&gt;

&lt;p&gt;It is introducing honesty.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;Small teams often optimize for speed.&lt;/p&gt;

&lt;p&gt;Ship fast.&lt;br&gt;
Fix later.&lt;br&gt;
Trust that things will hold.&lt;/p&gt;

&lt;p&gt;Chaos engineering is how you ship fast without gambling.&lt;/p&gt;

&lt;p&gt;It gives you confidence that when reality pushes back, your system bends instead of shatters.&lt;/p&gt;

&lt;p&gt;You do not need scale to practice resilience.&lt;/p&gt;

&lt;p&gt;You need maturity.&lt;/p&gt;

&lt;p&gt;And maturity begins with the courage to ask one simple question.&lt;/p&gt;

&lt;p&gt;What happens if this breaks.&lt;/p&gt;

&lt;p&gt;Then actually finding out.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>systemdesign</category>
      <category>webdev</category>
      <category>software</category>
    </item>
    <item>
      <title>When to refactor vs rewrite</title>
      <dc:creator>Edgar Nahama Alochi</dc:creator>
      <pubDate>Mon, 27 Jul 2026 19:56:55 +0000</pubDate>
      <link>https://dev.to/nahamaalochi/when-to-refactor-vs-rewrite-16j1</link>
      <guid>https://dev.to/nahamaalochi/when-to-refactor-vs-rewrite-16j1</guid>
      <description>&lt;h2&gt;
  
  
  A decision tree for grown engineers
&lt;/h2&gt;

&lt;p&gt;Every engineering team eventually faces the same dramatic sentence.&lt;/p&gt;

&lt;p&gt;We should just rewrite this.&lt;/p&gt;

&lt;p&gt;It is usually said after a bug, a missed deadline, or a moment of emotional exhaustion while reading a file that appears to have been written during a power outage.&lt;/p&gt;

&lt;p&gt;Rewriting feels clean. Refactoring feels responsible.&lt;/p&gt;

&lt;p&gt;One sounds heroic. The other sounds like laundry.&lt;/p&gt;

&lt;p&gt;But this decision is not about emotion. It is about risk, economics, and time.&lt;/p&gt;

&lt;p&gt;Let us walk through it like adults.&lt;/p&gt;




&lt;h2&gt;
  
  
  First question
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does the system work
&lt;/h3&gt;

&lt;p&gt;Not beautifully. Not elegantly. Not in a way that makes you proud.&lt;/p&gt;

&lt;p&gt;Does it work.&lt;/p&gt;

&lt;p&gt;If the system is stable, generating value, and customers depend on it daily, you are not staring at a technical problem. You are staring at a revenue engine.&lt;/p&gt;

&lt;p&gt;Rewriting revenue engines is not bravery. It is surgery.&lt;/p&gt;

&lt;p&gt;Refactor when the system works but hurts.&lt;/p&gt;

&lt;p&gt;Rewrite when the system fundamentally cannot meet current or future requirements.&lt;/p&gt;

&lt;p&gt;If it works and you just dislike the style, close the tab and drink water.&lt;/p&gt;




&lt;h2&gt;
  
  
  Second question
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is the problem structural or local
&lt;/h3&gt;

&lt;p&gt;Local problems are ugly functions, confusing modules, long files, poor naming, duplicated logic.&lt;/p&gt;

&lt;p&gt;Structural problems are incorrect domain models, broken abstractions, wrong architectural boundaries, impossible scaling constraints.&lt;/p&gt;

&lt;p&gt;Refactoring fixes local problems very well.&lt;/p&gt;

&lt;p&gt;Rewriting is justified only when the architecture itself prevents progress.&lt;/p&gt;

&lt;p&gt;If you can improve it piece by piece without stopping delivery, refactor.&lt;/p&gt;

&lt;p&gt;If every small change creates chaos because the foundations are wrong, then you may need a rewrite.&lt;/p&gt;

&lt;p&gt;Be honest here. Most problems are local.&lt;/p&gt;




&lt;h2&gt;
  
  
  Third question
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Do you fully understand the current system
&lt;/h3&gt;

&lt;p&gt;This is where most rewrite projects quietly die.&lt;/p&gt;

&lt;p&gt;If the current system is confusing, that confusion often contains business rules that no one documented.&lt;/p&gt;

&lt;p&gt;Legacy code is frequently a fossil record of production incidents.&lt;/p&gt;

&lt;p&gt;When you rewrite without fully understanding the behavior, you do not create a cleaner system. You create a regression generator.&lt;/p&gt;

&lt;p&gt;If the answer is no, you do not understand it deeply, your first step is not rewrite.&lt;/p&gt;

&lt;p&gt;Your first step is to learn.&lt;/p&gt;

&lt;p&gt;Refactor while learning. Add tests. Document behavior. Shrink uncertainty.&lt;/p&gt;

&lt;p&gt;Rewrite only after you can explain the old system clearly to someone else.&lt;/p&gt;




&lt;h2&gt;
  
  
  Fourth question
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is delivery allowed to slow down
&lt;/h3&gt;

&lt;p&gt;Rewrites consume focus. They create parallel universes. You maintain old and new simultaneously.&lt;/p&gt;

&lt;p&gt;If your company cannot afford slower feature delivery for months, rewriting is fantasy.&lt;/p&gt;

&lt;p&gt;Refactoring allows incremental progress. You improve while shipping.&lt;/p&gt;

&lt;p&gt;If the business needs momentum, refactor.&lt;/p&gt;

&lt;p&gt;If the business is intentionally investing in a platform reset, and everyone understands the cost, then rewrite can be strategic.&lt;/p&gt;

&lt;p&gt;But it must be a business decision, not a developer mood swing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Fifth question
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Are tests strong enough to protect you
&lt;/h3&gt;

&lt;p&gt;Refactoring relies on safety nets.&lt;/p&gt;

&lt;p&gt;If you do not have meaningful tests, refactoring feels dangerous and rewriting feels tempting.&lt;/p&gt;

&lt;p&gt;But here is the uncomfortable truth.&lt;/p&gt;

&lt;p&gt;Rewriting without tests is gambling at a higher table.&lt;/p&gt;

&lt;p&gt;If you cannot confidently change the system today, you will not magically become confident rebuilding it from scratch.&lt;/p&gt;

&lt;p&gt;Invest in tests first.&lt;/p&gt;

&lt;p&gt;The decision becomes clearer once safety exists.&lt;/p&gt;




&lt;h2&gt;
  
  
  Sixth question
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is the pain growing or stable
&lt;/h3&gt;

&lt;p&gt;Some code is ugly but stable. It does its job quietly.&lt;/p&gt;

&lt;p&gt;Other systems become slower, harder to change, and more fragile every quarter.&lt;/p&gt;

&lt;p&gt;If the cost of change is compounding, you are facing architectural debt.&lt;/p&gt;

&lt;p&gt;In that case, continuing to patch may be more expensive than starting fresh.&lt;/p&gt;

&lt;p&gt;If the cost is flat and predictable, refactoring over time is usually sufficient.&lt;/p&gt;

&lt;p&gt;Measure change cost. Do not guess.&lt;/p&gt;




&lt;h2&gt;
  
  
  The practical decision tree
&lt;/h2&gt;

&lt;p&gt;Here is the simplified version.&lt;/p&gt;

&lt;p&gt;Does it work and generate value&lt;br&gt;
Yes&lt;br&gt;
Then prefer refactor&lt;/p&gt;

&lt;p&gt;Does the architecture block critical future goals&lt;br&gt;
Yes&lt;br&gt;
Consider rewrite&lt;/p&gt;

&lt;p&gt;Do you deeply understand current behavior&lt;br&gt;
No&lt;br&gt;
Learn and refactor first&lt;/p&gt;

&lt;p&gt;Can the business tolerate slower delivery&lt;br&gt;
No&lt;br&gt;
Refactor&lt;/p&gt;

&lt;p&gt;Are tests strong&lt;br&gt;
No&lt;br&gt;
Strengthen them before anything dramatic&lt;/p&gt;

&lt;p&gt;Is change cost compounding&lt;br&gt;
Yes&lt;br&gt;
Rewrite might be strategic&lt;/p&gt;

&lt;p&gt;Notice something.&lt;/p&gt;

&lt;p&gt;Rewrite appears only after several gates.&lt;/p&gt;

&lt;p&gt;That is intentional.&lt;/p&gt;




&lt;h2&gt;
  
  
  The emotional trap
&lt;/h2&gt;

&lt;p&gt;Rewriting feels productive because it removes friction instantly.&lt;/p&gt;

&lt;p&gt;You open a new folder. The files are clean. The abstractions are pure. You feel like an architect instead of a mechanic.&lt;/p&gt;

&lt;p&gt;But software is not a painting. It is an evolving system embedded in reality.&lt;/p&gt;

&lt;p&gt;The old code survived production traffic. It contains scar tissue that protects you from repeating mistakes.&lt;/p&gt;

&lt;p&gt;Refactoring respects that history.&lt;/p&gt;

&lt;p&gt;Rewriting erases it.&lt;/p&gt;

&lt;p&gt;Sometimes erasing is necessary. Often it is ego.&lt;/p&gt;




&lt;h2&gt;
  
  
  A healthier pattern
&lt;/h2&gt;

&lt;p&gt;Instead of thinking refactor or rewrite, think in layers.&lt;/p&gt;

&lt;p&gt;Stabilize the existing system with tests.&lt;/p&gt;

&lt;p&gt;Extract boundaries slowly.&lt;/p&gt;

&lt;p&gt;Replace modules behind interfaces.&lt;/p&gt;

&lt;p&gt;Strangle old components with new ones.&lt;/p&gt;

&lt;p&gt;Over time, the system becomes new without a dramatic rewrite event.&lt;/p&gt;

&lt;p&gt;The business never feels a reset. The engineers never freeze progress.&lt;/p&gt;

&lt;p&gt;This is less cinematic. It is also less catastrophic.&lt;/p&gt;




&lt;h2&gt;
  
  
  The uncomfortable conclusion
&lt;/h2&gt;

&lt;p&gt;Most teams do not need rewrites.&lt;/p&gt;

&lt;p&gt;They need discipline.&lt;/p&gt;

&lt;p&gt;They need tests, clearer boundaries, smaller pull requests, and patience.&lt;/p&gt;

&lt;p&gt;Rewrites are rare strategic moves.&lt;/p&gt;

&lt;p&gt;Refactoring is daily engineering.&lt;/p&gt;

&lt;p&gt;If you find yourself wanting to rewrite, ask one final question.&lt;/p&gt;

&lt;p&gt;Am I solving a structural constraint&lt;br&gt;
Or am I trying to escape complexity I have not yet understood&lt;/p&gt;

&lt;p&gt;The answer determines whether you are being an engineer&lt;/p&gt;

&lt;p&gt;Or just emotionally refactoring your feelings.&lt;/p&gt;

</description>
      <category>bestpractices</category>
      <category>systemdesign</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>NASA's Rule of 10: The rules of programing that put flying metal in orbit</title>
      <dc:creator>Edgar Nahama Alochi</dc:creator>
      <pubDate>Sun, 26 Jul 2026 14:00:28 +0000</pubDate>
      <link>https://dev.to/nahamaalochi/nasas-rule-of-10-the-rules-of-programing-that-put-flying-metal-in-orbit-34lb</link>
      <guid>https://dev.to/nahamaalochi/nasas-rule-of-10-the-rules-of-programing-that-put-flying-metal-in-orbit-34lb</guid>
      <description>&lt;h2&gt;
  
  
  The NASA Ten Rules of Programming
&lt;/h2&gt;

&lt;p&gt;My interpretation of these rules with &lt;strong&gt;Golang&lt;/strong&gt; examples.&lt;/p&gt;

&lt;p&gt;NASA did not write these rules to win arguments on the internet.&lt;br&gt;
They wrote them because software failed in ways that were expensive frightening and sometimes irreversible.&lt;/p&gt;

&lt;p&gt;The rules are short. Almost annoyingly so.&lt;br&gt;
That is intentional.&lt;/p&gt;

&lt;p&gt;Each rule is a reminder that complexity is not free and that computers are fast but humans are fragile.&lt;/p&gt;

&lt;p&gt;They helped put flying metals in orbit and manage Voyager 1, the most distant human made object.&lt;/p&gt;

&lt;p&gt;Let’s walk through all ten using Go not because Go is perfect but because it makes these ideas painfully obvious.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1a7yiizhgvn8nms98hzu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1a7yiizhgvn8nms98hzu.png" alt="image" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Rule 1
&lt;/h3&gt;

&lt;p&gt;Restrict all code to very simple control flow&lt;/p&gt;

&lt;p&gt;If your logic requires a mental stack trace to understand it will fail at the worst possible moment.&lt;/p&gt;

&lt;p&gt;Go helps here by being boring on purpose.&lt;/p&gt;

&lt;p&gt;Bad&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nextValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;nextValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple flow is not about fewer lines.&lt;br&gt;
It is about fewer thoughts.&lt;/p&gt;


&lt;h3&gt;
  
  
  Rule 2
&lt;/h3&gt;

&lt;p&gt;Give all loops a fixed upper bound&lt;/p&gt;

&lt;p&gt;Unbounded loops are promises you cannot keep.&lt;/p&gt;

&lt;p&gt;They say trust me this will eventually stop.&lt;br&gt;
NASA does not trust that. Neither should you.&lt;/p&gt;

&lt;p&gt;Bad&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;maxReads&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even when reading streams you can still impose limits.&lt;br&gt;
Timeouts retries counters budgets.&lt;/p&gt;

&lt;p&gt;Infinite loops belong in theory not production.&lt;/p&gt;


&lt;h3&gt;
  
  
  Rule 3
&lt;/h3&gt;

&lt;p&gt;Avoid heap memory allocation after initialization&lt;/p&gt;

&lt;p&gt;This rule scares people because it sounds extreme.&lt;/p&gt;

&lt;p&gt;What it really says is do not allocate memory unpredictably while running critical logic.&lt;/p&gt;

&lt;p&gt;In Go you do not control the heap but you can control when and how you allocate.&lt;/p&gt;

&lt;p&gt;Bad&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Handler&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;NewHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maxSize&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Handler&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Handler&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;maxSize&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not about micro optimization.&lt;br&gt;
It is about predictability.&lt;/p&gt;

&lt;p&gt;The garbage collector is helpful.&lt;br&gt;
It is not magic.&lt;/p&gt;


&lt;h3&gt;
  
  
  Rule 4
&lt;/h3&gt;

&lt;p&gt;Restrict functions to a single purpose&lt;/p&gt;

&lt;p&gt;If a function does more than one thing it lies about its name.&lt;/p&gt;

&lt;p&gt;Bad&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;SaveUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"saved user %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sendEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;SaveUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Side effects should be explicit and separate.&lt;/p&gt;

&lt;p&gt;Small functions fail smaller.&lt;/p&gt;




&lt;h3&gt;
  
  
  Rule 5
&lt;/h3&gt;

&lt;p&gt;Use a minimum of two runtime assertions per function&lt;/p&gt;

&lt;p&gt;This rule is about defending assumptions.&lt;/p&gt;

&lt;p&gt;In Go assertions usually look like early checks.&lt;/p&gt;

&lt;p&gt;Bad&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"division by zero"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assertions are kindness to future readers.&lt;br&gt;
Especially future you at 2am.&lt;/p&gt;


&lt;h3&gt;
  
  
  Rule 6
&lt;/h3&gt;

&lt;p&gt;Declare data objects at the smallest possible scope&lt;/p&gt;

&lt;p&gt;The longer a variable lives the more places it can hurt you.&lt;/p&gt;

&lt;p&gt;Bad&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;compute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;compute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Short lifetimes mean fewer ghosts in the system.&lt;/p&gt;




&lt;h3&gt;
  
  
  Rule 7
&lt;/h3&gt;

&lt;p&gt;Check the return value of all non void functions&lt;/p&gt;

&lt;p&gt;This is the rule Go takes personally.&lt;/p&gt;

&lt;p&gt;Ignoring errors is lying to yourself.&lt;/p&gt;

&lt;p&gt;Bad&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Errors are information.&lt;br&gt;
Discarding them does not make them go away.&lt;/p&gt;


&lt;h3&gt;
  
  
  Rule 8
&lt;/h3&gt;

&lt;p&gt;Limit pointer use&lt;/p&gt;

&lt;p&gt;Pointers increase the number of possible states your program can be in.&lt;/p&gt;

&lt;p&gt;Go uses pointers but discourages pointer gymnastics.&lt;/p&gt;

&lt;p&gt;Bad&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToUpper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToUpper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use pointers when you must not because you can.&lt;/p&gt;




&lt;h3&gt;
  
  
  Rule 9
&lt;/h3&gt;

&lt;p&gt;Compile with all warnings enabled and treat them as errors&lt;/p&gt;

&lt;p&gt;Go does not have warnings.&lt;br&gt;
It simply refuses to compile nonsense.&lt;/p&gt;

&lt;p&gt;Unused variables unused imports unreachable code.&lt;br&gt;
All dead on arrival.&lt;/p&gt;

&lt;p&gt;That is a feature not a limitation.&lt;/p&gt;

&lt;p&gt;If your language allows warnings treat them like failures.&lt;br&gt;
Your future stability depends on it.&lt;/p&gt;


&lt;h3&gt;
  
  
  Rule 10
&lt;/h3&gt;

&lt;p&gt;Use static analysis tools&lt;/p&gt;

&lt;p&gt;Humans miss patterns.&lt;br&gt;
Machines do not get tired.&lt;/p&gt;

&lt;p&gt;In Go this means tools like&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;go vet&lt;/li&gt;
&lt;li&gt;staticcheck&lt;/li&gt;
&lt;li&gt;race detector&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;-race&lt;/span&gt; ./...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These tools are not optional extras.&lt;br&gt;
They are part of the engineering system.&lt;/p&gt;

&lt;p&gt;NASA trusted them with spacecraft.&lt;br&gt;
You can trust them with your backend.&lt;/p&gt;




&lt;h2&gt;
  
  
  The quiet lesson behind the rules
&lt;/h2&gt;

&lt;p&gt;The NASA rules are not about cleverness.&lt;br&gt;
They are about humility.&lt;/p&gt;

&lt;p&gt;They assume that you will forget.&lt;br&gt;
That you will misread.&lt;br&gt;
That you will be interrupted.&lt;/p&gt;

&lt;p&gt;They are written for humans under pressure.&lt;/p&gt;

&lt;p&gt;Go as a language aligns with this philosophy almost accidentally.&lt;br&gt;
Simple syntax explicit errors limited abstraction boring defaults.&lt;/p&gt;

&lt;p&gt;The rules remind us that reliability is not achieved by brilliance.&lt;br&gt;
It is achieved by restraint.&lt;/p&gt;

&lt;p&gt;And restraint scales better than genius ever will.&lt;/p&gt;

</description>
      <category>bestpractices</category>
      <category>go</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>A Small, Annoying Reminder About MySQL, Next.js, and Reality</title>
      <dc:creator>Edgar Nahama Alochi</dc:creator>
      <pubDate>Sat, 25 Jul 2026 20:01:24 +0000</pubDate>
      <link>https://dev.to/nahamaalochi/a-small-annoying-reminder-about-mysql-nextjs-and-reality-2aln</link>
      <guid>https://dev.to/nahamaalochi/a-small-annoying-reminder-about-mysql-nextjs-and-reality-2aln</guid>
      <description>&lt;p&gt;Today's reminder that MySQL will happily let you believe you're doing everything "right" right up until it doesn't.&lt;/p&gt;

&lt;p&gt;I was wiring up a perfectly ordinary paginated query in a Next.js service. Nothing exotic. Prepared statements, placeholders, clean parameter handling. The kind of code you write on autopilot because you've written it a hundred times before.&lt;/p&gt;

&lt;p&gt;And then MySQL reminded me again that it is not PostgreSQL.&lt;/p&gt;

&lt;p&gt;The offending query looked harmless:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;writings&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="k"&gt;OFFSET&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The parameters were validated. Integers only. Floored. Bounded. Safe. Sensible.&lt;/p&gt;

&lt;p&gt;And still: runtime error.&lt;/p&gt;

&lt;p&gt;The cause, as always, is not obvious until you already know it:&lt;/p&gt;

&lt;p&gt;MySQL does not support placeholders for&lt;code&gt;LIMIT&lt;/code&gt; and &lt;code&gt;OFFSET&lt;/code&gt; in prepared statements.&lt;/p&gt;

&lt;p&gt;Not partially. Not "sometimes." Just no.&lt;/p&gt;

&lt;p&gt;This is one of those behaviors that lives in the uncanny valley between "documented" and "constantly forgotten." Every time I switch contexts PostgreSQL to MySQL, ORM generated queries to raw SQL I relearn this the hard way.&lt;/p&gt;

&lt;p&gt;The fix is simple, but mildly infuriating.&lt;/p&gt;

&lt;p&gt;Instead of placeholders, you must interpolate the integers directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;limitInt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;limitNum&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;offsetInt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dataQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
  SELECT *
  FROM writings
  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;whereClause&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
  ORDER BY created_at DESC
  LIMIT &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;limitInt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; OFFSET &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;offsetInt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And yes, this is safe because:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;limitNum&lt;/code&gt; and&lt;code&gt;offset&lt;/code&gt;are validated&lt;br&gt;
Values are clamped and floored&lt;br&gt;
They cannot contain user controlled strings&lt;br&gt;
Only &lt;code&gt;WHERE&lt;/code&gt; clause values remain parameterized&lt;/p&gt;

&lt;p&gt;The resulting query is exactly what MySQL expects:&lt;/p&gt;

&lt;p&gt;text&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;writings&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="k"&gt;OFFSET&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of the version MySQL silently refuses to support:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;writings&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="k"&gt;OFFSET&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not a Next.js problem.&lt;br&gt;
It is not a driver bug.&lt;br&gt;
It is not a configuration issue.&lt;/p&gt;

&lt;p&gt;It is simply one of those MySQL constraints that leaks through abstraction layers and reminds you that SQL dialects are not interchangeable, no matter how much tooling tries to pretend they are.&lt;/p&gt;

&lt;p&gt;The frustrating part isn't the workaround.&lt;br&gt;
The frustrating part is that this failure happens after you've already done the "right" things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prepared statements&lt;/li&gt;
&lt;li&gt;Parameterized queries&lt;/li&gt;
&lt;li&gt;Defensive validation&lt;/li&gt;
&lt;li&gt;Boring, careful code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And yet, you still have to break the pattern carefully, deliberately to satisfy the database.&lt;/p&gt;

&lt;p&gt;The takeaway is not "don't use MySQL."&lt;br&gt;
The takeaway is simpler, and more annoying:&lt;/p&gt;

&lt;p&gt;Always remember which database you are talking to.&lt;/p&gt;

&lt;p&gt;Because the moment you assume uniform behavior across SQL engines, reality will correct you usually in production.&lt;/p&gt;

&lt;p&gt;Fixed.&lt;br&gt;
Again.&lt;/p&gt;

</description>
      <category>database</category>
      <category>sql</category>
      <category>typescript</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Understanding Next.js Page Caching (with a real example)</title>
      <dc:creator>Edgar Nahama Alochi</dc:creator>
      <pubDate>Wed, 22 Jul 2026 23:12:10 +0000</pubDate>
      <link>https://dev.to/nahamaalochi/understanding-nextjs-page-caching-with-a-real-example-10io</link>
      <guid>https://dev.to/nahamaalochi/understanding-nextjs-page-caching-with-a-real-example-10io</guid>
      <description>&lt;p&gt;Caching can be a tricky topic, especially when pages don’t update the way you expect.&lt;br&gt;
I recently ran into an interesting issue while working on the &lt;strong&gt;/writing&lt;/strong&gt; page of my site. Whenever I added or updated articles, the changes did not show immediately. Oddly enough, the individual article pages updated as expected, but the listing page stayed stale.&lt;/p&gt;

&lt;p&gt;After some digging, I realized this was not a bug. It was &lt;strong&gt;Next.js doing exactly what it is supposed to&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  How Next.js caching works
&lt;/h3&gt;

&lt;p&gt;Next.js (App Router) handles &lt;strong&gt;HTML caching at the edge&lt;/strong&gt; in production. For statically prerendered pages, it sets &lt;code&gt;Cache-Control: s-maxage=31536000&lt;/code&gt;, which is one year. This header tells &lt;strong&gt;CDNs and edge caches&lt;/strong&gt; that they can serve the page without re-fetching for a long time. Browser cache headers such as &lt;code&gt;no-cache&lt;/code&gt; do not override this because &lt;code&gt;s-maxage&lt;/code&gt; takes priority for shared caches.&lt;/p&gt;

&lt;p&gt;This explains why the listing page showed stale content while individual article pages, which are either dynamic or use revalidation, updated immediately.&lt;/p&gt;
&lt;h3&gt;
  
  
  How to control caching
&lt;/h3&gt;

&lt;p&gt;Next.js provides a clean way to manage page freshness.&lt;/p&gt;

&lt;p&gt;First, set revalidation for a page. In the page file, for example &lt;code&gt;app/writing/page.tsx&lt;/code&gt;, add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;revalidate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// seconds&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The page is served from cache for 60 seconds. After 60 seconds, the next visitor triggers &lt;strong&gt;background regeneration&lt;/strong&gt;. Visitors continue to get a fast response while the page updates.&lt;/p&gt;

&lt;p&gt;For instant updates after saving content, use on-demand revalidation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;revalidatePath&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/cache&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;revalidatePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/writing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Call this in your article save logic, whether that is a CMS, API route, or webhook, to invalidate the cached page immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key lessons from my experience
&lt;/h3&gt;

&lt;p&gt;Edge caching is powerful, but it can make pages seem stale if revalidation is not configured. Browser cache clearing or changing Nginx headers does not affect HTML caching for statically prerendered pages. The correct place to control page freshness is in the Next.js route itself, not the server or CDN alone.&lt;/p&gt;

&lt;p&gt;By adding a single line of code to the route, I now get the perfect balance: fast cached pages that still update reliably when I add or edit content.&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://nextjs.org/docs/app/guides/self-hosting" rel="noopener noreferrer"&gt;Next.js ISR and Self-hosting&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nextjs.org/docs/app/getting-started/caching-and-revalidating" rel="noopener noreferrer"&gt;Next.js Caching and Revalidation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nextjs.org/docs/pages/api-reference/config-next-config-js/headers" rel="noopener noreferrer"&gt;Next.js Config and Headers&lt;/a&gt;&lt;/p&gt;

</description>
      <category>note</category>
      <category>caching</category>
      <category>frontend</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Making Next.js Behave: Practical Notes on Performance, Architecture, and Not Shooting Yourself</title>
      <dc:creator>Edgar Nahama Alochi</dc:creator>
      <pubDate>Wed, 22 Jul 2026 06:33:08 +0000</pubDate>
      <link>https://dev.to/nahamaalochi/making-nextjs-behave-practical-notes-on-performance-architecture-and-not-shooting-yourself-5h3k</link>
      <guid>https://dev.to/nahamaalochi/making-nextjs-behave-practical-notes-on-performance-architecture-and-not-shooting-yourself-5h3k</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4f17rivfuzw6gzdcbf9d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4f17rivfuzw6gzdcbf9d.png" alt=" " width="598" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next.js is fast by default.&lt;br&gt;
It is also very easy to make slow by accident.&lt;/p&gt;

&lt;p&gt;Most performance problems I see in Next apps are not about React being slow or Vercel being expensive. They come from unclear boundaries, duplicated work, and letting “temporary” decisions live forever.&lt;/p&gt;

&lt;p&gt;These are notes on how to keep a Next.js codebase fast to build, predictable to run, and pleasant to work in.&lt;/p&gt;
&lt;h4&gt;
  
  
  Start by making the codebase legible
&lt;/h4&gt;

&lt;p&gt;Before touching performance tools, make the project understandable.&lt;/p&gt;

&lt;p&gt;If a new developer cannot tell where hooks live, where API logic lives, or where page copy lives within a few minutes, you will pay for that confusion forever.&lt;/p&gt;

&lt;p&gt;A boring structure wins.&lt;/p&gt;

&lt;p&gt;Keep one place for hooks.&lt;br&gt;
One place for shared UI components.&lt;br&gt;
One place for content and metadata.&lt;br&gt;
Thin pages that mostly wire things together.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
  &lt;span class="nx"&gt;dashboard&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
  &lt;span class="nx"&gt;solutions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
  &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
  &lt;span class="nx"&gt;bar&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="nx"&gt;hooks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="nx"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This does not make the app faster at runtime. It makes humans faster. That compounds.&lt;/p&gt;

&lt;h4&gt;
  
  
  DRY is about removing decisions, not saving lines
&lt;/h4&gt;

&lt;p&gt;Duplicated logic forces the reader to make choices.&lt;/p&gt;

&lt;p&gt;Which metadata file is correct.&lt;br&gt;
Which SEO description was updated.&lt;br&gt;
Which API client variation should I use.&lt;/p&gt;

&lt;p&gt;Centralize anything that changes together.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;buildMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MetadataInput&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Metadata&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;openGraph&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;twitter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When every page uses the same builder, you stop worrying about consistency. You trust the system again.&lt;/p&gt;

&lt;p&gt;Trust is performance.&lt;/p&gt;

&lt;h4&gt;
  
  
  Prefer server components until proven otherwise
&lt;/h4&gt;

&lt;p&gt;Client components are easy. They are also expensive.&lt;/p&gt;

&lt;p&gt;Every client component ships JavaScript, runs hydration, and increases build and bundle cost. Use them only when you actually need interactivity.&lt;/p&gt;

&lt;p&gt;If a component does not use state, effects, or browser APIs, keep it on the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No use client. No hydration. Less work.&lt;/p&gt;

&lt;p&gt;You can always move logic client side later. Moving it back is harder.&lt;/p&gt;

&lt;h4&gt;
  
  
  Cache aggressively, but intentionally
&lt;/h4&gt;

&lt;p&gt;Next gives you caching for free, but only if you let it.&lt;/p&gt;

&lt;p&gt;Use fetch with caching semantics instead of rolling your own.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;revalidate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Avoid wrapping everything in dynamic just because something broke once. That turns your app into an expensive SPA with extra steps.&lt;/p&gt;

&lt;p&gt;If something must be dynamic, isolate it. Do not poison the whole page.&lt;/p&gt;

&lt;h4&gt;
  
  
  Keep API clients dumb
&lt;/h4&gt;

&lt;p&gt;Your API client should not know about routing, auth state, or UI behavior. It should send requests and return data.&lt;/p&gt;

&lt;p&gt;Once we added a server proxy, the client became simpler instead of more complex.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/backend/payments&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;include&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No tokens.&lt;br&gt;
No headers.&lt;br&gt;
No branching logic.&lt;/p&gt;

&lt;p&gt;The server handles auth. The client just asks for data.&lt;/p&gt;

&lt;p&gt;This improves security and reduces mental load.&lt;/p&gt;
&lt;h4&gt;
  
  
  Never store tokens in localStorage
&lt;/h4&gt;

&lt;p&gt;It is convenient.&lt;br&gt;
It is also unsafe.&lt;/p&gt;

&lt;p&gt;LocalStorage is readable by any injected script. There is no mitigation once it is compromised.&lt;/p&gt;

&lt;p&gt;If you care about security, use httpOnly cookies and move auth to the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;access_token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;httpOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;secure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yes, it requires more setup. Yes, it is worth it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Reduce build work by deleting code
&lt;/h4&gt;

&lt;p&gt;Most build optimizations come from removing work, not adding tools.&lt;/p&gt;

&lt;p&gt;Things that slow builds quietly:&lt;br&gt;
Duplicated imports&lt;br&gt;
Large client components&lt;br&gt;
Overused dynamic rendering&lt;br&gt;
Unused dependencies&lt;br&gt;
Copy pasted config&lt;/p&gt;

&lt;p&gt;Before reaching for caching layers, ask what the compiler is doing repeatedly that it should not be doing at all.&lt;/p&gt;
&lt;h4&gt;
  
  
  Treat DX issues as real bugs
&lt;/h4&gt;

&lt;p&gt;If a fresh clone does not boot cleanly, that is a bug.&lt;br&gt;
If formatting changes every commit, that is a bug.&lt;br&gt;
If Node versions drift, that is a bug.&lt;/p&gt;

&lt;p&gt;Pin your environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# .nvmrc
20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit generated files that tools expect.&lt;br&gt;
Pick one package manager.&lt;br&gt;
Make the happy path obvious.&lt;/p&gt;

&lt;p&gt;The goal is that nothing surprising happens on day one.&lt;/p&gt;

&lt;h4&gt;
  
  
  Make failures explicit
&lt;/h4&gt;

&lt;p&gt;If the backend is down, fail clearly.&lt;br&gt;
If an image format is unsafe, opt into it intentionally.&lt;br&gt;
If something is deprecated, address it early.&lt;/p&gt;

&lt;p&gt;Silent failures turn into folklore. Loud failures turn into fixes.&lt;/p&gt;

&lt;h4&gt;
  
  
  The real optimization
&lt;/h4&gt;

&lt;p&gt;A fast Next.js app is not one with the most tricks.&lt;br&gt;
It is one that does the least unnecessary work.&lt;br&gt;
For the browser.&lt;br&gt;
For the server.&lt;br&gt;
For the developer.&lt;/p&gt;

&lt;p&gt;When the structure is clear, the build gets faster.&lt;br&gt;
When the security model is clean, the code gets simpler.&lt;br&gt;
When the project explains itself, people stop being afraid to change it.&lt;/p&gt;

&lt;p&gt;That is when Next.js starts to feel boring again.&lt;/p&gt;

&lt;p&gt;And boring is exactly what you want.&lt;/p&gt;

</description>
      <category>note</category>
      <category>caching</category>
      <category>frontend</category>
      <category>mistakes</category>
    </item>
    <item>
      <title>Open Source in the Age of AI: When Slop Floods the Swamp</title>
      <dc:creator>Edgar Nahama Alochi</dc:creator>
      <pubDate>Tue, 21 Jul 2026 09:21:04 +0000</pubDate>
      <link>https://dev.to/nahamaalochi/open-source-in-the-age-of-ai-when-slop-floods-the-swamp-3dp3</link>
      <guid>https://dev.to/nahamaalochi/open-source-in-the-age-of-ai-when-slop-floods-the-swamp-3dp3</guid>
      <description>&lt;p&gt;I like open source for the same reason I like well designed systems.&lt;br&gt;
Clear inputs. Honest outputs. Humans in the loop.&lt;/p&gt;

&lt;p&gt;Lately that loop feels clogged.&lt;/p&gt;

&lt;p&gt;Over the last few weeks something strange has happened. Pull requests multiplied. Bug reports exploded. Security issues appeared out of thin air. Everything looked serious. Everything looked formatted. Everything looked wrong.&lt;/p&gt;

&lt;p&gt;This is not enthusiasm.&lt;br&gt;
This is industrial scale contribution theater.&lt;/p&gt;

&lt;p&gt;We taught machines to talk. Some people decided that talking counts as contributing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F75r5jciwzwgwqx0q791y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F75r5jciwzwgwqx0q791y.png" alt="image" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Inbox as a Crime Scene
&lt;/h2&gt;

&lt;p&gt;If you maintain a project today your inbox looks like a crime scene.&lt;/p&gt;

&lt;p&gt;There are fingerprints everywhere. None of them match reality.&lt;/p&gt;

&lt;p&gt;You open a pull request. It compiles on paper. It fails in practice.&lt;br&gt;
You read a security report. It references functions that do not exist.&lt;br&gt;
You scan the explanation. Confident tone. Wrong universe.&lt;/p&gt;

&lt;p&gt;The tragedy is not that the code is bad. Bad code has always existed.&lt;br&gt;
The tragedy is volume.&lt;/p&gt;

&lt;p&gt;One thoughtful contribution costs minutes to review.&lt;br&gt;
One careless AI generated contribution costs context. Attention. Energy.&lt;/p&gt;

&lt;p&gt;Multiply that by a hundred. By a thousand.&lt;/p&gt;

&lt;p&gt;This is not collaboration. This is a denial of service attack on human judgment.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Slop Factory Model
&lt;/h2&gt;

&lt;p&gt;Here is the new workflow.&lt;/p&gt;

&lt;p&gt;Prompt the model&lt;br&gt;
Generate something plausible&lt;br&gt;
Submit it everywhere&lt;br&gt;
Hope something sticks&lt;/p&gt;

&lt;p&gt;No understanding required. No ownership. No follow up.&lt;/p&gt;

&lt;p&gt;It is the software equivalent of throwing spaghetti at a wall and calling yourself a chef.&lt;/p&gt;

&lt;p&gt;The machine does not care.&lt;br&gt;
The submitter often does not either.&lt;br&gt;
The maintainer pays the bill.&lt;/p&gt;

&lt;p&gt;Open source was built on learning in public.&lt;br&gt;
This is guessing in bulk.&lt;/p&gt;




&lt;h2&gt;
  
  
  When Everything Looks Like Work
&lt;/h2&gt;

&lt;p&gt;AI slop is dangerous because it looks like effort.&lt;/p&gt;

&lt;p&gt;There are tests. There are comments. There are long explanations written in a polite tone.&lt;br&gt;
There is just one missing ingredient.&lt;/p&gt;

&lt;p&gt;Reality.&lt;/p&gt;

&lt;p&gt;The model does not know your codebase.&lt;br&gt;
It does not know your constraints.&lt;br&gt;
It does not know why that weird edge case exists.&lt;/p&gt;

&lt;p&gt;It only knows how code usually looks.&lt;br&gt;
And that is not enough.&lt;/p&gt;

&lt;p&gt;A map of a city is not the city.&lt;br&gt;
Generated code is not understanding.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Maintainer as the Bottleneck
&lt;/h2&gt;

&lt;p&gt;Here is the uncomfortable truth.&lt;/p&gt;

&lt;p&gt;Open source does not scale on code.&lt;br&gt;
It scales on trust.&lt;/p&gt;

&lt;p&gt;Maintainers are not compute. They do not autoscale.&lt;br&gt;
They get tired. They burn out. They leave.&lt;/p&gt;

&lt;p&gt;When you flood a project with low quality contributions you are not helping.&lt;br&gt;
You are converting goodwill into unpaid labor.&lt;/p&gt;

&lt;p&gt;That is why some projects are closing pull requests.&lt;br&gt;
Ending bug bounties.&lt;br&gt;
Banning AI generated submissions outright.&lt;/p&gt;

&lt;p&gt;Not because they hate tools.&lt;br&gt;
Because they value their time.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tools Are Not the Enemy
&lt;/h2&gt;

&lt;p&gt;This is important.&lt;/p&gt;

&lt;p&gt;AI is not the villain.&lt;br&gt;
Misaligned incentives are.&lt;/p&gt;

&lt;p&gt;Used well AI is a sharp knife.&lt;br&gt;
Used badly it is a confetti cannon pointed at a codebase.&lt;/p&gt;

&lt;p&gt;The difference is intent.&lt;/p&gt;

&lt;p&gt;Did you read the code&lt;br&gt;
Did you run it&lt;br&gt;
Do you understand the change&lt;br&gt;
Are you willing to maintain it&lt;/p&gt;

&lt;p&gt;If the answer is no then the contribution is noise regardless of how it was produced.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Open Source Actually Needs
&lt;/h2&gt;

&lt;p&gt;Less volume.&lt;br&gt;
More care.&lt;/p&gt;

&lt;p&gt;Fewer drive by contributions.&lt;br&gt;
More long term thinking.&lt;/p&gt;

&lt;p&gt;AI that helps people understand systems instead of impersonating them.&lt;br&gt;
Contribution guidelines that reward clarity not quantity.&lt;br&gt;
Platforms that protect maintainers instead of optimizing for activity graphs.&lt;/p&gt;

&lt;p&gt;Open source survives on meaning not motion.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Quiet Ending
&lt;/h2&gt;

&lt;p&gt;If we are not careful we will build a future where bots submit to bots and humans quietly walk away.&lt;/p&gt;

&lt;p&gt;Not with anger.&lt;br&gt;
With exhaustion.&lt;/p&gt;

&lt;p&gt;The fix is not dramatic.&lt;br&gt;
It is boring.&lt;br&gt;
It is human.&lt;/p&gt;

&lt;p&gt;Slow down.&lt;br&gt;
Read before you write.&lt;br&gt;
Understand before you submit.&lt;/p&gt;

&lt;p&gt;Because open source was never about how much code you can generate.&lt;/p&gt;

&lt;p&gt;It was about caring enough to make it right.&lt;/p&gt;

</description>
      <category>note</category>
      <category>ai</category>
      <category>bestpractices</category>
      <category>casestudy</category>
    </item>
    <item>
      <title>The Best Line of Code Is the One You Never Write</title>
      <dc:creator>Edgar Nahama Alochi</dc:creator>
      <pubDate>Mon, 20 Jul 2026 22:47:37 +0000</pubDate>
      <link>https://dev.to/nahamaalochi/the-best-line-of-code-is-the-one-you-never-write-1ola</link>
      <guid>https://dev.to/nahamaalochi/the-best-line-of-code-is-the-one-you-never-write-1ola</guid>
      <description>&lt;p&gt;The best line of code is the one you never write.&lt;br&gt;
The second best is the one you delete.&lt;/p&gt;

&lt;p&gt;This isn’t laziness. It’s restraint.&lt;/p&gt;

&lt;p&gt;Every line of code is a liability: something to read, understand, test, debug, maintain, migrate, and eventually explain to someone who didn’t write it, often future you, who will be far less charitable. Less code doesn’t just mean fewer bugs. It means fewer assumptions, fewer hidden contracts, and fewer places for complexity to quietly rot.&lt;/p&gt;

&lt;p&gt;Simple code beats clever code almost every time. Clever code impresses in the moment. Simple code survives. The goal isn’t to be smart. It’s to be clear. Code should explain itself without requiring interpretation or bravado.&lt;/p&gt;

&lt;p&gt;Consider a small example.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clever:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;lo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SumBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;lo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Paid&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Refunded&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Amount&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Discount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works. It is concise. It is also doing filtering, business rules, and calculation in a single expression. Understanding it requires knowing the helper library, the order of operations, and the embedded business logic all at once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Paid&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Refunded&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NetAmount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More lines. Less code.&lt;/p&gt;

&lt;p&gt;The intent is obvious. The loop reads top to bottom. The business rule has a name. There is a clear place to add logging, debugging, or a new condition without fear.&lt;/p&gt;

&lt;p&gt;This is not accidental. Go’s design nudges you toward this style. It makes cleverness slightly uncomfortable and simplicity feel natural, because boring, readable code scales better than impressive code ever will.&lt;/p&gt;

&lt;p&gt;The same principle applies at the system level. Well-designed systems outperform clever ones. Clever systems depend on sustained brilliance and discipline to keep functioning. Well-designed systems depend on structure, constraints, and unremarkable correctness. They do not need heroics to stay stable.&lt;/p&gt;

&lt;p&gt;AI makes this lesson more urgent, not less. Modern tools are extremely good at generating code quickly and confidently. They will happily produce large, intricate solutions to problems that would have been better solved by a simpler model, a tighter constraint, or a deleted requirement. AI optimizes locally. Humans must optimize globally.&lt;/p&gt;

&lt;p&gt;Without global understanding of the domain, the trade-offs, and the long-term cost, code generation turns into code inflation. The risk is not that AI writes bad code. It is that it writes reasonable-looking code that no one fully understands or truly owns.&lt;/p&gt;

&lt;p&gt;Great engineers do not win by typing faster. They win by choosing simplicity over cleverness, design over tricks, and deletion over accumulation.&lt;/p&gt;

&lt;p&gt;Deletion is a design skill.&lt;br&gt;
Omission is an architectural decision.&lt;/p&gt;

&lt;p&gt;In an era where code is cheap, clarity is expensive. That is where real engineering lives.&lt;/p&gt;

&lt;p&gt;Write less. Delete more. Design simply.&lt;/p&gt;

</description>
      <category>note</category>
      <category>ai</category>
      <category>architecture</category>
      <category>bestpractices</category>
    </item>
  </channel>
</rss>
