Skip to content
Home

Tags

Every post, snippet, cheatsheet and project — searchable, filterable, and sortable by tag or tool.

  • One Regex Took Down Cloudflare for 27 Minutes

    Post · Oct 12, 2026

    On 2 July 2019 a single new firewall rule took Cloudflare, and a large part of the web with it, offline for 27 minutes. Not an attack, not a hardware failure. How does one rule do that to every server at once?

  • You Don't Need to Store 4 Billion Users to Count Them

    Post · Oct 03, 2026

    Counting unique visitors sounds like a set: add every user id, read its size. At a few billion ids that set is tens of gigabytes, kept only to produce one number. Do you need to remember who visited to count them?

  • How Does Facebook's Distributed Like Counter Work?

    Post · Oct 01, 2026

    A celebrity posts and a million people tap the heart in ten minutes, and every one of them sees a count that seems to keep up. One row with a number in it can't take that. So what does?

  • The Two Egg Drop Problem: Why the Answer Is 14

    Post · Sep 28, 2026

    Two eggs, a 100-floor building, and the fewest drops that are guaranteed to find the floor where eggs start breaking. Binary search is the obvious answer, and it loses badly.

  • Transactional Outbox: Two Systems, One Commit

    Post · Sep 28, 2026

    Save to the database, then publish an event: two lines, two systems, and nothing that makes them agree. What happens when the process dies in between, and why every obvious fix still leaves a gap.

  • Event-Driven Systems: Stop Calling, Start Announcing

    Post · Sep 28, 2026

    A checkout handler that calls the ledger, the warehouse, the email service and analytics in a row is as slow as all of them added together and as fragile as all of them multiplied. And every team that cares about payments makes it a little worse.

  • Two Writes, One Row: Who Wins?

    Post · Sep 26, 2026

    Two requests read the same row, both do their maths, both write back. One of them silently disappears. How the system should resolve that isn't one answer: it depends on whether the write is a delta, a quick piece of logic, or a human edit made minutes after the read.

  • Your Logging Sucks!

    Post · Sep 03, 2026

    Your checkout logs a line at every step, which looks like good observability. Then a customer says their payment failed, and you find out what those logs can't tell you.

  • Same Mistakes, New Framework

    Post · Aug 28, 2026

    A team rewriting its app in this month's framework to fix the speed, a search box whose effects set state that sets more state, and a marketing page that ships more JavaScript than a video game. None of them is fixed by switching tools.

  • What Breaks From 1k to 1M Requests Per Second

    Post · Aug 11, 2026

    One product-page endpoint, the same code, ten times more traffic, then ten times more again. Each step breaks something different, and the last one breaks something extra capacity can't fix.

  • Invert This Binary Tree (For a CRUD Job)

    Post · Aug 05, 2026

    Six rounds, a weekend take-home, and a hard LeetCode problem, all to hire someone who'll spend their first quarter adding fields to a form. Most interview loops test whether you can pass interview loops, and I'd rather test the job.

  • AI Didn't Ship Your Bug, Your LGTM Did

    Post · Jul 30, 2026

    One camp says AI is about to replace engineers. The other ships two hundred generated lines, with tests generated from the same code, on the strength of a Friday LGTM. Both treat the model as the one doing the job, but the model never pressed merge.

  • Migrating Schema-Per-Tenant Databases at Scale

    Post · Jul 24, 2026

    Give each tenant its own schema and you get real isolation. You also get two new problems: knowing where each tenant lives, and running one migration correctly five hundred times instead of once.

  • Designing Multi-Tenant APIs That Scale

    Post · Jul 18, 2026

    One app, many customers, one WHERE clause keeping them apart. Forget it once and nothing crashes: tenant A just sees tenant B's invoices. How to make isolation something the system enforces, not something engineers remember.

  • Why Payment Retries Need Idempotency Keys

    Post · Jul 12, 2026

    You tap your card, the machine freezes, you tap again. Were you charged twice? An HTTP payment endpoint faces the same question on every retry, and without an idempotency key it gets it wrong.

  • Building a Typed Fetch Factory

    Post · May 04, 2026

    Every project grows a hand-rolled fetch wrapper: untyped, half-cached, retried by accident. Here's one built on purpose, with types inferred from an OpenAPI schema and every layer explained.

  • Hashing and the Birthday Paradox

    Post · Apr 22, 2026

    A 32-bit hash has 4.3 billion possible values. How many items can you hash before a collision is a coin flip? Not billions: about 77,000.

  • Valid Triangle Number

    Post · Apr 16, 2026

    Count how many triplets of side lengths can form a triangle. Testing every triple is n³; sorting plus one observation lets a single comparison count a whole batch of triangles at once.

  • 3Sum

    Post · Apr 10, 2026

    Find every triplet that sums to zero, without listing any twice. Three unknowns become two once you fix one, and the hard part turns out to be the duplicates, not the search.

  • Two Sum II

    Post · Apr 05, 2026

    Two pointers on a sorted array finds the pair in one pass. But why is it safe to throw a number away after one bad sum? Draw every pair as a grid and the proof becomes a picture.

  • Container With Most Water

    Post · Mar 30, 2026

    Pick two walls from a row so the water between them is as large as possible. Checking every pair works, but one observation about the shorter wall makes it a single pass.

  • Two Pointers

    Post · Mar 24, 2026

    Checking every pair in an array costs n² comparisons. If the array is sorted, one comparison can rule out a whole row of pairs at once, and the nested loop collapses into a single pass.

  • AI Without Losing Judgment

    Post · Mar 17, 2026

    AI made me ship faster, and for a while it also made me approve code I couldn't defend. Speed isn't progress if nobody owns the decisions.

  • Plan for 2026

    Post · Jan 01, 2026

    It's 2026, and I'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.

  • Dissecting My Portfolio

    Post · Apr 12, 2025

    Three years of starting, stopping and rewriting a personal site. The blocker was never the technology: it was perfectionism dressed up as engineering standards.

  • 👋 Hello!

    Post · Apr 06, 2025

    The name's Nas. Software Engineer based in UK, with Computer Science degree from King's College London University.

  • Keep Your UI Copy in One Place

    Snip · Oct 19, 2026

    All of the site's copy moves out of components into one central file, and components read it through `t('key')`. The keys are typed against that file, so they autocomplete, and a typo or a deleted line fails the type-check instead of shipping blank.

  • Don't Drop Focus When the Button Disappears

    Snip · Oct 17, 2026

    Click "Show all" on a collapsed block and the button unmounts, taking keyboard focus with it: the next Tab starts from the top of the page. `useCollapsible` moves focus to whatever replaced the button.

  • Show More Only When It's Cut Off

    Snip · Oct 17, 2026

    `line-clamp` cuts text off, but it can't tell your JavaScript whether it did, so every short description gets a pointless "Show more". `useOverflow` measures the element and answers that one question.

  • A Flag That Lowers Itself

    Snip · Oct 17, 2026

    A "Copied" tick, a "Saved" badge, a shake on a wrong password: state that should be true for a moment and then go back on its own. `useMomentaryFlag` is that boolean, with the timer handled.

  • Wide Event Logger

    Snip · Sep 09, 2026

    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.

  • Retry with Backoff & Jitter

    Snip · Jun 19, 2026

    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.

  • Typed Event Emitter

    Snip · Jun 13, 2026

    A ~20-line pub/sub where the event names and each event's payload type come from one map, so `on` and `emit` are fully checked against it and `on` returns its own unsubscribe.

  • assertNever

    Snip · Jun 08, 2026

    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.

  • TypeScript Result Type and tryCatch

    Snip · Jun 02, 2026

    A `Result<T, E>` 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.

  • useLocalStorage

    Snip · May 27, 2026

    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.

  • useControllableState

    Snip · May 21, 2026

    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 `<input>` has, while the component body only ever reads one value and calls one setter.

  • A Readable useToggle

    Snip · May 15, 2026

    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.

  • Typed Fetch Factory

    Snip · Apr 28, 2026

    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`.

  • Size a System on the Back of an Envelope

    Cheat · Sep 20, 2026

    The interviewer asks how much traffic you're expecting. Round to powers of ten, turn per-day into per-second, and end every number on the design decision it forces: one node, a cache, or a shard.

  • Instrument a Service with Wide Events

    Cheat · Sep 14, 2026

    You're about to add logging to a new service, or you'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.

  • Cut a Slow N+1 Query Down

    Cheat · Aug 16, 2026

    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.

  • Pick a Rendering Strategy for a Next.js Route

    Cheat · Jul 07, 2026

    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.

  • Make a Write Endpoint Safely Retryable

    Cheat · Jul 01, 2026

    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.

  • First 15 Minutes of a Prod Incident

    Cheat · Jun 25, 2026

    Something's on fire in production and you'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.

  • Keep an AI Agent Grounded While It Builds a Feature

    Cheat · May 09, 2026

    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.

  • Annual Leave Optimiser (external site)

    Project · Oct 08, 2026

    An annual leave optimiser that plans where to spend your holiday days around public holidays and weekends to get the most time off.

  • E-Paper Status Wall

    Project · Sep 20, 2026

    A 31.2 inch monochrome e-paper panel on my living room wall that shows live health and traffic for itsnas.me, so I know the site is fine without opening a single dashboard.

  • From Weekly Releases to Several a Day

    Case study · Sep 01, 2025

    A team of five was releasing a payments frontend weekly off long-lived branches, with no SLOs to say whether a release had actually regressed anything. Moving to trunk-based development with feature flags and Sentry-backed SLOs turned that into several releases a day.

  • Carrying Argentex's Portal Into IFX

    Case study · Jan 13, 2025

    I kicked off IGP's customer-facing portal at Argentex, a greenfield React rebuild, and owned the frontend through the rest of it. After IFX bought IGP, we moved it onto IFX's stack and ran it as ibanq v2 alongside IFX's own v1, migrating clients across cohort by cohort.

  • Personal Portfolio (external site)

    Project · Jan 12, 2025

    A personal portfolio on a monorepo architecture, built around fast page loads, rich MDX content, and reusable UI components.

  • Making TrueLayer's Website Rank and Convert

    Case study · Mar 01, 2022

    Lighthouse hit 95 while real visitors still waited four seconds for the page. What actually fixed it, and roughly quadrupled organic traffic, was never in the lab score.

  • One Design System Across Four Teams

    Case study · Sep 01, 2021

    Four product teams each built their own components, so the brand looked different everywhere. A token-first design system, adopted incrementally through workshops and pairing, reached 90% adoption and cut brand-change rollout from weeks to hours.

  • Getting Customers Through TrueLayer's Consent Flow

    Case study · Jun 01, 2020

    A third of customers who chose pay by bank never finished paying, and most of them were lost inside their own bank's login. App-to-app redirects, a QR hand-off on desktop, a smarter bank picker and a return page that survives a lost session took completion from 64% to 82%.