<?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: Nadeem Ur-Rehman</title>
    <description>The latest articles on DEV Community by Nadeem Ur-Rehman (@nurrehman).</description>
    <link>https://dev.to/nurrehman</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%2F839062%2F91f08487-9804-40f7-ac13-b27edad2564b.jpeg</url>
      <title>DEV Community: Nadeem Ur-Rehman</title>
      <link>https://dev.to/nurrehman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nurrehman"/>
    <language>en</language>
    <item>
      <title>Your 'BFF' Is Just a Second Backend With Better Marketing</title>
      <dc:creator>Nadeem Ur-Rehman</dc:creator>
      <pubDate>Fri, 16 Oct 2026 06:59:29 +0000</pubDate>
      <link>https://dev.to/nurrehman/your-bff-is-just-a-second-backend-with-better-marketing-3je5</link>
      <guid>https://dev.to/nurrehman/your-bff-is-just-a-second-backend-with-better-marketing-3je5</guid>
      <description>&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/XTJ6mufbTj8" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Watch the 40-second version: &lt;a href="https://www.youtube.com/shorts/XTJ6mufbTj8" rel="noopener noreferrer"&gt;Backend-for-Frontend Explained for Interviews (Q15/60)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The screen needed five microservice calls to render. Profile from here, orders from there, pricing from somewhere else, and two nobody could explain. So the team did the sensible thing. They built a BFF.&lt;/p&gt;

&lt;p&gt;Six months later the BFF had its own database, its own cron jobs, business logic nobody would claim in a meeting, and an on-call rotation. Congratulations. You did not build a backend-for-frontend. You built a second backend and gave it a frontend pattern's name so nobody would ask questions.&lt;/p&gt;

&lt;p&gt;I have watched this exact movie more than once. It starts with pure intentions. The frontend is chatty, mobile users on bad connections are suffering, so someone stands up a thin aggregation layer. Thin is doing a lot of work in that sentence, because thin is a property of the present. Give it two quarters and thin quietly becomes "well, the logic has to live SOMEWHERE."&lt;/p&gt;

&lt;p&gt;Here is the line interviewers are really testing when they ask where a BFF fits. A BFF has one job: translate the product journey. Aggregate the calls. Shape the payload for the screen. Enforce what this channel is allowed to see. Hide the service topology so the frontend never learns how many services you really have. Domain rules stay in the owning services. The day your BFF starts owning business logic, it stopped being a BFF. Call it what it is and staff it like one.&lt;/p&gt;

&lt;p&gt;The non-obvious part: The BFF's real value is what it deletes. Every round trip your phone does not make on a bad connection is latency your users never feel and a failure mode you never debug at 2 a.m. And if you think one BFF can serve web, mobile, and the partner API, enjoy your new distributed monolith. One channel, one BFF. Shared BFFs drift. It is the same gravity that made the monolith, just with more YAML.&lt;/p&gt;

&lt;p&gt;The 30-second BFF audit. Run this on yours today:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does it own business logic? Move it to the owning service.&lt;/li&gt;
&lt;li&gt;Does it have its own database? Then it is a backend. Rename it honestly.&lt;/li&gt;
&lt;li&gt;Could you rebuild it from the service contracts in a day? If not, it grew roots.&lt;/li&gt;
&lt;li&gt;Does each channel get its own BFF? Shared ones drift into monoliths.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In Angular, the cleanest consumer of a BFF is a route resolver. One call in, and the route does not activate until the screen-shaped payload arrives:&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DashboardResolver&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Resolve&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DashboardVm&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DashboardVm&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// one request out, five service calls hidden behind the BFF&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DashboardVm&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/bff/dashboard&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="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// route: { path: 'dashboard', component: DashboardComponent,&lt;/span&gt;
&lt;span class="c1"&gt;//          resolve: { vm: DashboardResolver } }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Five service calls, one HTTP request, zero business logic in the middle. That is the whole pattern. Keep it boring and it stays a BFF.&lt;/p&gt;

&lt;p&gt;I broke this down in 40 seconds here: &lt;a href="https://www.youtube.com/shorts/XTJ6mufbTj8" rel="noopener noreferrer"&gt;https://www.youtube.com/shorts/XTJ6mufbTj8&lt;/a&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>REST vs GraphQL Is a Judgment Test, Not a Loyalty Test</title>
      <dc:creator>Nadeem Ur-Rehman</dc:creator>
      <pubDate>Thu, 15 Oct 2026 06:57:49 +0000</pubDate>
      <link>https://dev.to/nurrehman/rest-vs-graphql-is-a-judgment-test-not-a-loyalty-test-4hnk</link>
      <guid>https://dev.to/nurrehman/rest-vs-graphql-is-a-judgment-test-not-a-loyalty-test-4hnk</guid>
      <description>&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/FGzszHhXh1g" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Everyone on your team has a strong opinion about REST vs GraphQL, and half of them picked their side in 2019 and never looked back. Here is the war story version: a product page ships, it fires four REST requests to render, the mobile team complains about battery drain, someone "fixes" it by merging everything into one 2MB endpoint, and now every client pays for fields it never reads. Three rewrites later, the frontend team has PTSD and the backend team has trust issues.&lt;/p&gt;

&lt;p&gt;The interview version of this is simpler and crueler. "REST or GraphQL?" is not a loyalty test. It is a judgment test. An interviewer can tell in ten seconds whether you actually chose the contract for a reason, or whether you just memorized a blog post.&lt;/p&gt;

&lt;p&gt;Why it matters more than the framework debate people obsess over: the API contract is the one decision your frontend cannot escape. You can swap a component library in a weekend. You cannot swap your data-fetching contract without touching every screen. Pick wrong and you pay for it in round trips, in over-fetching, and in the kind of performance bugs that only show up on cheap phones your team never tests on.&lt;/p&gt;

&lt;p&gt;The non-obvious angle nobody mentions in interviews: the real cost is rarely bandwidth. It is ownership. GraphQL gives the client query power, which sounds like freedom, until you realize someone has to own query complexity, rate limiting, and cache invalidation for arbitrary queries. REST gives you predictable endpoints, until the fifth client-specific "v2" endpoint exists and nobody knows which ones are safe to kill. The failure mode of GraphQL is a query that quietly costs your database a full-table scan. The failure mode of REST is endpoint sprawl. Pick the failure mode your team is equipped to govern, because you will get the failure either way.&lt;/p&gt;

&lt;p&gt;Here is the decision rule, copy-paste friendly. Run any API through these three checks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Client diversity.&lt;/strong&gt; One web app that you control? REST is probably fine. Web, iOS, Android, and a partner API, all needing different slices of the same data? That is GraphQL territory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Graph tangles.&lt;/strong&gt; If rendering one screen means five sequential round trips for nested data, you have a graph problem and you are solving it with HTTP duct tape. Name the round-trip count out loud in the interview; it is the number that does the talking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost ownership.&lt;/strong&gt; Who pays when the contract is wrong? Over-fetching burns mobile data plans and CDN bills. Under-fetching burns users on 3G. GraphQL kills over-fetching but moves the cost to query governance. REST is cheap to start and expensive to evolve.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The punchline I give in every interview: name the cost or do not spend it. "GraphQL because our three clients need different data shapes and we are willing to own query complexity" is a staff-level answer. "GraphQL because REST is old" is a junior answer with senior confidence.&lt;/p&gt;

&lt;p&gt;I broke this down in 40 seconds here: &lt;a href="https://www.youtube.com/shorts/FGzszHhXh1g" rel="noopener noreferrer"&gt;REST vs GraphQL: How Staff Engineers Choose (Q14/60)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Your Server Rendered Tuesday. Your Client Rendered Wednesday.</title>
      <dc:creator>Nadeem Ur-Rehman</dc:creator>
      <pubDate>Wed, 14 Oct 2026 06:57:56 +0000</pubDate>
      <link>https://dev.to/nurrehman/your-server-rendered-tuesday-your-client-rendered-wednesday-4hlh</link>
      <guid>https://dev.to/nurrehman/your-server-rendered-tuesday-your-client-rendered-wednesday-4hlh</guid>
      <description>&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/3MmFVFFEJxw" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Your server rendered Tuesday. Your client rendered Wednesday. The user saw the page flicker like a haunted television, and somewhere a PM wrote "the page blinks on load" in a bug ticket. That ticket is the interview question. It just showed up in production first.&lt;/p&gt;

&lt;p&gt;A hydration mismatch is simpler than people make it sound. Server-side rendering produces HTML. The client re-renders the same components and compares. If the two outputs disagree, even by one character, React panics and throws the whole server HTML away and re-renders everything client-side. You lose the entire performance win you added SSR for. The user gets a flash, a layout jump, and your careful performance budget goes up in smoke.&lt;/p&gt;

&lt;p&gt;In the interview, "what causes a hydration mismatch" is not a trivia question. It is a filter for "has this person ever shipped SSR to real users." The causes are always the same three. Random values: &lt;code&gt;Math.random()&lt;/code&gt;, &lt;code&gt;Date.now()&lt;/code&gt;, or a UUID generated during render, so the server snapshot and the client snapshot can never agree. Dates: &lt;code&gt;new Date().toLocaleString()&lt;/code&gt; renders in the server's timezone, then re-renders in the browser's timezone, and the two strings disagree by hours. And browser-only APIs: touching &lt;code&gt;window&lt;/code&gt;, &lt;code&gt;localStorage&lt;/code&gt;, or &lt;code&gt;matchMedia&lt;/code&gt; during render throws or returns something different on the server. Every single one of these is the same bug wearing a different hat. Your render function is not deterministic.&lt;/p&gt;

&lt;p&gt;Here is the non-obvious part, and it is the thing that actually scores the interview points. A hydration mismatch is not a framework quirk. It is the framework telling you, bluntly, that your render output depends on something outside the component's inputs. It is a purity check. People treat it like a config problem and slap &lt;code&gt;suppressHydrationWarning&lt;/code&gt; on the element. That prop is a confession, not a fix. It silences the warning while the underlying mismatch still costs you the full client re-render. The right mental model: if a component can disagree with itself across two renders, it will eventually disagree with your users.&lt;/p&gt;

&lt;p&gt;The practical fix is a four-line rule you can apply to any codebase tonight.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Hydration survival rule: the render must be a pure function of props.
// 1. No Math.random(), Date.now(), or UUIDs during render. Move them to useEffect, or seed them from props.
// 2. No browser-only APIs (window, localStorage, matchMedia) during render. Guard behind `typeof window !== "undefined"` or render after mount.
// 3. No locale or timezone-dependent formatting during render. Format in a client-only component, or pass a fixed timezone from the server.
// 4. No conditional rendering that differs between server and client (extension-dependent markup, client-side A/B flags). Resolve it before first render or gate it behind a mounted state.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And for the bonus point that separates seniors from staff: React 18's selective hydration means you do not have to fix the whole page at once. Wrap the unstable part in a Suspense boundary and the framework hydrates around it. Fail small, not everywhere.&lt;/p&gt;

&lt;p&gt;I broke this down in 40 seconds here: &lt;a href="https://www.youtube.com/shorts/3MmFVFFEJxw" rel="noopener noreferrer"&gt;https://www.youtube.com/shorts/3MmFVFFEJxw&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is question 12 of 60 in the Frontend System Design Interview Playbook. The full playbook with all 60 questions is here: &lt;a href="https://bittalk.gumroad.com/l/frontend-interview-playbook" rel="noopener noreferrer"&gt;https://bittalk.gumroad.com/l/frontend-interview-playbook&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
    <item>
      <title>A Decision Nobody Wrote Down Is a Rumor With Consequences</title>
      <dc:creator>Nadeem Ur-Rehman</dc:creator>
      <pubDate>Tue, 13 Oct 2026 06:57:54 +0000</pubDate>
      <link>https://dev.to/nurrehman/a-decision-nobody-wrote-down-is-a-rumor-with-consequences-1k3l</link>
      <guid>https://dev.to/nurrehman/a-decision-nobody-wrote-down-is-a-rumor-with-consequences-1k3l</guid>
      <description>&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/yzKxYk1nWhM" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Watch the 40-second version here: &lt;a href="https://www.youtube.com/shorts/yzKxYk1nWhM" rel="noopener noreferrer"&gt;Architecture Decision Records That Pass Review&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every team has one. The cache TTL set to 47 minutes for reasons lost to time. The "temporary" dependency that is now load-bearing. Ask who decided and you get four names, two of whom left the company last year.&lt;/p&gt;

&lt;p&gt;The decision evaporated. The consequences did not.&lt;/p&gt;

&lt;p&gt;This is why staff-level engineers write Architecture Decision Records. An ADR is one page answering: what did we decide, what did we reject, what are we on the hook for now. Four sections: context, options, decision, consequences. Twenty minutes of writing that outlives every meeting that produced the decision.&lt;/p&gt;

&lt;p&gt;Now the part nobody tells you. The options section is the entire point. A decision with no options section is not a record, it is a press release. "We chose Postgres" teaches the reader nothing without the alternatives. The rejected options are where the actual knowledge lives. Six months later a new hire suggests "why not Mongo" and instead of re-litigating a settled debate, you hand them the ADR. The argument died before it was born.&lt;/p&gt;

&lt;p&gt;Then there is the selfish effect. Undocumented decisions are incident fuel. At 2am nobody can reconstruct why the circuit breaker threshold is 12 and not 50, so they guess. They guess under pressure. ADRs are the difference between debugging the system and reverse-engineering it while the pager screams.&lt;/p&gt;

&lt;p&gt;It also reads well in interviews. Juniors describe what the system does. Staff-level candidates explain what it could have been and why it is not. The answer that lands shows trade-off thinking, and ADRs are trade-off thinking in document form.&lt;/p&gt;

&lt;p&gt;Here is a template you can steal. Save it as docs/adr/001-whatever.md and fill one in today:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# ADR 004: Use React Query for server state&lt;/span&gt;

Date: 2026-10-13
Status: Accepted

&lt;span class="gu"&gt;## Context&lt;/span&gt;
Dashboard refetches on every tab change. Three hand-rolled caches
disagree with each other. Users see stale data; support tickets agree.

&lt;span class="gu"&gt;## Options&lt;/span&gt;
&lt;span class="p"&gt;1.&lt;/span&gt; React Query: battle-tested cache/invalidate, +28KB.
&lt;span class="p"&gt;2.&lt;/span&gt; Custom fetch hook: full control, we own every bug forever.
&lt;span class="p"&gt;3.&lt;/span&gt; Redux + thunks: team knows it, but it is boilerplate city for
   data that is just "load this URL and cache it".

&lt;span class="gu"&gt;## Decision&lt;/span&gt;
React Query. It matches our shape of problem exactly: lots of
reads, few writes, invalidation is the hard part.

&lt;span class="gu"&gt;## Consequences&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Accept: bundle grows ~28KB; team must learn cache keys.
&lt;span class="p"&gt;-&lt;/span&gt; Risk: if we later need offline-first, revisit.
&lt;span class="p"&gt;-&lt;/span&gt; If this proves wrong, ADR 005 supersedes it. ADRs are never edited.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last line matters more than it looks. Never edit an ADR. Supersede it. The history of being wrong is just as valuable as being right.&lt;/p&gt;

&lt;p&gt;Write the decision down today, or future you reverse-engineers it at 2am during an incident. Future you is the reader. Do not make them suffer.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
    <item>
      <title>If Swapping React Meant Rewriting Your App, You Never Had an Architecture</title>
      <dc:creator>Nadeem Ur-Rehman</dc:creator>
      <pubDate>Mon, 12 Oct 2026 06:58:04 +0000</pubDate>
      <link>https://dev.to/nurrehman/if-swapping-react-meant-rewriting-your-app-you-never-had-an-architecture-1dkk</link>
      <guid>https://dev.to/nurrehman/if-swapping-react-meant-rewriting-your-app-you-never-had-an-architecture-1dkk</guid>
      <description>&lt;h1&gt;
  
  
  If Swapping React Meant Rewriting Your App, You Never Had an Architecture
&lt;/h1&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/3-uXNKHeBM8" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Watch the 40-second version: &lt;a href="https://www.youtube.com/shorts/3-uXNKHeBM8" rel="noopener noreferrer"&gt;Q9: Stop Picking Frameworks First in Interviews&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a moment in every system design interview where a candidate leans in and starts their answer with "well, I'd use Next.js for this." And there is a moment, about three seconds later, where the interviewer quietly downgrades the hire signal. That is not a framework debate. That is a smell test, and you just failed it.&lt;/p&gt;

&lt;p&gt;Frameworks are details. Somebody else's details. When you start your architecture from the framework, you are not designing a system. You are decorating one that was already designed for you, by someone who has never met your users. And then one day React deprecates the API half your components are built on, and you discover the truth: you do not have an app with a framework in it. You have a framework with your app trapped inside.&lt;/p&gt;

&lt;p&gt;Here is the part nobody tells you. The interviewer is not testing whether you know the framework. They are testing whether you know where it ends. A candidate who can recite five Next.js caching behaviors but cannot say which components are pure presentation is a candidate who writes business logic inside &lt;code&gt;useEffect&lt;/code&gt; and calls it architecture. I have inherited those codebases. They all read like the same crime novel.&lt;/p&gt;

&lt;p&gt;The fix is boring, which is how you know it works. Think in seams, not stacks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Swap Test (steal this for your next review):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Could you unit-test your core business logic without mounting a single component?&lt;/li&gt;
&lt;li&gt;Is your framework code isolated behind thin adapters, or sprinkled across 40 components like seasoning?&lt;/li&gt;
&lt;li&gt;Do your components contain rules about money and permissions, or only about pixels?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the honest answer to any of those is no, your framework is load-bearing, and load-bearing frameworks are a migration bill with interest.&lt;/p&gt;

&lt;p&gt;A tiny pattern that enforces the seam. Your components should never import a framework-specific API for data work. Wrap it once:&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="c1"&gt;// adapters/http.ts — the ONLY file that knows what fetch wrapper you use&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ApiClient&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// features/checkout/pricing.ts — pure logic, zero framework, testable in isolation&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;applyDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;subtotal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;coupon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Coupon&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;coupon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;subtotal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&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;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;subtotal&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;coupon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&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;&lt;code&gt;pricing.ts&lt;/code&gt; can be tested with node. No DOM, no hooks, no framework. The component renders the number, the adapter moves the bytes. Swap the framework tomorrow and you rewrite the adapters, not the app.&lt;/p&gt;

&lt;p&gt;So next time someone asks how you would architect something, resist the urge to name the stack first. Name the seams. That is what interviewers are actually scoring, and it is the only answer that survives the next framework.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is question 9 of 60 in the Frontend System Design Interview Playbook. The full set of answers, with the ones interviewers actually grade, is here: &lt;a href="https://bittalk.gumroad.com/l/frontend-interview-playbook" rel="noopener noreferrer"&gt;https://bittalk.gumroad.com/l/frontend-interview-playbook&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Your Architecture Isn't Fast Until It Has a Number Attached</title>
      <dc:creator>Nadeem Ur-Rehman</dc:creator>
      <pubDate>Sun, 11 Oct 2026 12:41:42 +0000</pubDate>
      <link>https://dev.to/nurrehman/your-architecture-isnt-fast-until-it-has-a-number-attached-4a5h</link>
      <guid>https://dev.to/nurrehman/your-architecture-isnt-fast-until-it-has-a-number-attached-4a5h</guid>
      <description>&lt;h1&gt;
  
  
  Your Architecture Isn't Fast Until It Has a Number Attached
&lt;/h1&gt;

&lt;p&gt;Every frontend system design interview has a moment where the candidate says "it'll be fast and scalable" and the interviewer's pen does a little dance. Not the good kind of dance. The "zero points, moving on" dance.&lt;/p&gt;

&lt;p&gt;"Fast" is not a design. It is a hope with a logo. The candidate who sounds senior never says fast. They say a number, and then they say what they are deleting to hit it. That second part is the whole game.&lt;/p&gt;

&lt;h2&gt;
  
  
  The performance budget is a negotiation, not a constraint
&lt;/h2&gt;

&lt;p&gt;Most candidates treat performance like a property the architecture magically has. Seniors treat it like a budget they are allowed to spend, which is a completely different mental model. A budget means three things: a number you commit to, a way to measure it, and a list of things you will cut when the meter goes red.&lt;/p&gt;

&lt;p&gt;Walk in with that frame and something weird happens. The interviewer stops testing your component diagram and starts negotiating with you. "What if the carousel breaks the budget?" "Then the carousel ships in phase two and the hero section renders in one paint." That back-and-forth IS the interview. The whiteboard is just the receipt.&lt;/p&gt;

&lt;p&gt;The non-obvious part: the budget makes you faster, not slower. Candidates without a budget draw fifteen boxes and then defend all of them for twenty minutes. Candidates with a budget delete five of their own boxes in the first ten minutes, unprompted, and the interviewer promotes them for it. Nothing impresses a hiring bar like a candidate who volunteers the amputation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 4-line budget card
&lt;/h2&gt;

&lt;p&gt;Here is the entire artifact. Write it in the corner of the whiteboard before you draw anything:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Metric.&lt;/strong&gt; Pick one per surface. LCP for pages, INP for interactions. One.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Budget.&lt;/strong&gt; A number from the world, not your feelings. "2.5s on a mid-range Android over 4G" beats "fast" the way a salary beats "competitive compensation."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Current.&lt;/strong&gt; Your honest estimate after sketching the happy path. You will be wrong. Saying it anyway is the point.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cut list.&lt;/strong&gt; Two or three things you already know you will sacrifice when the number blows: the carousel, the third-party chat widget, the hero video on mobile.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then narrate the ledger out loud as you design. "That adds 80KB of JS, my budget has 170KB, the chat widget is now on the cut list." You are showing the interviewer a working engineer thinking in public. That is the highest-scoring sentence shape in the entire round.&lt;/p&gt;

&lt;h2&gt;
  
  
  A 60-second worked example
&lt;/h2&gt;

&lt;p&gt;Prompt: "Design a social feed that feels instant on a cheap phone."&lt;/p&gt;

&lt;p&gt;Budget: LCP 2.5s on 4G, JS payload 170KB.&lt;/p&gt;

&lt;p&gt;Happy path estimate: skeleton feed at 1.8s, images lazy, 140KB of JS. Under budget. Good.&lt;/p&gt;

&lt;p&gt;Then the interviewer pokes it: "Marketing wants an autoplaying video hero." New estimate: 3.4s, 260KB. Over budget. So you say it out loud: "Video goes to the cut list on mobile. Desktop keeps a muted preview under 100KB. The 2.5s budget survives." You just turned a trap question into a promotion signal in under a minute.&lt;/p&gt;

&lt;p&gt;I turned the full 60-question drill set into The Frontend System Design Interview Playbook ($19): &lt;a href="https://bittalk.gumroad.com/l/frontend-interview-playbook" rel="noopener noreferrer"&gt;https://bittalk.gumroad.com/l/frontend-interview-playbook&lt;/a&gt;. Sixty architect-level questions, the frameworks, the trade-offs, the drills.&lt;/p&gt;

&lt;h2&gt;
  
  
  The closer
&lt;/h2&gt;

&lt;p&gt;The interview is not scored on your diagram. It is scored on the decisions the diagram forced you to make, and whether you made them out loud. A performance budget is just a way to make the decisions visible before anyone asks. Bring the number. Bring the meter. Bring the list of things you are willing to kill. That is what senior sounds like.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>career</category>
    </item>
    <item>
      <title>Build vs Buy Is the Wrong Question. Staff Engineers Ask This Instead.</title>
      <dc:creator>Nadeem Ur-Rehman</dc:creator>
      <pubDate>Sun, 11 Oct 2026 06:58:03 +0000</pubDate>
      <link>https://dev.to/nurrehman/build-vs-buy-is-the-wrong-question-staff-engineers-ask-this-instead-2ahj</link>
      <guid>https://dev.to/nurrehman/build-vs-buy-is-the-wrong-question-staff-engineers-ask-this-instead-2ahj</guid>
      <description>&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/9vg5M1VsRXY" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Every system design interview has a build vs buy question, and most candidates answer it like shoppers. "Buying is faster, building gives control." That answer is not wrong. It is also not an answer. It is a shrug with a tie on.&lt;/p&gt;

&lt;p&gt;The staff-level answer starts somewhere else entirely: nobody cares what you built. They care what you refused to build.&lt;/p&gt;

&lt;p&gt;Auth is never the differentiator. Neither is billing, email delivery, or file uploads. These are solved problems with vendors who have entire teams thinking about them while you sleep. Building them yourself is not engineering rigor. It is volunteering to own someone else's roadmap at 3am, forever.&lt;/p&gt;

&lt;p&gt;The two questions that actually decide it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Is this undifferentiated heavy lifting? If yes, buy it.&lt;/li&gt;
&lt;li&gt;Does this make our product different? If no, buy it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both questions are about the product, not the technology, which is exactly why interviewers ask this. They are checking whether you can think like someone with a budget and a deadline instead of a hobbyist with opinions.&lt;/p&gt;

&lt;p&gt;Now the part nobody mentions: the maintenance bill. Everyone prices the build. Nobody prices the five years after. The login flow you built in two sprints needs SSO next quarter, passkeys the quarter after that, and an audit trail when the enterprise deal lands. The vendor prices all of that into the contract. Your two sprints were just the down payment. An honest estimate of "build" is build cost plus maintenance forever, and forever is expensive.&lt;/p&gt;

&lt;p&gt;Here is the decision rule I actually use, and the one that lands in interviews:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The build vs buy rule:&lt;/strong&gt; buy anything where the failure mode is boring (auth, payments, email, CI). Build only what changes when your product wins. And wrap every bought capability behind your own thin interface, because the day the vendor raises prices or dies, you want the migration to be a one-week swap, not a rewrite.&lt;/p&gt;

&lt;p&gt;That seam is the real senior move. Buying without a seam is outsourcing your architecture. Building everything is NIH with extra steps.&lt;/p&gt;

&lt;p&gt;The question was never build or buy. The question is: what do we refuse to own?&lt;/p&gt;

&lt;p&gt;Watch the 40-second version: &lt;a href="https://www.youtube.com/shorts/9vg5M1VsRXY" rel="noopener noreferrer"&gt;Build vs Buy: How Staff Engineers Decide&lt;/a&gt;. This is question 8 of 60 in the Frontend System Design Interview Playbook.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Your Interviewer Does Not Want the Right Number</title>
      <dc:creator>Nadeem Ur-Rehman</dc:creator>
      <pubDate>Sat, 10 Oct 2026 06:57:57 +0000</pubDate>
      <link>https://dev.to/nurrehman/your-interviewer-does-not-want-the-right-number-5dl6</link>
      <guid>https://dev.to/nurrehman/your-interviewer-does-not-want-the-right-number-5dl6</guid>
      <description>&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/USgUygqIrT4" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtube.com/shorts/USgUygqIrT4" rel="noopener noreferrer"&gt;Watch the 40-second version here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Your Interviewer Does Not Want the Right Number
&lt;/h2&gt;

&lt;p&gt;Ask a senior dev how much bandwidth a feature will cost and watch what happens. The good ones start doing arithmetic on a napkin. The rest ask for a Jira ticket and a sprint.&lt;/p&gt;

&lt;p&gt;Frontend system design interviews have a step everyone tries to skip: scale estimation. The interviewer says "a hundred thousand daily users," or worse, says nothing at all, and expects you to do something with it. Most candidates freeze. The freeze is the fail. The math is not the point.&lt;/p&gt;

&lt;p&gt;Here is why it matters. Nobody on the hiring panel believes your estimate. Not because you are wrong, but because estimation is not about the answer. It is a proxy for how you think when the spec is incomplete, which is the actual job. A staff engineer who can Fermi-estimate a feature in ninety seconds is worth ten who need a "spike story" to tell you what a query costs.&lt;/p&gt;

&lt;p&gt;And here is the non-obvious part. Your guesses are the product. Every number you state out loud is an invitation to be corrected, and corrections are free information. Say "assume 10 percent of MAU is concurrent at peak" and a good interviewer will say "closer to 30 percent in our case," and now you are having a conversation instead of doing arithmetic alone. The candidates who bomb are the ones who did the math silently and announced a number. Nobody can argue with a finished number. Everyone can sharpen a wrong guess.&lt;/p&gt;

&lt;p&gt;The practical artifact: a 60-second scale card you can use in the interview and on the job.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. USERS
   DAU = ___   Peak concurrent = DAU × peak factor (0.1 to 0.3)

2. JOURNEYS
   Actions per user per day = ___
   (page loads, screen views, API calls)

3. DATA WEIGHT
   KB per journey = ___
   (payload + images + JS; weigh the median page, not the homepage)

SCALE = DAU × journeys × data weight
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Worked example: 100k DAU × 20 actions/day × 300KB = 600GB of transfer per day. Now you can talk about CDN cache hit ratios instead of vibes. Notice nothing here requires a correct guess. The peak factor is a range, the data weight is measured from one representative page, and every line is stated out loud so the interviewer can correct it.&lt;/p&gt;

&lt;p&gt;Nobody gets hired for dividing 600 by 0.7 correctly. They get hired because they broke an impossible question into three small ones and kept talking. Try it on your next project in thirty seconds. It feels theatrical the first time. By the third time it is just how you scope.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Question 7 of 60 from the Frontend System Design Interview Playbook.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>architecture</category>
    </item>
    <item>
      <title>The First 60 Seconds Decide Your System Design Interview. Here Is the Script.</title>
      <dc:creator>Nadeem Ur-Rehman</dc:creator>
      <pubDate>Fri, 09 Oct 2026 06:58:02 +0000</pubDate>
      <link>https://dev.to/nurrehman/the-first-60-seconds-decide-your-system-design-interview-here-is-the-script-85h</link>
      <guid>https://dev.to/nurrehman/the-first-60-seconds-decide-your-system-design-interview-here-is-the-script-85h</guid>
      <description>&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/v0NKUo-p5Dc" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Watch the 40-second version: &lt;a href="https://www.youtube.com/shorts/v0NKUo-p5Dc" rel="noopener noreferrer"&gt;https://www.youtube.com/shorts/v0NKUo-p5Dc&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The First 60 Seconds Decide Your System Design Interview. Here Is the Script.
&lt;/h1&gt;

&lt;p&gt;Most candidates hear "design a photo app" and reach for the marker. That is how you lose in the first sixty seconds, before a single box is drawn. Not because your boxes were wrong. Because you never showed anyone how you think.&lt;/p&gt;

&lt;p&gt;Here is the part nobody tells you: the interviewer is not grading your diagram. They are grading what you do with ambiguity. In real work, nobody hands you a clean requirements doc either. They hand you a noun in a meeting and expect an architecture by Friday. The clarification round is a live demo of how you handle that. Treat it like filler and you have told them everything.&lt;/p&gt;

&lt;p&gt;The classic mistake is asking "web or mobile?" and thinking you clarified. That is trivia, not thinking. What actually works is a thirty-second script, three moves:&lt;/p&gt;

&lt;p&gt;First, turn the noun into a journey. "Design a photo app" is a noun. "A user captures a photo, uploads it, shares it with followers who comment" is a journey. Journeys have edges. Edges are where requirements hide.&lt;/p&gt;

&lt;p&gt;Second, draw the boundary out loud. "In scope: upload pipeline, storage, feed. Out of scope: auth, payments." Half of all failing interviews die here, in the mushy middle where the candidate designs half of three systems instead of one system well.&lt;/p&gt;

&lt;p&gt;Third, name the one hard part. "The interesting bit is reliable uploads on flaky mobile networks." This is the move that separates seniors from everyone else. Juniors describe. Seniors diagnose.&lt;/p&gt;

&lt;p&gt;And here is the non-obvious angle. Every clarifying question you ask is a negotiation over where you get scored. Ask about scale, you will be graded on architecture. Ask about edge cases, you will be graded on rigor. Ask about the product journey, you will be graded on product sense. So clarify deliberately, toward the strengths you actually want judged. You are not buying time. You are choosing the battlefield.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 30-second script, copy-paste edition
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Journey it: "So a user captures a photo, uploads it, shares it with followers who comment. Right?"&lt;/li&gt;
&lt;li&gt;Bound it: "In scope: upload, storage, feed. Out of scope: auth, payments, moderation."&lt;/li&gt;
&lt;li&gt;Diagnose it: "The hard part looks like reliable uploads on bad mobile connections."&lt;/li&gt;
&lt;li&gt;Anchor it: "Roughly how many daily uploads are we designing for?"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Four sentences. Thirty seconds. No boxes. And the interviewer has already decided you are one of the ones who thinks.&lt;/p&gt;

&lt;p&gt;This is question 1 of 60 in my Frontend System Design Interview Playbook, the full set of questions, scripts, and traps, with the answers I wish someone had handed me: &lt;a href="https://bittalk.gumroad.com/l/frontend-interview-playbook" rel="noopener noreferrer"&gt;https://bittalk.gumroad.com/l/frontend-interview-playbook&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Stop Saying Your System Is "Fast and Scalable." That Is Not a Requirement.</title>
      <dc:creator>Nadeem Ur-Rehman</dc:creator>
      <pubDate>Thu, 08 Oct 2026 06:58:05 +0000</pubDate>
      <link>https://dev.to/nurrehman/stop-saying-your-system-is-fast-and-scalable-that-is-not-a-requirement-5gp4</link>
      <guid>https://dev.to/nurrehman/stop-saying-your-system-is-fast-and-scalable-that-is-not-a-requirement-5gp4</guid>
      <description>&lt;h1&gt;
  
  
  Stop Saying Your System Is "Fast and Scalable." That Is Not a Requirement.
&lt;/h1&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/CRNY0Cny-48" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtube.com/shorts/CRNY0Cny-48" rel="noopener noreferrer"&gt;Watch the 40-second version on YouTube&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every system design interview has a moment where the candidate says the system should be "fast and scalable," and the interviewer's eyes glaze over. That is not a requirement. That is a wish. Wishes do not pick architectures. Numbers do.&lt;/p&gt;

&lt;p&gt;Here is the split that matters. &lt;strong&gt;Functional requirements&lt;/strong&gt; are what the system does: login, search, checkout, upload a profile photo. Every candidate gets these right, and they are nearly useless, because two systems with identical features can need completely different architectures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Non-functional requirements&lt;/strong&gt; are how well the system must do it: latency, throughput, availability, consistency, data scale. Name these first, because they pick your architecture for you. "Fast" at 50ms p95 is a CDN, edge caching, and a read path with no cross-region calls. "Fast" at 2 seconds p95 is a plain server and a nap. Same word, different system, different budget, different on-call pain.&lt;/p&gt;

&lt;p&gt;The non-obvious part: non-functionals are the interviewer's scoring rubric wearing a costume. Every "trade-off" discussion they steer you toward is a non-functional you never wrote down. Strong versus eventual consistency is not a philosophy question, it is a latency number and a conflict-resolution budget. Caching strategy is not a vibe, it is your read-to-write ratio. When you quantify, the design stops being a drawing exercise and starts being arithmetic, and arithmetic is much harder to argue with.&lt;/p&gt;

&lt;p&gt;This is not interview theater either. Real production outages are almost never "the feature was wrong." They are "nobody wrote down the number," followed by a database melting at 3 a.m. because someone assumed 100 requests a second meant 100,000.&lt;/p&gt;

&lt;p&gt;So steal this. Before you draw a single box, in an interview or a real design doc, fill in the five lines. It takes 30 seconds and it is the highest-ROI 30 seconds in architecture.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REQUIREMENTS, QUANTIFIED (the 30-second script)
[ ] Latency:      p95 ___ ms, p99 ___ ms (which endpoints? reads vs writes?)
[ ] Throughput:   ___ reads/s, ___ writes/s, peak multiplier ___x
[ ] Scale:        ___ DAU, ___ total records, growth ___x per year
[ ] Availability: ___% (two nines = 87h downtime/yr, three nines = 8.8h)
[ ] Consistency:  strong / eventual / last-write-wins (pick one, defend it)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a line stays blank, say so out loud and state your assumption. Interviewers score that too. It beats "fast and scalable" every single time.&lt;/p&gt;

&lt;p&gt;Question 6 of 60 in the Frontend System Design Interview Playbook. What is the worst unquantified requirement you have ever seen in an interview? I am collecting them.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Your AI Does Not Read Your Prompt. It Places Bets on It.</title>
      <dc:creator>Nadeem Ur-Rehman</dc:creator>
      <pubDate>Wed, 07 Oct 2026 06:57:44 +0000</pubDate>
      <link>https://dev.to/nurrehman/your-ai-does-not-read-your-prompt-it-places-bets-on-it-18b5</link>
      <guid>https://dev.to/nurrehman/your-ai-does-not-read-your-prompt-it-places-bets-on-it-18b5</guid>
      <description>&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/mzPZ_LI5Zo4" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Watch the 40-second version: &lt;a href="https://youtube.com/shorts/mzPZ_LI5Zo4" rel="noopener noreferrer"&gt;How Transformers Predict Your Next Word&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Your AI does not read your prompt. It places bets on it.
&lt;/h2&gt;

&lt;p&gt;Here is the uncomfortable truth about the most sophisticated software you have ever used: it has never once known what it was saying. A transformer takes your prompt, turns every word into a coordinate in a giant space of meaning, runs attention over the whole mess to decide which words deserve to influence the answer, and then rolls weighted dice. One token at a time. Fifty-ish times a second.&lt;/p&gt;

&lt;p&gt;That is it. There is no little reasoning engine in there double-checking facts. There is a probability distribution and a sampling function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this explains everything weird about LLMs
&lt;/h2&gt;

&lt;p&gt;Once you see next-token prediction as the mechanism, the famous quirks stop being mysteries and start being obvious consequences.&lt;/p&gt;

&lt;p&gt;Bad at math but good at vibes? Math needs exactness; dice need distribution. Asking a token predictor to do arithmetic is like asking a vibe generator to file your taxes. It can approximate the shape of a correct answer, which is why 2+2=4 works and your mortgage amortization does not.&lt;/p&gt;

&lt;p&gt;Hallucination is not a bug. It is the mechanism working exactly as designed. The model was trained to produce the most plausible next token, not the most true one. Truth and plausibility overlap often enough to fool you, and diverge exactly where you cannot verify. "Confidently wrong" is just what sampling looks like when the stakes are high.&lt;/p&gt;

&lt;p&gt;And the non-obvious angle nobody tells you: this is why prompt engineering works at all. You are not "talking" to the model. You are biasing a probability distribution. Every example you add, every constraint you write, reshapes the odds of the next token. Prompting is statistics with a user interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  The checklist: force the dice to behave
&lt;/h2&gt;

&lt;p&gt;You cannot make a transformer reason. But you can rig the bet. Copy this before any task where correctness matters:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Lower the temperature to 0 for factual tasks. High temperature is the model brainstorming. You do not want brainstorming from your accountant.&lt;/li&gt;
&lt;li&gt;Demand structure. Ask for JSON, tables, or numbered steps. Format constraints cut off entire branches of plausible nonsense.&lt;/li&gt;
&lt;li&gt;Make it show work on one line per step. Chain-of-thought is not reasoning, but it gives the model more tokens to condition on, and longer conditioning means tighter distributions.&lt;/li&gt;
&lt;li&gt;Feed it the facts instead of asking it to recall them. This is what RAG is for. The model is a fantastic interpolator and a terrible memorizer, so stop testing its memory.&lt;/li&gt;
&lt;li&gt;Verify the one thing that matters. Sampling errors cluster in details: numbers, names, dates. Scan those first.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The closer
&lt;/h2&gt;

&lt;p&gt;The transformer is a bet-placement machine that learned to sound like a person. Treat it like one and it will con you. Treat it like a loaded probability distribution and it becomes the most useful tool on your desk. The difference is not in the model. It is in what you assumed it was doing.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Your Global Store Is a Junk Drawer. Sort State Into Four Boxes First</title>
      <dc:creator>Nadeem Ur-Rehman</dc:creator>
      <pubDate>Tue, 06 Oct 2026 06:58:08 +0000</pubDate>
      <link>https://dev.to/nurrehman/your-global-store-is-a-junk-drawer-sort-state-into-four-boxes-first-nbb</link>
      <guid>https://dev.to/nurrehman/your-global-store-is-a-junk-drawer-sort-state-into-four-boxes-first-nbb</guid>
      <description>&lt;p&gt;If everything lives in the store, nothing really lives in the store.&lt;/p&gt;

&lt;p&gt;I have watched senior engineers, people with a decade on their resume, answer "how do you structure state in a complex app" by describing one giant global store. Server data, form inputs, a sidebar toggle, a cached auth token, all of it swimming in the same tank like it is 2016 and we are still doing it for the aesthetic. It is the fastest way to turn an architecture interview, and your actual codebase, into a junk drawer.&lt;/p&gt;

&lt;p&gt;Here is the thing nobody says out loud: most of what you call "state" is not yours. Server state is someone else's database that you are temporarily babysitting. URL state is free deep-linking infrastructure you already own. Local UI state is just a variable that got ideas above its station. Once you see it that way, the architecture question answers itself: classify first, then pick the tool. The store is a destination you arrive at, not the place everything starts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sort every state item into four boxes
&lt;/h2&gt;

&lt;p&gt;This is the whole method, and it fits on an index card. For every piece of state in the app, ask:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Did it come from a server?&lt;/strong&gt; Then it is server state. It is a cache, not state you "manage". Give it a cache (query library with stale-while-revalidate), not a reducer. If you are writing &lt;code&gt;setServerData&lt;/code&gt; by hand in 2026, you are doing the library's job badly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Would another person need it from a shared link?&lt;/strong&gt; Then it belongs in the URL. Query params are the most underused store in frontend: free persistence across refreshes, free deep links, zero code. Search filters, selected tabs, pagination. If a page cannot be shared with a link, you have a bug, not a design choice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Is it only alive inside one component subtree?&lt;/strong&gt; Local UI state. &lt;code&gt;useState&lt;/code&gt;, colocated with the component that uses it. A modal open flag does not need to travel. If your store has a boolean called &lt;code&gt;isOpen&lt;/code&gt; with no idea what it opens, I have questions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Must it survive a reload?&lt;/strong&gt; Persisted state. localStorage or IndexedDB with a hydration plan and an expiry story. And here is the non-obvious one: persisted state is a cache of a previous session, which makes it server state from the past. Treat it with the same suspicion you would treat any cache.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The decision rule
&lt;/h2&gt;

&lt;p&gt;Copy-paste this into your team's docs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you cannot name which of the four boxes a state item belongs in, it does not go in a global store yet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That one rule kills 80% of store bloat before it starts. The remaining 20% is the genuinely shared, client-owned state: the stuff that is neither server data, nor URL, nor local, nor persisted. That is what your store is for. You will be shocked how small it is.&lt;/p&gt;

&lt;p&gt;The interview answer writes itself after that: four boxes, classify first, tools follow. The architecture answer is the same sentence, just slower.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/2k9uY5jQbmY" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Watch the 40-second version of this idea: &lt;a href="https://www.youtube.com/shorts/2k9uY5jQbmY" rel="noopener noreferrer"&gt;https://www.youtube.com/shorts/2k9uY5jQbmY&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is Question 13 of 60 in my Frontend Interview Questions series. The full 60-question playbook, with the system design frameworks behind each answer, is linked on the channel.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>webdev</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
