<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Mike Mwita</title><link>https://mikemwita.com/</link><description>Recent content on Mike Mwita</description><generator>Hugo</generator><language>en</language><copyright>© 2026 Mike Mwita</copyright><lastBuildDate>Sun, 02 Aug 2026 11:00:00 +0300</lastBuildDate><atom:link href="https://mikemwita.com/index.xml" rel="self" type="application/rss+xml"/><item><title>Forget Everything You Know About Time</title><link>https://mikemwita.com/thoughts/forget-everything-you-know-about-time/</link><pubDate>Sun, 02 Aug 2026 11:00:00 +0300</pubDate><guid>https://mikemwita.com/thoughts/forget-everything-you-know-about-time/</guid><description>&lt;p>&lt;span class="dropcap">M&lt;/span>
itch Hedberg had a bit about late-night television:&lt;/p>
&lt;blockquote>
&lt;p>&amp;ldquo;I saw a commercial on late-night TV, it said, &amp;lsquo;Forget everything you know about slipcovers.&amp;rsquo; So I did, and it was a load off my mind. Then the commercial tried to sell me slipcovers, but I didn&amp;rsquo;t know what the hell they were.&amp;rdquo;&lt;/p>
&lt;/blockquote>
&lt;p>So here is my pitch: forget everything you know about time.&lt;/p>
&lt;p>I mean it. Put the intuition down and step away from it. You learned clocks and calendars before you could read, you have used them every single day since, and that fluency is precisely the problem — it is &lt;em>conversational&lt;/em> fluency. It survives on ambiguity, because a human listener quietly patches the gaps for you. A computer will not. It takes your assumption, applies it with total consistency, and hands you back something wrong in a way you never thought to check.&lt;/p></description></item><item><title>Bug #1 — The Clock That Kept Slipping</title><link>https://mikemwita.com/buglog/the-clock-that-kept-slipping/</link><pubDate>Sun, 02 Aug 2026 09:00:00 +0300</pubDate><guid>https://mikemwita.com/buglog/the-clock-that-kept-slipping/</guid><description>&lt;p>&lt;span class="dropcap">I&lt;/span>
 was integrating an external API. The datetime it stamped on every response never agreed with my local clock — and not by a clean, constant amount. Sometimes it was 4 minutes behind. Later, 8. Then more. The gap kept drifting.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span> our clock their timestamp gap
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ─────────────────────────────────────────────
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 10:14 10:10 −4 min
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 11:02 10:54 −8 min
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 13:40 13:29 −11 min
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ↑
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> not a constant — it grows
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="the-wrong-theory">The Wrong Theory&lt;/h2>
&lt;p>My first instinct was that we were sending the wrong value, so I checked the payload. The date was correct. That check cost me time: a timezone shift usually leaves the date component intact and only moves the clock, so a date-only comparison passes while the instant is wrong. The date only flips when the shift crosses midnight — which is why &amp;ldquo;the date is right&amp;rdquo; &lt;em>feels&lt;/em> like evidence and isn&amp;rsquo;t.&lt;/p></description></item><item><title>Beyond Backend Basics</title><link>https://mikemwita.com/thoughts/beyond-the-backend-basics/</link><pubDate>Wed, 07 Jan 2026 13:10:00 +0300</pubDate><guid>https://mikemwita.com/thoughts/beyond-the-backend-basics/</guid><description>&lt;h1 id="beyond-backend-basics">Beyond Backend Basics&lt;/h1>
&lt;p>Most backend developers can build APIs, wire up databases, and scale services.
That’s good. But “good” is not enough if your ambition is to become the kind of engineer who can design &lt;strong>distributed systems that survive chaos&lt;/strong> and influence organizations at scale.&lt;/p>
&lt;p>It’s a checklist of some of the skills you need to learn now if you want to operate at the highest levels of engineering.&lt;/p>
&lt;hr>
&lt;h2 id="from-backend-comfort--distributed-systems-reality">From Backend Comfort → Distributed Systems Reality&lt;/h2>
&lt;p>The leap from backend to distributed systems is not about syntax or frameworks.
It’s about learning to think in terms of &lt;strong>tradeoffs, failures, and coordination across unreliable networks&lt;/strong>.&lt;/p></description></item><item><title>Write Once, Test Everywhere: Sharing Common Tests in Python’s unittest</title><link>https://mikemwita.com/thoughts/unit-test/</link><pubDate>Tue, 21 Oct 2025 07:00:00 +0300</pubDate><guid>https://mikemwita.com/thoughts/unit-test/</guid><description>&lt;p>A while back, I was writing tests for a project using Python’s unittest.
Nothing dramatic — just the usual rhythm: write a class, test it, move to the next one.
After a few classes, though, the déjà vu hit.&lt;/p></description></item><item><title>Generating Go Code from OpenAPI Specification</title><link>https://mikemwita.com/thoughts/generating-go-code-from-openapi/</link><pubDate>Sun, 12 Oct 2025 07:00:00 +0300</pubDate><guid>https://mikemwita.com/thoughts/generating-go-code-from-openapi/</guid><description>&lt;p>A quick and practical walkthrough for developers who want to generate type-safe Go code directly from OpenAPI specs.&lt;/p></description></item><item><title>go-strict</title><link>https://mikemwita.com/projects/go-strict/</link><pubDate>Mon, 18 Mar 2024 00:00:00 +0000</pubDate><guid>https://mikemwita.com/projects/go-strict/</guid><description>&lt;h2 id="motivation">Motivation&lt;/h2>
&lt;p>As Go codebases grow, complexity often hides in deeply nested logic rather than raw line count. Traditional linters catch syntax and style issues but rarely highlight &lt;em>mental load&lt;/em>.&lt;/p>
&lt;p>go-strict was built to quantify cognitive complexity so teams can reason about readability early—before code becomes difficult to maintain or review.&lt;/p>
&lt;h2 id="results">Results&lt;/h2>
&lt;p>The linter analyzes function control flow, nesting, and branching to produce a clear complexity score with file and line references. Output formats are configurable, making it easy to integrate into CI pipelines.&lt;/p></description></item><item><title>FinDocParserPro</title><link>https://mikemwita.com/projects/findoc-parser-pro/</link><pubDate>Wed, 10 Jan 2024 00:00:00 +0000</pubDate><guid>https://mikemwita.com/projects/findoc-parser-pro/</guid><description>&lt;h2 id="motivation">Motivation&lt;/h2>
&lt;p>Financial systems often rely on documents like invoices and receipts that arrive in inconsistent formats and qualities. Many OCR solutions extract raw text but stop short of producing reliable, structured domain data that can be consumed by ERP or accounting systems.&lt;/p>
&lt;p>FinDocParserPro was built to bridge this gap by combining OCR, deterministic extraction rules, and a clean, testable architecture that scales with complexity instead of collapsing under it.&lt;/p>
&lt;h2 id="results">Results&lt;/h2>
&lt;p>The project delivers a robust document ingestion pipeline with clear separation of concerns across Domain, Application, Infrastructure, and API layers. CQRS is implemented without heavyweight dependencies, ensuring clarity and performance.&lt;/p></description></item><item><title>go-bloomfilter</title><link>https://mikemwita.com/projects/go-bloomfilter/</link><pubDate>Thu, 02 Nov 2023 00:00:00 +0000</pubDate><guid>https://mikemwita.com/projects/go-bloomfilter/</guid><description>&lt;h2 id="motivation">Motivation&lt;/h2>
&lt;p>Many backend systems need to answer one question extremely fast: &lt;em>have I seen this before?&lt;/em> Traditional data structures often trade memory for speed, which becomes expensive at scale.&lt;/p>
&lt;p>This project was created to explore probabilistic data structures in Go while gaining hands-on experience with bitwise operations, hashing strategies, and memory-efficient design.&lt;/p>
&lt;h2 id="results">Results&lt;/h2>
&lt;p>The implementation uses a compact &lt;code>[]uint64&lt;/code> bit array with auto-tuned parameters to balance false positives and memory usage. Hashing is inspired by MurmurHash to ensure even distribution and consistent performance.&lt;/p></description></item><item><title>Africa's Talking Go SDK</title><link>https://mikemwita.com/projects/africas-talking-go-sdk/</link><pubDate>Wed, 05 Jul 2023 00:00:00 +0000</pubDate><guid>https://mikemwita.com/projects/africas-talking-go-sdk/</guid><description>&lt;h2 id="motivation">Motivation&lt;/h2>
&lt;p>Africa’s Talking provides powerful communication and payment APIs, but Go developers lacked a cohesive, idiomatic SDK that reduced boilerplate and simplified integrations.&lt;/p>
&lt;p>This project aimed to make building telecom-driven applications in Go as seamless as possible, from quick prototypes to production systems.&lt;/p>
&lt;h2 id="results">Results&lt;/h2>
&lt;p>The SDK offers clean abstractions for SMS, Voice, USSD, Airtime, and Payments with minimal setup. It follows Go conventions closely, enabling predictable usage and easy extensibility.&lt;/p></description></item><item><title>Autores de Hugo</title><link>https://mikemwita.com/autores/autores-de-hugo/</link><pubDate>Thu, 05 Jan 2023 01:15:52 +0100</pubDate><guid>https://mikemwita.com/autores/autores-de-hugo/</guid><description/></item><item><title>temas</title><link>https://mikemwita.com/categoria/temas/</link><pubDate>Wed, 04 Jan 2023 23:21:18 +0100</pubDate><guid>https://mikemwita.com/categoria/temas/</guid><description/></item><item><title>sintaxe</title><link>https://mikemwita.com/categoria/sintaxe/</link><pubDate>Wed, 04 Jan 2023 23:21:06 +0100</pubDate><guid>https://mikemwita.com/categoria/sintaxe/</guid><description/></item><item><title>Códigos curtos</title><link>https://mikemwita.com/tags/shortcodes/_index.pt-br/</link><pubDate>Wed, 04 Jan 2023 11:51:36 +0100</pubDate><guid>https://mikemwita.com/tags/shortcodes/_index.pt-br/</guid><description/></item><item><title>Behavior-Driven Development in Go</title><link>https://mikemwita.com/thoughts/bdd-tests-in-go/</link><pubDate>Tue, 12 May 2020 07:00:22 +0300</pubDate><guid>https://mikemwita.com/thoughts/bdd-tests-in-go/</guid><description>&lt;p>Testing is often seen as a technical safeguard — a way to ensure code correctness.
But what if tests could do more than that?
What if they could express intent, document behavior, and communicate meaning across developers, testers, and product owners alike?&lt;/p></description></item><item><title>Caching Is Easy. Invalidation Is Where Systems Falter.</title><link>https://mikemwita.com/thoughts/cache-invalidation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://mikemwita.com/thoughts/cache-invalidation/</guid><description>&lt;h1 id="caching-is-easy-invalidation-is-where-systems-falter">Caching Is Easy. Invalidation Is Where Systems Falter.&lt;/h1>
&lt;p>Adding a cache is a one-afternoon task. You pick a layer, set a TTL, watch your database load drop. It feels like engineering.&lt;/p>
&lt;p>Invalidation is the part nobody writes down. It is also the part that wakes you up at 3am. Users seeing stale data after an update. A rollback that leaves garbage in cache for 24 hours. A race condition where two services update the same key in the wrong order and nobody notices for a week.&lt;/p></description></item><item><title>Escape Analysis in Go</title><link>https://mikemwita.com/thoughts/escape-analysis-in-go/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://mikemwita.com/thoughts/escape-analysis-in-go/</guid><description/></item><item><title>Flow Control in Distributed Systems: Understanding Backpressure</title><link>https://mikemwita.com/thoughts/understanding-backpressure/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://mikemwita.com/thoughts/understanding-backpressure/</guid><description/></item><item><title>Foreign Function Interfaces (FFI)</title><link>https://mikemwita.com/thoughts/foreign-function-interface/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://mikemwita.com/thoughts/foreign-function-interface/</guid><description/></item><item><title>Hexagonal Architecture in Go</title><link>https://mikemwita.com/thoughts/hexagonal-architecture-in-go/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://mikemwita.com/thoughts/hexagonal-architecture-in-go/</guid><description>&lt;p>&lt;span class="dropcap">M&lt;/span>
ost Go services start out reasonable. A handler calls a database. A function returns a struct. Six months later, your HTTP handler is importing your database package, your database package is calling an external API, and your tests require a live Postgres instance to run a single unit.&lt;/p>
&lt;p>This is not a Go problem. It is an architecture problem — and hexagonal architecture is the structural answer.&lt;aside class="sidenote">Also called &lt;strong>ports and adapters&lt;/strong>, coined by Alistair Cockburn in 2005. The hexagon shape has no special meaning — it just illustrates that an application has multiple sides to connect.&lt;/aside>
&lt;/p></description></item><item><title>Just Use Postgres</title><link>https://mikemwita.com/reads/just_use_postgres/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://mikemwita.com/reads/just_use_postgres/</guid><description>&lt;ul>
&lt;li>PostgreSQL’s source code is overwhelmingly written in C .(Over 85%)&lt;/li>
&lt;/ul></description></item><item><title>Multitenancy Lessons from Slack</title><link>https://mikemwita.com/thoughts/multitenancy-lessons-from-slack/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://mikemwita.com/thoughts/multitenancy-lessons-from-slack/</guid><description>&lt;h1 id="multitenancy-lessons-from-slack">Multitenancy Lessons from Slack&lt;/h1>
&lt;p>Slack looks like a messaging app. Under the hood, it is a multi-tenant distributed system solving problems that every SaaS platform eventually runs into — just at a scale that makes the problems impossible to ignore.&lt;/p>
&lt;p>If you think about it carefully, every architectural decision Slack makes is shaped by one central tension: &lt;strong>every workspace feels isolated, but you cannot afford isolated infrastructure per customer.&lt;/strong>&lt;/p>
&lt;p>That tension is the defining constraint. Everything else — how messages are delivered, how storage is structured, how quotas are enforced — is downstream of it.&lt;/p></description></item><item><title>My Thoughts on Domain-Driven Design in Golang</title><link>https://mikemwita.com/thoughts/domain-driven-design/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://mikemwita.com/thoughts/domain-driven-design/</guid><description>&lt;p>&lt;span class="dropcap">C&lt;/span>
ontrary to what most people think, DDD is not about folder naming. It is not about having directories called &lt;code>domain&lt;/code> and &lt;code>infrastructure&lt;/code> and calling it a day.&lt;/p>
&lt;p>Here is my lightweight approach that helps you think about what your app domain actually is. The concept is straightforward: you see a domain, you create a directory for it. The real value is not in the structure itself — it is in the thinking the structure forces you to do.&lt;/p></description></item><item><title>Reading Flame Graphs in Go</title><link>https://mikemwita.com/thoughts/reading-flame-graphs-in-go/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://mikemwita.com/thoughts/reading-flame-graphs-in-go/</guid><description>&lt;p>&lt;span class="dropcap">I&lt;/span>
nvisible performance bugs are the ones that scale with you. A function that takes 800 nanoseconds at 100 rows and 130 microseconds at 10,000 rows looks fine in every test you write on day one, and quietly becomes the reason a page hangs on day three hundred. You cannot fix what you cannot see — and a guess is not seeing.&lt;/p>
&lt;p>This is a walkthrough of making one such bug visible: write a benchmark, capture a CPU profile, and read the flame graph until the cost stops being a mystery. The example is a real lookup from &lt;a href="https://github.com/MikeMwita/PayMeter">PayMeter&lt;/a>, a small Go payments service, but the workflow is the same for anything.&lt;aside class="sidenote">Everything here uses only the standard toolchain — &lt;code>go test&lt;/code>, &lt;code>go tool pprof&lt;/code>, and Graphviz. No third-party profilers.&lt;/aside>
&lt;/p></description></item><item><title>Root Cause</title><link>https://mikemwita.com/reads/root-cause/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://mikemwita.com/reads/root-cause/</guid><description>&lt;p>Notes and highlights from reading Root Cause by Hussein Nasser — war stories from twenty years of backend bugs, and what each one taught.&lt;/p></description></item><item><title>SQL Doesn't Run in the Order You Write It</title><link>https://mikemwita.com/thoughts/sql-execution-order/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://mikemwita.com/thoughts/sql-execution-order/</guid><description>&lt;p>&lt;span class="dropcap">E&lt;/span>
very developer who has written SQL has made the same mistake at least once: used a &lt;code>SELECT&lt;/code> alias in a &lt;code>WHERE&lt;/code> clause, or tried to filter on an aggregate without &lt;code>HAVING&lt;/code>, and gotten an error that felt completely arbitrary. It is not arbitrary. It is the database telling you that you wrote the query in one order and expected it to execute in that order. It does not.&lt;/p>
&lt;p>Understanding the actual execution order is one of those things that turns SQL from a language you fight into a language you reason with.&lt;/p></description></item><item><title>SQL Performance Explained</title><link>https://mikemwita.com/reads/sql-performance-explained/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://mikemwita.com/reads/sql-performance-explained/</guid><description>&lt;p>Notes and highlights from reading SQL Performance Explained by Markus Winand.&lt;/p></description></item><item><title>That Username Is Taken. How Does Google Know Instantly?</title><link>https://mikemwita.com/thoughts/username-availability-at-scale/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://mikemwita.com/thoughts/username-availability-at-scale/</guid><description>&lt;p>&lt;img alt="Gmail username availability check — &amp;ldquo;newuser&amp;rdquo; is taken, n12205707 is suggested" src="https://mikemwita.com/images/gmail-username-check.png">&lt;/p>
&lt;p>You type &amp;ldquo;newuser&amp;rdquo; into the Gmail signup screen. Already taken. The UI suggests &amp;ldquo;n12205707&amp;rdquo; before you have even stopped typing. No spinner. No network flicker. Just instant.&lt;/p>
&lt;p>You are not doing an Elasticsearch query on every keypress. That would be a crime.&lt;/p>
&lt;p>So how does it work? I want to walk through what I think is the right solution — the math behind it, and why most engineers reach for the wrong tool first.&lt;/p></description></item><item><title>The Pragmatic Programmer</title><link>https://mikemwita.com/reads/the-pragmatic-programmer/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://mikemwita.com/reads/the-pragmatic-programmer/</guid><description>&lt;h2 id="highlights">Highlights&lt;/h2>
&lt;ul>
&lt;li>Don’t live with broken windows&lt;/li>
&lt;li>Make it easy to change&lt;/li>
&lt;li>Build software that can explain itself&lt;/li>
&lt;/ul></description></item><item><title>The Thundering Herd Problem</title><link>https://mikemwita.com/thoughts/cache-stampede/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://mikemwita.com/thoughts/cache-stampede/</guid><description>&lt;h1 id="the-thundering-herd-problem">The Thundering Herd Problem&lt;/h1>
&lt;p>Your site&amp;rsquo;s homepage is heavily cached. The cache key expires every 60 seconds. At 12:00 PM, the cache expires. At 12:00:01 PM, 10,000 concurrent user requests come in. None of them find anything in cache. All 10,000 hit your database simultaneously to regenerate the exact same content.&lt;/p>
&lt;p>Your database crashes. The site goes down.&lt;/p>
&lt;p>This is a &lt;strong>cache stampede&lt;/strong>, also called a thundering herd. The irony is that the cache was there to protect the database. The moment it failed to do its job, it caused something worse than if it had never existed.&lt;/p></description></item><item><title>What It Takes to Be a Real Go Engineer</title><link>https://mikemwita.com/thoughts/what-it-takes-to-be-a-real-go-engineer/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://mikemwita.com/thoughts/what-it-takes-to-be-a-real-go-engineer/</guid><description>&lt;p>&lt;span class="dropcap">M&lt;/span>
ost developers can learn Go&amp;rsquo;s syntax in a weekend. Goroutines, channels, interfaces, error handling — the surface area is deliberately small. That is one of Go&amp;rsquo;s design strengths. It is also the trap.&lt;/p>
&lt;p>The hard parts of Go are invisible in the syntax: knowing &lt;em>when&lt;/em> to reach for concurrency, &lt;em>why&lt;/em> a value is escaping to the heap, &lt;em>what&lt;/em> your goroutines are doing when the load spikes at 3am.&lt;/p>
&lt;aside class="pullquote">
 Syntax is the easy part. Judgment is what production actually tests.
&lt;/aside>

&lt;div class="section-divider">
 &lt;span>&lt;/span>&lt;span>&lt;/span>&lt;span>&lt;/span>
&lt;/div>

&lt;h2 id="concurrency-is-a-tool-not-a-default">Concurrency Is a Tool, Not a Default&lt;/h2>
&lt;p>Go makes concurrency syntactically trivial. That is a feature and a footgun in the same breath. In older systems languages, spawning a thread was expensive and awkward — the friction forced you to think. In Go, you write &lt;code>go&lt;/code> and move on. The language removes the friction. The problem does not.&lt;/p></description></item></channel></rss>