<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>itsnas.me — Writing</title>
    <link>https://itsnas.me/writing</link>
    <description>Thoughts, tutorials, and engineering notes from real-world projects.</description>
    <language>en</language>
    <lastBuildDate>Wed, 23 Sep 2026 10:00:00 GMT</lastBuildDate>
    <atom:link href="https://itsnas.me/feed.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Instrument a Service with Wide Events</title>
      <link>https://itsnas.me/writing/instrument-a-service-with-wide-events</link>
      <guid isPermaLink="true">https://itsnas.me/writing/instrument-a-service-with-wide-events</guid>
      <pubDate>Wed, 23 Sep 2026 10:00:00 GMT</pubDate>
      <description>You&apos;re about to add logging to a new service, or you&apos;re staring at an existing one where every incident turns into a grep-and-guess session across a dozen disconnected log lines. Replace the step-by-step logs with one wide event per request.</description>
    </item>
    <item>
      <title>Wide Event Logger</title>
      <link>https://itsnas.me/writing/wide-event-logger</link>
      <guid isPermaLink="true">https://itsnas.me/writing/wide-event-logger</guid>
      <pubDate>Wed, 23 Sep 2026 09:30:00 GMT</pubDate>
      <description>A tiny `createEvent(name, seed)` that accumulates fields over the life of a request via `.set()` and emits exactly one structured log line via `.emit()`, so a request that touches ten steps still produces one row instead of ten.</description>
    </item>
    <item>
      <title>Your Logging Sucks!</title>
      <link>https://itsnas.me/writing/your-logging-sucks</link>
      <guid isPermaLink="true">https://itsnas.me/writing/your-logging-sucks</guid>
      <pubDate>Wed, 23 Sep 2026 09:00:00 GMT</pubDate>
      <description>A checkout endpoint with a log line at every step looks like good observability, right up until a customer says &quot;my payment failed&quot; and you have thirteen unrelated lines from thirteen unrelated requests to sort through. The fix isn&apos;t more logs, it&apos;s one wide event per request instead.</description>
    </item>
    <item>
      <title>Cut a Slow N+1 Query Down</title>
      <link>https://itsnas.me/writing/cut-a-slow-n-plus-one-query-down</link>
      <guid isPermaLink="true">https://itsnas.me/writing/cut-a-slow-n-plus-one-query-down</guid>
      <pubDate>Fri, 18 Sep 2026 14:00:00 GMT</pubDate>
      <description>An endpoint that queries once per parent row instead of once per request looks fine with ten rows and falls over with ten thousand. Batch the per-row lookups into one query and the round trips disappear.</description>
    </item>
    <item>
      <title>What Breaks From 1k to 1M Requests Per Second</title>
      <link>https://itsnas.me/writing/what-breaks-1k-to-1m-requests-per-second</link>
      <guid isPermaLink="true">https://itsnas.me/writing/what-breaks-1k-to-1m-requests-per-second</guid>
      <pubDate>Thu, 17 Sep 2026 09:00:00 GMT</pubDate>
      <description>The same endpoint, run through four traffic tiers. At 1k req/s almost any design survives. At 10k the database and the single instance give first. At 100k the cache and the load balancer become the systems under test. At 1M the architecture itself has to change, because the failure mode is no longer capacity, it&apos;s correlated behavior across clients you don&apos;t control.</description>
    </item>
    <item>
      <title>Migrating Schema-Per-Tenant Databases at Scale</title>
      <link>https://itsnas.me/writing/migrating-schema-per-tenant-databases-at-scale</link>
      <guid isPermaLink="true">https://itsnas.me/writing/migrating-schema-per-tenant-databases-at-scale</guid>
      <pubDate>Sat, 12 Sep 2026 15:00:00 GMT</pubDate>
      <description>Choosing physical tenant isolation over a shared, RLS-scoped schema buys two new problems: knowing where a tenant&apos;s data actually lives, and running one migration correctly hundreds of times instead of once. Neither has an app-code fix, both need their own infrastructure.</description>
    </item>
    <item>
      <title>Designing Multi-Tenant APIs That Scale</title>
      <link>https://itsnas.me/writing/designing-multi-tenant-apis-that-scale</link>
      <guid isPermaLink="true">https://itsnas.me/writing/designing-multi-tenant-apis-that-scale</guid>
      <pubDate>Sat, 12 Sep 2026 09:00:00 GMT</pubDate>
      <description>A missing tenant filter is a data leak, not a crash. Row-level security fixes that structurally, but rate limits, connection pools, and error codes built for one instance break the same quiet way once the API runs as several.</description>
    </item>
    <item>
      <title>Why Payment Retries Need Idempotency</title>
      <link>https://itsnas.me/writing/why-payment-retries-need-idempotency</link>
      <guid isPermaLink="true">https://itsnas.me/writing/why-payment-retries-need-idempotency</guid>
      <pubDate>Fri, 11 Sep 2026 09:00:00 GMT</pubDate>
      <description>A plain payment endpoint looks correct until you trace what a double-click, a timed-out request, or a redelivered webhook actually does to it. Each one turns one payment into two. Idempotency keys are the fix, at two layers most write-ups skip.</description>
    </item>
    <item>
      <title>Pick a Rendering Strategy for a Next.js Route</title>
      <link>https://itsnas.me/writing/next-route-rendering-strategy</link>
      <guid isPermaLink="true">https://itsnas.me/writing/next-route-rendering-strategy</guid>
      <pubDate>Tue, 01 Sep 2026 17:30:00 GMT</pubDate>
      <description>An App Router route is prerendered by default and silently turns dynamic the moment you read something request-specific. Knowing which bucket a route belongs in (and what forces it out) is the difference between an instant page and a server render on every hit.</description>
    </item>
    <item>
      <title>Make a Write Endpoint Safely Retryable</title>
      <link>https://itsnas.me/writing/retryable-write-endpoint</link>
      <guid isPermaLink="true">https://itsnas.me/writing/retryable-write-endpoint</guid>
      <pubDate>Tue, 01 Sep 2026 17:00:00 GMT</pubDate>
      <description>A client that retries a POST after a timeout can create the resource twice or charge a card twice. An idempotency key lets the server spot the retry and replay the first response instead of doing the work again.</description>
    </item>
    <item>
      <title>First 15 Minutes of a Prod Incident</title>
      <link>https://itsnas.me/writing/first-15-minutes-of-a-prod-incident</link>
      <guid isPermaLink="true">https://itsnas.me/writing/first-15-minutes-of-a-prod-incident</guid>
      <pubDate>Tue, 01 Sep 2026 16:30:00 GMT</pubDate>
      <description>Something&apos;s on fire in production and you&apos;re the one holding it. Your job for the next fifteen minutes is to shrink the impact and coordinate the response, not to find the root cause.</description>
    </item>
    <item>
      <title>Retry with Backoff &amp; Jitter</title>
      <link>https://itsnas.me/writing/retry-backoff</link>
      <guid isPermaLink="true">https://itsnas.me/writing/retry-backoff</guid>
      <pubDate>Tue, 01 Sep 2026 15:00:00 GMT</pubDate>
      <description>A generic `retry(task, options)` that re-runs a failing async task with exponential backoff and full jitter, an optional `shouldRetry` predicate, and a cap on any single delay.</description>
    </item>
    <item>
      <title>Typed Event Emitter</title>
      <link>https://itsnas.me/writing/typed-event-emitter</link>
      <guid isPermaLink="true">https://itsnas.me/writing/typed-event-emitter</guid>
      <pubDate>Tue, 01 Sep 2026 14:00:00 GMT</pubDate>
      <description>A ~20-line pub/sub where the event names and each event&apos;s payload type come from one map, so `on` and `emit` are fully checked against it and `on` returns its own unsubscribe.</description>
    </item>
    <item>
      <title>assertNever</title>
      <link>https://itsnas.me/writing/assert-never</link>
      <guid isPermaLink="true">https://itsnas.me/writing/assert-never</guid>
      <pubDate>Tue, 01 Sep 2026 13:00:00 GMT</pubDate>
      <description>A one-line helper that makes a `switch` over a discriminated union a compile error the moment a case is added and left unhandled, with a runtime throw as the safety net for data that violated the types at the edges.</description>
    </item>
    <item>
      <title>Result &amp; tryCatch</title>
      <link>https://itsnas.me/writing/result-type</link>
      <guid isPermaLink="true">https://itsnas.me/writing/result-type</guid>
      <pubDate>Tue, 01 Sep 2026 12:00:00 GMT</pubDate>
      <description>A `Result&lt;T, E&gt;` union plus `tryCatch` wrappers that turn a throwing call into a value the caller has to inspect: the failure path becomes part of the return type instead of an invisible jump.</description>
    </item>
    <item>
      <title>useLocalStorage</title>
      <link>https://itsnas.me/writing/use-local-storage</link>
      <guid isPermaLink="true">https://itsnas.me/writing/use-local-storage</guid>
      <pubDate>Tue, 01 Sep 2026 11:00:00 GMT</pubDate>
      <description>A `localStorage`-backed `useState` built on `useSyncExternalStore`: no hydration mismatch under SSR, live updates when another tab writes, and live updates when another hook on the same page writes.</description>
    </item>
    <item>
      <title>useControllableState</title>
      <link>https://itsnas.me/writing/use-controllable-state</link>
      <guid isPermaLink="true">https://itsnas.me/writing/use-controllable-state</guid>
      <pubDate>Tue, 01 Sep 2026 10:00:00 GMT</pubDate>
      <description>One hook that lets a component be driven from outside (`value` + `onChange`) or manage its own state (`defaultValue`), the same two-mode contract a native `&lt;input&gt;` has, while the component body only ever reads one value and calls one setter.</description>
    </item>
    <item>
      <title>A Readable useToggle</title>
      <link>https://itsnas.me/writing/use-toggle</link>
      <guid isPermaLink="true">https://itsnas.me/writing/use-toggle</guid>
      <pubDate>Tue, 01 Sep 2026 09:00:00 GMT</pubDate>
      <description>A boolean `useState` that hands back `on` / `off` / `toggle` instead of a raw setter, so call sites read as intent. Every function, and the controls object itself, stays referentially stable, safe to pass as props or list as effect dependencies without retriggering anything downstream.</description>
    </item>
    <item>
      <title>Keep an AI Agent Grounded While It Builds a Feature</title>
      <link>https://itsnas.me/writing/ai-agent-skills-dev-workflow</link>
      <guid isPermaLink="true">https://itsnas.me/writing/ai-agent-skills-dev-workflow</guid>
      <pubDate>Wed, 26 Aug 2026 18:00:00 GMT</pubDate>
      <description>An AI agent produces plausible, well-formatted code that quietly drifts from what was asked. The fix is a loop with a durable spec: a real GitHub issue the agent must reference, and a two-axis review (standards vs. spec) that runs against it before the PR opens.</description>
    </item>
    <item>
      <title>Building a Typed Fetch Factory</title>
      <link>https://itsnas.me/writing/building-a-typed-fetch-factory</link>
      <guid isPermaLink="true">https://itsnas.me/writing/building-a-typed-fetch-factory</guid>
      <pubDate>Tue, 25 Aug 2026 10:00:00 GMT</pubDate>
      <description>How a single createFetcher factory infers request/response types from an OpenAPI schema and layers in caching, retries, and cancellation, and why each piece is built the way it is.</description>
    </item>
    <item>
      <title>Typed Fetch Factory</title>
      <link>https://itsnas.me/writing/typed-fetch-factory</link>
      <guid isPermaLink="true">https://itsnas.me/writing/typed-fetch-factory</guid>
      <pubDate>Tue, 25 Aug 2026 09:15:00 GMT</pubDate>
      <description>A reusable fetch factory that infers request/response types from an OpenAPI schema and adds in-memory caching, retry with backoff, and AbortController support, no per-endpoint boilerplate, no `any`.</description>
    </item>
    <item>
      <title>Hashing and the Birthday Paradox</title>
      <link>https://itsnas.me/writing/hashing-and-the-birthday-paradox</link>
      <guid isPermaLink="true">https://itsnas.me/writing/hashing-and-the-birthday-paradox</guid>
      <pubDate>Wed, 19 Aug 2026 09:00:00 GMT</pubDate>
      <description>A hash space that looks astronomically large can still produce collisions with a surprisingly small number of items, the same math behind the birthday paradox, applied to hashing.</description>
    </item>
    <item>
      <title>Valid Triangle Number</title>
      <link>https://itsnas.me/writing/valid-triangle-number</link>
      <guid isPermaLink="true">https://itsnas.me/writing/valid-triangle-number</guid>
      <pubDate>Sat, 15 Aug 2026 09:00:00 GMT</pubDate>
      <description>Sort the side lengths, fix the largest one at a time, and let the gap between two pointers count every valid pair against it in one step instead of testing them one by one.</description>
    </item>
    <item>
      <title>3Sum</title>
      <link>https://itsnas.me/writing/3sum</link>
      <guid isPermaLink="true">https://itsnas.me/writing/3sum</guid>
      <pubDate>Fri, 14 Aug 2026 09:00:00 GMT</pubDate>
      <description>Sort the array, fix one value as a moving target, and reuse the exact two-pointer proof from Two Sum II to sweep the rest, with a couple of extra duplicate-skipping rules layered on top.</description>
    </item>
    <item>
      <title>Two Sum II</title>
      <link>https://itsnas.me/writing/two-sum-ii</link>
      <guid isPermaLink="true">https://itsnas.me/writing/two-sum-ii</guid>
      <pubDate>Thu, 13 Aug 2026 09:00:00 GMT</pubDate>
      <description>A sorted array, two pointers closing in from both ends, and a proof that whichever side is off-target can be ruled out entirely rather than retried against a smaller search space.</description>
    </item>
    <item>
      <title>Container With Most Water</title>
      <link>https://itsnas.me/writing/container-with-most-water</link>
      <guid isPermaLink="true">https://itsnas.me/writing/container-with-most-water</guid>
      <pubDate>Wed, 12 Aug 2026 09:00:00 GMT</pubDate>
      <description>A row of walls, two pointers starting at the widest container, and a proof that moving the taller wall can never beat what you already have, so only the shorter side is ever worth moving.</description>
    </item>
    <item>
      <title>Two Pointers</title>
      <link>https://itsnas.me/writing/two-pointers</link>
      <guid isPermaLink="true">https://itsnas.me/writing/two-pointers</guid>
      <pubDate>Tue, 11 Aug 2026 09:00:00 GMT</pubDate>
      <description>Two indices walking through one ordered structure, discarding the side that cannot improve the answer at every step and replacing a nested loop with a single pass.</description>
    </item>
    <item>
      <title>AI Without Losing Judgment</title>
      <link>https://itsnas.me/writing/ai-without-losing-engineering-judgment</link>
      <guid isPermaLink="true">https://itsnas.me/writing/ai-without-losing-engineering-judgment</guid>
      <pubDate>Tue, 17 Mar 2026 09:30:00 GMT</pubDate>
      <description>AI can speed up delivery, but engineers still own architecture, quality, and decisions. A simple workflow to ship faster without outsourcing judgment.</description>
    </item>
    <item>
      <title>Plan for 2026</title>
      <link>https://itsnas.me/writing/plan-for-2026</link>
      <guid isPermaLink="true">https://itsnas.me/writing/plan-for-2026</guid>
      <pubDate>Thu, 01 Jan 2026 00:00:00 GMT</pubDate>
      <description>It&apos;s 2026, and I&apos;m still working as a Senior Software Engineer, setting some ambitious goals for myself and writing about it as tech keeps changing under our feet.</description>
    </item>
    <item>
      <title>Disecting my portfolio</title>
      <link>https://itsnas.me/writing/disecting-my-portfolio</link>
      <guid isPermaLink="true">https://itsnas.me/writing/disecting-my-portfolio</guid>
      <pubDate>Sat, 12 Apr 2025 16:00:00 GMT</pubDate>
      <description>It took me 3 years to build my portfolio. The process was bitter yet rewarding. Learnt many things and adopted good habbits.</description>
    </item>
    <item>
      <title>👋 Hello!</title>
      <link>https://itsnas.me/writing/welcome</link>
      <guid isPermaLink="true">https://itsnas.me/writing/welcome</guid>
      <pubDate>Sun, 06 Apr 2025 14:40:00 GMT</pubDate>
      <description>The name&apos;s Nas. Software Engineer based in UK, with Computer Science degree from King&apos;s College London University.</description>
    </item>
  </channel>
</rss>
