How's Linear so fast? A technical breakdown

SouravInsights1 pts0 comments

How's Linear so fast? A technical breakdown

Dennis Brotzky·May 3, 2026<br>How's Linear so fast? A technical breakdown<br>A few milliseconds is all it takes to update an issue in Linear. A traditional CRUD app doing the same thing takes about 300ms. How do they do it? There's no secret silver bullet to performance. The reality is that it's built from the ground up on the right foundation, then improved by countless decisions. My goal is to walk through some of the techniques that make Linear feel the way it does and help you implement the same.<br>What I'll cover<br>Database in the browser

Making the first load feel instant

The sync engine

Designed for speed

Animations

A quick disclaimer: I've never worked at Linear and have never seen their code. Everything I share comes from my personal experience, studying their app, reading their blog posts, or watching their conference talks. I simply love building web apps and have been using Linear since their beta launch. Also, the article’s hero image comes from a video by Meg Wayne, whose work for Linear is phenomenal.<br>Database in the browser<br>Most web apps live inside the same loop. The user clicks. The browser fires an HTTP request. A server queries a database and sends it back. The browser repaints. The end result is a spinner, a skeleton, or a frozen UI for a few hundred milliseconds while the app waits on the network.<br>Linear inverts the traditional relationship. The actual database the UI reads from is in the browser, in IndexedDB. Mutations apply locally first, then asynchronously push to the server, which broadcasts deltas back to other clients via WebSocket.<br>In my opinion, this is the most critical piece to Linear's performance. When your goal is to build a fast web app the biggest bottleneck you will fight is the network. Any data sent between the client and server costs hundreds of milliseconds. The best approach is to eliminate the need for a network request entirely: which is exactly what Linear does.<br>I'll be repeating this a lot, but the secret to building incredible web apps is by hiding all the network requests from the user. The more loading states you can avoid the better.<br>Here's an example of how simple Linear's requests are:<br>// A traditional web app updating the server<br>async function updateIssue({ issue }) {<br>showSpinner();<br>const response = await fetch(`/api/issues/${issue.id}`, {<br>method: "PATCH",<br>body: JSON.stringify({ title: issue.title }),<br>});<br>const updated = await response.json();<br>setIssue(updated)<br>hideSpinner();

// vs Linear<br>issue.title = "Faster app launch";<br>issue.save();<br>The first line, issue.title = "Faster app launch", updates an in-memory datastore (MobX observable in Linear's case) . The second line, issue.save();, queues a transaction that their sync engine batches and flushes to the server. The key here is that the UI re-renders synchronously off the local, in-memory, update. There are no spinners because there is nothing to wait for because the data is synced in the backround. This is the magic of treating the browser as the database for each user.<br>Tuomas, one of Linear's co-founders, said this at a conference in 2024: 'Literally the first lines of code that I wrote was the sync engine, which is very uncommon to what you usually do when you're a startup.' From day one, Linear knew the approach they wanted to take and the tradeoffs it would take.<br>Linear's issue creation no spinners or delays<br>I know most people won't build a custom sync engine like Linear just to make their app feel fast and they don't need to. For most use cases, libraries like Tanstack Query and SWR can get surprisingly close with optimistic updates. Most web apps feel slow because the UI waits for each network request to complete before updating state. For most usecases the network request will succeed so you should take advantage of that and optimistically update your state.<br>// optimistic mutation with SWR<br>mutate(<br>`/api/issues/${issue.id}`,<br>{ ...issue, title: "Faster app launch" },<br>false<br>);

// vs Linear<br>issue.title = "Faster app launch";<br>issue.save();<br>The key idea is simple: UI responsiveness should not depend on network latency. Users perceive speed based on how quickly the interface reacts, not how quickly the server responds.<br>Optmistic requests is one of the highest leverage improvements you can make:<br>eliminate unnecessary spinners

update state immediately

validate in the background

rollback only if needed

Linear's foundation is based on this exact principal and it makes the app feel native and fast.<br>A peek into Linear's stack<br>Linear is built on the simplest stacks you can find: React, TypeScript, MobX, Postgres, a CDN. There's no edge database, no React Server Components, or no fancy framework.<br>Frontend<br>React + react-dom (UI runtime)<br>MobX (observable graph, granular re-renders)<br>TypeScript (single language end-to-end)<br>Rolldown-Vite + plugin-react-oxc(mid-2025; previously Rollup; previously Parcel)<br>ProseMirror + y-prosemirror (rich text editor; Yjs CRDT for live...

linear issue server network fast from

Related Articles