We use Linear at work. I’m definitely in the minority, but I really struggle with the UX. I also wouldn’t call it fast. Sure the page technically loads reasonably quickly, but half the time I see numbers updating on the page with no visual indicator that data loading is still happening.
SenHeng 1 hours ago [-]
A common problem I have with Linear is that repeated writes sometimes overwrite themselves. Consider this flow
1. type
2. stop to ponder for a split second
3. type some more
4. Linear reverts data to step 1
It's bad enough that I'll use Linear to create issues with a single sentence description. This is what Linear is good and fast at. Then I'll switch to GitHub to fill in the details.
SkyPuncher 1 hours ago [-]
Linear has become the thing it sought to kill - complex.
It's really the only way for companies to survive and go up market, unfortunately.
nailer 35 minutes ago [-]
God it’s awful. I had to get a colleague to show me how to add a due date to an item because it’s hidden in the nav pane. It’s better than Jira, but that’s a very low bar.
desireco42 1 hours ago [-]
I share your sentiment, not to say that Linear is bad, just that I don't see it as good UX or fast.
cyberax 32 minutes ago [-]
Linear enshittified their UI in the name of "clarity". You know the drill: remove functionality, add small icons with invisible text and HUGE padding, hide controls, etc.
For example, the search field only shows if you press "ctrl-f".
SkitterKherpi 35 minutes ago [-]
[dead]
syspec 3 hours ago [-]
Whole blog post is basically: Make a mutation in the clientside, assume it worked, and save in the background.
mohsen1 3 hours ago [-]
Works for Linear because the tab stays open, and worse case if tab is closed you can recover later when the tab is opened again and deal with conflict resolution. Won't work if:
1. user clicks a button and closes the tab thinking transaction is done and it's important that transaction is done
2. conflict resolution is difficult or impossible in future client wake up
nine_k 3 hours ago [-]
The user clicks the button, the mutation is stored in local storage. The user closes the tab, but it's not a problem.
A background worker picks up the mutation and sends it to the remote backend. It takes time, retries, etc.
Similarly, any errors reported by the background worker go to local store, and the next time the UI tab is loaded / activated, they are shown. A service worker can show a notification outright to let the user easily load the main UI. Normally this would be a rare occasion.
blauditore 38 minutes ago [-]
1. What if the browser gets closed/killed?
2. Error messages around syncing issues are notoriously worse than those of a sync request to the backend that failed. So the UX in the end is worse.
More generally: You can't circument the trade-offs of a distributed database, which such products are, conceptually.
ifwinterco 2 hours ago [-]
Yeah this pattern can be made to work fine.
Main downside is it significantly complicates the front end code compared to just waiting for FE to sync with BE before updating
galaxyLogic 56 minutes ago [-]
What if we had a local server running on the same PC, which then relays the request to some shared server on the internet?
pyrolistical 1 hours ago [-]
Expose the sync queue to end user and train them to understand if they attempt to close the tab with a pending queue they will get the ugly prompt warning them
dbbk 2 hours ago [-]
Still works if you use beacon requests, they survive tab close
Onavo 2 hours ago [-]
Yes and for linear (if you break it down strictly in a theoretical CS sense, is roughly equivalent to TodoMVC in terms of application complexity assuming non-collaborative text editing) they have clearly defined states for most items and few if none truly destructive actions. The hardest part is anything text related.
NewsaHackO 3 hours ago [-]
I agree. To each their own, but the UI updating automatically doesn't really add much value to me. I would prefer that the view I am seeing is a snapshot in time of what the ground truth server was, not some mixed state that forces me to consider the possibility that seeing my request go through on the screen doesn't actually mean it went through and has been sent to the server.
inezk 2 hours ago [-]
The goal is - and I think they have achieved it - is that you don't have to think about it. They handle sync, and they do it reliably.
SoftTalker 1 hours ago [-]
Then they have solved one of the fundamental hard things in computer science.
girvo 36 minutes ago [-]
AKA what Relay does out of the box haha
Though its depressing how few actually use it to its full extent. My team is one of the few where I work; heavy declarative mutation directives with optimisticResponse (and optimisticUpdaters because some of our APIs are not very Relay-compatible, annoyingly)
pier25 3 hours ago [-]
For native apps this is less of an issue since they have access to persistent storage but with browsers there's no guaranteed persistence.
WhyNotHugo 3 hours ago [-]
There's guaranteed persistence, but there's no guarantee that the host will be up anytime soon. E.g.: I might leave a final reply with all the details on an issue before going on vacation (or maybe I don't work the next day but my colleagues abroad do!). I see that it's properly posted and close the laptop.
The reply with be delayed by days or weeks, but the UI indicated that it had been properly saved.
pier25 3 hours ago [-]
> There's guaranteed persistence
There's not. Browsers can delete "persistent" storage at any time.
> If, for any reason, developers need persistent storage [...] they can do so by using the navigator.storage.persist() method of the Storage API.
This makes a request for guaranteed permanent storage ... which can be approved (or denied) by the user or by browser defaults.
ifwinterco 2 hours ago [-]
Edge case but playing devil’s advocate: a user can also uninstall the native app at any time, and might still expect their last change before they closed the app to be reflected in the web version.
You can never truly trust anything about a client because by definition you don’t control it
killingtime74 2 hours ago [-]
But the os can't uninstall the native app at any time unprompted right
ifwinterco 2 hours ago [-]
No, it’s definitely a lot less likely and probably an edge case you can ignore in practice
prerok 3 hours ago [-]
Indeed. I have to say, I hate this. Suppose you are in a meeting, you update something and you see the result, but the rest of the team does not. Ok, a couple of hundred ms does not play into this but if the update does not make it through? And yes, it happens.
artman 3 hours ago [-]
Changes go through and synced to everyone on your team in almost realtime. If there's a conflict on the server and your change cannot be applied (almost never happens), your change is rolled back on your client, again, almost in realtime. If servers cannot be reached, we will show you a syncing badge within 4 seconds to tell you that you have made changes that haven't been sent to others yet.
Strange that we can be so be polar opposites on this. You hate it, I would never write an app in any other way, ever again.
n_e 2 hours ago [-]
As a user, I like when things appear to sync instantly and perfectly, such as in Google Docs.
As a developer, I hated the article and many of the comments I read thus far because:
- Having clients and a server properly sync and not lose data in the event of a network failure amounts to having a consistent distributed system which is not easy to do, and the commenters don't seem to have understood that
- I hate having written a long document and then losing it because the sync code is buggy, so the previous point becomes even more important.
So reading many of the things here has been mildly infuriating.
That being said, none of these people are likely affiliated with Linear, and given the overall quality of the product I'm pretty sure it works properly.
ifwinterco 2 hours ago [-]
In the case of a partition the client nodes get temporarily out of sync but the system will then synchronise to one state again once the partition is resolved if it’s written correctly.
So no violation of CAP theorem it just prioritises liveness over consistency
porridgeraisin 3 hours ago [-]
(curious) What if a user closes it before 4 seconds? Ctrl+enter, it optimistically locally updates within 1 second. I close ctrl+w. But my wifi goofed and it didn't reach the server.
singron 2 hours ago [-]
I have mysteriously lost comments/descriptions I wrote on issues. I figured it was related to a failed and lost opportunistic update like this, although I suppose it could have been caused by a fixable bug.
artman 2 hours ago [-]
The HTTP request is fired off instantly, so chances are that the request is already written to the socket and closing the page won't cancel the request. Should your wifi-router drop it, your client will retain the transaction on disk and retry it the next time you come online.
porridgeraisin 1 hours ago [-]
> next time you come online
Yeah that's the issue isn't it?
I see in the UI it's sent. But actually it's sent only the next morning.
To be fair. It's fine for an issue tracker. Anything actually important i'd spend a few seconds going over what I just sent. In which case I'd see it's not synced. And what's not that important it's really fine if in some random wifi edge case it's phantom sent. So makes sense.
sneak 2 hours ago [-]
I believe this is called “eventual consistency”.
amelius 2 hours ago [-]
No, because if a transaction fails it still needs to be handled by the user in many cases.
E.g. if you buy a book, but it turns out the book was already sold, then you will first get a message "Your book is on its way!" and then "Oops, sorry, the book was already sold to someone else".
Eventual consistency is just a property of the database.
simjnd 3 hours ago [-]
Last year a guy reverse engineered Linear's sync engine and published it on GitHub with a cool explainer.
Writing an eventually consistent database is hard, it maybe fine for Linear's use cases, but not knowing if my updates made it to the server (aka my team),is problematic. The sync lags have created untold problems in other projects I have worked for, so I always go for a synchronous solution. All the fancy stuff comes out only if it's absolutely needed. I'd rather optimize my server to be blazing fast, and have the user "suffer" network latency.
booi 2 hours ago [-]
Yeah I’ve had inconsistencies before with linear but jira is a garbage fire so…
angrydev 1 hours ago [-]
This is my experience but haven’t used linear in 2 years. Switching to JIRA was miserable.
ricardobeat 2 hours ago [-]
I would always hear about how Linear was fast, but after actually working daily with it, I’ve lost enthusiasm. Search is quite slow, the UI is often clunky (looks good though), “Pulse” is a torrent of noise even at small scale, and I have trouble finding things I need and resort to adding everything to favorites.
Early days’ Trello was the best project tracking experience by far.
jacobgold 3 hours ago [-]
These kinds of local-first syncing web apps are really interesting and can be really useful, but I think the premise is somewhat wrong.
"A few milliseconds is all it takes to update an issue in Linear. A traditional CRUD app doing the same thing takes about 300ms."
"Any data sent between the client and server costs hundreds of milliseconds."
There’s no solving the problem of a large RTT between an HTTP client and server when it’s due to the speed of light.
But what you can do is locate the backend near users and make sure it’s fast.
For example, it’s very possible to run a web app backend within ~10ms RTT of most users and have the backend render responses within ~10ms too.
In other words, you can absolutely create a traditional CRUD app where doing the same thing takes more like 30ms, not 300ms.
lmm 55 seconds ago [-]
> it’s very possible to run a web app backend within ~10ms RTT of most users
Only if your users are all located quite close to each other, or (sadly very common) you only care about making it fast for US users and screw everyone else.
(Of course you can have "intermediary backends" around the world on a CDN's edge network or similar, but at that point you're paying the same complexity cost as this style of putting the "intermediary backend" on the client)
evantbyrne 2 hours ago [-]
Thank you. Was beginning to feel like I was taking crazy pills seeing people claim that 300ms is fast when 30ms has been the target TTFB for as long as I can remember. Maybe Linear takes more time on the backend for totally valid reasons and it needs some help from the frontend, but that's not generalizable, and every bit of JS comes with its own costs.
SoftTalker 1 hours ago [-]
When I started in this business, "sub-second" responses were the goal.
pastel8739 59 minutes ago [-]
Can you do this where you need to have a database shared between all these edge backends?
nine_k 3 hours ago [-]
You can locate an "intermediary backend" on the client, write outstanding mutations into local storage, have a background worker send it to the backend, with necessary retries, etc. At worst, the background worker would put out a message about a failed update which the UI tread would receive and show.
But the happy path stays lightning-fast.
jacobgold 2 hours ago [-]
Sure but there's a ton of complexity in any kind of local-first syncing solution. Often the solution is CRDTs.
My point above is that the simple solution ("traditional CRUD app") is actually viable even when the goal is very low latency.
throwaway7783 2 hours ago [-]
100% agree. A traditional CRUD app (like Linear) can be made pretty low latency without local-first. The complexity is not worth it.
3 hours ago [-]
mattmatters 8 minutes ago [-]
Linear still only uses j/k for up and down. I've asked over and over for the past 5 years for ctrl+n/ctrl+p up and down and have gotten nonsensical answers from support.
What's crazier is they support this navigation key combo in their command palette but no where else.
The vim line nav is a nice thing in apps, but it's extremely frustrating I can't change it.
Keyframe 2 hours ago [-]
This is neat. To be honest, I never considered Linear as "fast". Seemed laggy as most web apps, but in contrast to JIRA it's lightspeed of course. Linear is great though, a real refreshment after JIRA torture.
As for optimistic routes and "fast" - maybe we ought to talk gmail first?
victorkulla 9 minutes ago [-]
Apparently "Hacker News" won't allow me to delete my account. Well let's give this a go:
HACKER NEWS is ran by a bunch of idiots that think karma is an actual thing, If this is so - then explain this?
cuechan 3 hours ago [-]
> A traditional CRUD app doing the same thing takes about 300ms.
300ms seems like a lot. Even if this includes the whole http request+response it still seems unbelievably long.
jpollock 3 hours ago [-]
It depends on where your clients are, and where your servers are. You may have a lot of customers in a country and not want to host servers in that country (tax, regulatory, maintenance cost, etc.)
RTT from Hyderabad to the East Coast USA is ~300ms.
this is kinda missing the point. yes, the raw http calls __should__ be enough for 300ms.
but the benchmark is similar software like JIRA, which takes agonizingly long to do anything reasonable.
IshKebab 3 hours ago [-]
Yeah you can easily get this speed down to like 100ms which is near enough to instant to not matter. You definitely don't need to go to client side rendering for most things to feel fast.
Also I couldn't see any explanation of what happens when a network request fails. That's a huge downside of local rendering.
I think for most sites the best option is still server-side rendering but use a fast backend (e.g. not Python) and lightweight frontend.
saagarjha 3 hours ago [-]
I’ve actually found Linear to be quite slow? There was a week where it would also spin at 100% CPU if I left a tab with it open for a while :(
seabombs 3 hours ago [-]
It appears to use a lot of memory too, at least in Firefox. I can't have more than a few Linear tabs open at a time.
Escapado 3 hours ago [-]
I love using linear and where applicable I try to use optimistic updates in the applications I build too and I think it's a good article that touches on the most important aspects of a performant web app of that caliber.
One thing I would like to point out though is that building a performant sync engine that behaves the way you would like in most cases is a non-trivial thing.
If two users are offline and add, edit, remove issues and come online again, you need to reason about what happens. Sometimes you can get away with Last Writer Wins but what happens if an issue is deleted and then edited. What happens if an item in a list gets re-ordered differently on different clients, what's the final ordering? In which cases can you merge what state and in which do you need to discard something. Do you show a conflict resolution UI? How do you deal with rollbacks. How do you deal with schema drift and updates on items that would be affected by schema drift? Business logic might change between being reconnects. FK constraints can shift. Can you set up your data and the sync engine so that it only syncs the minimum amount of changes and batches them correctly during longer offline sessions so you don't fire 5000 change requests after reconnecting?
I recently had to implement local first + remote sync on some fairly complex dynamic forms and where luckily there is usually only one writer and I can get away with last writer wins and reject if things are too old or if there is schema drift and can just display an error message and roll back. But what I am trying to say is: Whatever can go wrong in an online-first world, can also go wrong in an offline first world but you might get informed of that all at once at a later time - or not at all and your data is not what you think it should be. Some sync engines like zero from rocicorp has opted out of supporting offline writes entirely because of all these problems.
And just to be clear: I love offline first approaches. I yearn for fast performance. And in a lot of cases slapping a sync engine on your app can really be helpful for that if your use case allows it. But it's absolutely crucial to be aware of the pitfalls that come with it.
hamandcheese 3 hours ago [-]
I worry that optimistic updates is going to become trendy and applied to more software, but without any plan for the "sad path" - failed to sync, sync conflict, etc. Get ready for a whole new era of race conditions and frustration!
12_throw_away 2 hours ago [-]
> optimistic updates [...] without any plan for the "sad path"
based on my experience, this is a great description of the sync implementation in many already widely deployed products (say, off the top of my head, OneNote, OneDrive)
jack_pp 3 hours ago [-]
Don't you have the same problems with basic CRUD apps? Also you need to handle the sad path for every single request instead of having the sync engine do it all in one place.
Escapado 3 hours ago [-]
Correct but the feedback is usually more immediate. Save a change to your issue and it fails - You will get an error toast and probably stay on the form.
In the local first world you might have navigated away already and created 3 more issues of which 2 more failed because of schema drift or other conflicts. And you might have edited one that was deleted. And now you need to figure out what exactly to tell the user - or what not to tell them.
jack_pp 3 hours ago [-]
Well the sync engine can figure out if there's an issue fast, say <500ms, if you build it that way. Then you can just make a toast telling the user there are issues and anything they do will be saved locally only for the time being.
Warn the user that if they leave the website their changes won't be saved remotely.
artman 3 hours ago [-]
In reality conflicts almost never happen.
hamandcheese 3 hours ago [-]
The issue that I foresee is that the point of error becomes decoupled from the UI and the UI doesn't handle a delayed error. Especially if retrofit into existing products.
MaoSYJ 2 hours ago [-]
well it has been the standard for non critical feedback.
I would not implement optimistic resolution in key information, prices, for example. They live in the server and backend should keep the total control in the client side, even feedback response time.
wbobeirne 3 hours ago [-]
I'm glad to see more positive takes on client-side rendering. Unless SEO and crawlability are important for your site, server side rendering is such an overprescribed solution. If I put my tin-foil hat on, I'd say it gets a lot of attention because it's a lot easier to charge people for server time spent in SSR that you just don't have in CSR.
Bottom line is, if your app's content is behind a login screen, just use client side rendering. It is way lower complexity and a way better user experience.
epgui 3 hours ago [-]
I’ve never thought of Linear as particularly fast.
esafak 3 hours ago [-]
What web app would you put forward instead?
herpdyderp 2 hours ago [-]
My Linear client gets stuck "syncing" all the time, completely blocking all interaction. I'd rather have loading spinners than getting, essentially, locked out of the whole app for 10 minutes.
ianberdin 3 hours ago [-]
Thanks for the read. It is a bit more complicated than you think.
I completely rebuilt this sync engine + orm with relations, lazy loading etc, using Vue + Pinia in https://playcode.io. Google Linear’s videos, they explained in detail their architecture.
Yes, I spent a few months. But it worth it. Every new field, model I need to add, it is so straightforward. I do love frameworks and foundations. They make live easier later by a lot.
ianberdin 3 hours ago [-]
Feel free to ask questions.
lampe3 3 hours ago [-]
what google linear video?
echoangle 3 hours ago [-]
I think google is an imperative verb here. You're supposed to google (as in search for) Linears Videos.
These are original video. Very clear and a way better than the blog post.
victor9000 1 hours ago [-]
The linear MCP is amazing to work with as it lets me keep all my workflows in the terminal. The ergonomics around search and ticket management are dead simple going through a terminal agent, so I didn't need much more convincing after enabling that configuration.
seaal 2 hours ago [-]
Pretty nice how they package each article into a skill, wonder how useful they actually are in real world workflows.
Interesting.
Looking forward to the next article explaining how it is so slow.
(TL;DR it's a webapp disguised as a desktop app.)
3 hours ago [-]
ArcaneMoose 2 hours ago [-]
I recently started interacting with JIRA exclusively through AI agents (as a Skill in Cursor) and the difference between Linear and JIRA has immediately evaporated. No UI clunkiness problems if I don't even use it :)
nilirl 3 hours ago [-]
Am I the only that doesn't "get" Linear? Even if speed is the killer feature, isn't an issue tracker a relatively low-frequency application for a dev?
Whenever I use it, I don't feel like I'm doing anything new when compared to all the other issue trackers and Kanban boards I've used before.
andersonklando 2 hours ago [-]
It is definitely way more performant than Jira + Microsoft Planner. Trello comes to mind in terms of performance. I speak from being a heavy user of Linear for my personal project and as a Jira enterprise user.
A leader of 6 will spend a lot of time in such an app, so the UX is valuable and a differentiator for them.
mrbombastic 47 minutes ago [-]
Jira is fine and devs just grow to hate issue trackers because they hate that part of the job. Watch for another one to come and go when people get sick of linear.
ambicapter 2 hours ago [-]
I honesty can’t say it’s better than Jira, the myriad options just make it a confusing mess to figure out how to navigate and put stuff (could be my company is just hella disorganized), and the GitHub tracking is annoyingly eager (just because the first PR has been merged doesn’t mean the ticket is done).
yolo3000 2 hours ago [-]
Maybe we work at the same company. I have the same experience. Don't know why people use it.
apothegm 2 hours ago [-]
Say what you will about Jira, at least it’s not a total maze.
jwr 3 hours ago [-]
Linear is the best web app I have ever seen, period. It is also the best bug-tracker I've ever used. I use it, and pay for it (gladly). It's worth it.
I am genuinely impressed with their engineering and design — I aspire to attain these levels, though I lack not only the skills, but also several zeroes in my bank account, I think. Still, it's worth looking at what they do and try to get there!
Big props and kudos to the Linear team. It's an impressive app.
apsurd 3 hours ago [-]
Interestingly, as a professional developer I had the opposite first experience. It's a tracker. It looks like every other tracker. Everything is really small and "clean" which means they just hide everything, for that modern look.
I was thoroughly unimpressed. "This is it?" - "It's a tracker"
I feel comfortable saying this because in the weeks after, actually using it is the aha experience. Linear nailed the UX of working where people already work. Which again is really funny because the best part of Linear is how well it works outside of Linear.
(disclaimer: I actually now use their UI a lot. It's a helpful dashboard. But it suffers from every other hard-problem of information dense task-based dashboards.)
epolanski 2 hours ago [-]
Jira might be a technological disaster I hate with all of my guts, but as a product, it's on a completely different level than Linear.
Seriously, I hate it, but I've worked in most other competing products, from Trello to Azure Devops to Linear, Jira is a much more powerful engine that can be easily adapted to large organizations where each team has very different processes.
What works for a software team, does not work for sales, which does not work for HR, which does not work for QA or business development. Jira is flexible enough that can accomodate any kind of operation. Linear is like a very small and catchy subset of it.
jonny_eh 2 hours ago [-]
I like it when a spinner represents the truth about the state of the value on the server. I want to know when/if it's been updated.
pier25 3 hours ago [-]
Honestly you can POST to an API to the other side of the world and receive a response in less than 300ms. That's literally the blink of an eye. There are very few use cases where you'd need even lower latency than that while at the same time sacrificing reliability (there's no guaranteed persistent storage in a browser).
wasmperson 3 hours ago [-]
In gamedev, "optimistic updates" are called "client-side prediction," and are a standard part of multiplayer games. IMO it's somewhat risky to apply the technique to web-apps, since each network request typically corresponds to some important operation, and optimistically updating the UI is lying to the user about whether that operation completed successfully.
IMO a good approach is to update the UI immediately but still show some indication that the operation hasn't completed. So in a chat app, for example, add the message to the list of messages, but with contrast reduced slightly to indicate that other people can't see it yet.
artman 3 hours ago [-]
Operations are on average applied within a few hundred milliseconds, and almost never fail. Because of this we treat the success path as default, and indicate that your changes haven't been applied only if we detect that you're offline, or if it takes more than 4 second to apply the changes.
I see this comment over and over again, yet I know lots of Linear-enthusiastic people and none is suffering of this.
Meanwhile after a brief period of Jira being performant, it has felt into ruin again.
In any case, I've tried both, and Jira is on another whole level when it comes to map processes of different teams.
Linear is a good looking toy mostly catered to the average software engineering team, it just doesn't support the flow complexity needed by different business units.
adverbly 3 hours ago [-]
Any good resources or wrappers for indexedDB people would recommend? The API seems kinda unapproachable compared to other data stores.
I was expecting a post about how O(n) algorithms can sometimes beat o(n), if you can take advantange of the hardware. Instead I get some mountain of stuff targeting "agents". Bah.
lampe3 3 hours ago [-]
funny how things come back.
I loved meteorjs and its still my fav framework to this day.
Seeing optimistic ui and browser based databases being used this way makes me happy.
I would like to understand how they do the chunking and only updating part of the graph instead all of it.
255kb 2 hours ago [-]
Had to scroll this far to see meteors being mentioned.
It was the first framework I started my js journey with.
And it was doing exactly what is described here, using a reimplementation of mongodb, in the frontend: minimongo.
AG342 3 hours ago [-]
I've always wondered how they made the UX so slick - thanks for sharing.
jeffbee 3 hours ago [-]
This is bizarrely laudatory. The app is fast because it is not correct. The user has no way to know if their view is consistent with any other user's view. The user has no way to know if the app silently discarded one of their inputs because of a conflict. Linear developers seem to believe that silent data loss is an acceptable cost for maintaining the illusion of speed.
rsingel 49 minutes ago [-]
I miss Pivotal Tracker
blauditore 3 hours ago [-]
TL;DR: Background syncing instead of synchronous updates to the cloud.
This is basically a thick client, and comes with according trade-offs. It's interesting and there are some best practices, but I can't help but feeling that either the author is a huge fan or the post is an ad (or "sponsored").
xiaoyu2006 3 hours ago [-]
I was expecting a post on how hardware accelerate linear algebra lol
joeyguerra 2 hours ago [-]
just one thing, this is not the simplest stacks you can find.
ArtRichards 3 hours ago [-]
They're doing some really cool stuff with Agents too.. automating software pm. it's a huge difference between this and their (unnamed) larger competitors.
ralferoo 3 hours ago [-]
I've never used linear, but just watching their example video [1] would worry me if I was a user and it's actually doing what they say it's doing.
He creates a task called "Create faster app launch", if we believe the article, it's processing that locally rather than going via the server, and then it's allocated an ID "BRO-5". That the ID is so low suggests it's just adding one to the previous issue ID, and so under heavy load, there are almost certainly going to be conflicts with other users creating tasks and getting identical IDs. Even if the system resolves this by changing one of those IDs, the system shouldn't be presenting the ID to the user until it is guaranteed unique. What if they've already pasted it into a document when the system notices the collision and renumbers it?
EDIT: WTH, there are some seriously bad karma people in this thread - just because I dared to have an opinion that the approach taken by this software might not be the best, my post was downvoted in less than a minute after posting! I'm sure whoever did that carefully considered my argument. If I'm wrong, explain why, don't just downvote my comment. If I'm not wrong, shame on you.
mpalmer 2 hours ago [-]
Did we need five thousand words (easily 1/3 of which didn't deal with the main topic) on techniques that aren't exclusive to Linear in the slightest?
callamdelaney 2 hours ago [-]
It’s webscale
0xbadcafebee 3 hours ago [-]
> 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
He chose the path to a better product rather than the path to a quick buck. That is definitely odd for a silicon valley startup
throwaway7783 2 hours ago [-]
Based on all the comments above, it is very debatable if it is a better product all said and done
bfung 2 hours ago [-]
Meta: so many words to say - save local first & sync in background.
Feels like AI slop.
Doesn’t address the concurrent update problem except for “optimistic”. At least provide some data why that’s ok.
4 hours ago [-]
MagicMoonlight 23 minutes ago [-]
[dead]
sieabahlpark 4 hours ago [-]
[dead]
Rendered at 23:05:51 GMT+0000 (Coordinated Universal Time) with Vercel.
1. type
2. stop to ponder for a split second
3. type some more
4. Linear reverts data to step 1
It's bad enough that I'll use Linear to create issues with a single sentence description. This is what Linear is good and fast at. Then I'll switch to GitHub to fill in the details.
It's really the only way for companies to survive and go up market, unfortunately.
For example, the search field only shows if you press "ctrl-f".
1. user clicks a button and closes the tab thinking transaction is done and it's important that transaction is done
2. conflict resolution is difficult or impossible in future client wake up
A background worker picks up the mutation and sends it to the remote backend. It takes time, retries, etc.
Similarly, any errors reported by the background worker go to local store, and the next time the UI tab is loaded / activated, they are shown. A service worker can show a notification outright to let the user easily load the main UI. Normally this would be a rare occasion.
More generally: You can't circument the trade-offs of a distributed database, which such products are, conceptually.
Main downside is it significantly complicates the front end code compared to just waiting for FE to sync with BE before updating
Though its depressing how few actually use it to its full extent. My team is one of the few where I work; heavy declarative mutation directives with optimisticResponse (and optimisticUpdaters because some of our APIs are not very Relay-compatible, annoyingly)
The reply with be delayed by days or weeks, but the UI indicated that it had been properly saved.
There's not. Browsers can delete "persistent" storage at any time.
https://developer.mozilla.org/en-US/docs/Web/API/Storage_API...
> If, for any reason, developers need persistent storage [...] they can do so by using the navigator.storage.persist() method of the Storage API.
This makes a request for guaranteed permanent storage ... which can be approved (or denied) by the user or by browser defaults.
You can never truly trust anything about a client because by definition you don’t control it
Strange that we can be so be polar opposites on this. You hate it, I would never write an app in any other way, ever again.
As a developer, I hated the article and many of the comments I read thus far because:
- Having clients and a server properly sync and not lose data in the event of a network failure amounts to having a consistent distributed system which is not easy to do, and the commenters don't seem to have understood that
- I hate having written a long document and then losing it because the sync code is buggy, so the previous point becomes even more important.
So reading many of the things here has been mildly infuriating.
That being said, none of these people are likely affiliated with Linear, and given the overall quality of the product I'm pretty sure it works properly.
So no violation of CAP theorem it just prioritises liveness over consistency
Yeah that's the issue isn't it? I see in the UI it's sent. But actually it's sent only the next morning.
To be fair. It's fine for an issue tracker. Anything actually important i'd spend a few seconds going over what I just sent. In which case I'd see it's not synced. And what's not that important it's really fine if in some random wifi edge case it's phantom sent. So makes sense.
E.g. if you buy a book, but it turns out the book was already sold, then you will first get a message "Your book is on its way!" and then "Oops, sorry, the book was already sold to someone else".
Eventual consistency is just a property of the database.
https://github.com/wzhudev/reverse-linear-sync-engine/blob/m...
Reverse engineering of Linear's sync engine - https://news.ycombinator.com/item?id=44123131 - May 2025 (33 comments)
Early days’ Trello was the best project tracking experience by far.
"A few milliseconds is all it takes to update an issue in Linear. A traditional CRUD app doing the same thing takes about 300ms."
"Any data sent between the client and server costs hundreds of milliseconds."
There’s no solving the problem of a large RTT between an HTTP client and server when it’s due to the speed of light.
But what you can do is locate the backend near users and make sure it’s fast.
For example, it’s very possible to run a web app backend within ~10ms RTT of most users and have the backend render responses within ~10ms too.
In other words, you can absolutely create a traditional CRUD app where doing the same thing takes more like 30ms, not 300ms.
Only if your users are all located quite close to each other, or (sadly very common) you only care about making it fast for US users and screw everyone else.
(Of course you can have "intermediary backends" around the world on a CDN's edge network or similar, but at that point you're paying the same complexity cost as this style of putting the "intermediary backend" on the client)
But the happy path stays lightning-fast.
My point above is that the simple solution ("traditional CRUD app") is actually viable even when the goal is very low latency.
What's crazier is they support this navigation key combo in their command palette but no where else.
The vim line nav is a nice thing in apps, but it's extremely frustrating I can't change it.
As for optimistic routes and "fast" - maybe we ought to talk gmail first?
HACKER NEWS is ran by a bunch of idiots that think karma is an actual thing, If this is so - then explain this?
300ms seems like a lot. Even if this includes the whole http request+response it still seems unbelievably long.
RTT from Hyderabad to the East Coast USA is ~300ms.
Then you have execution and database retrieval.
https://wondernetwork.com/pings
but the benchmark is similar software like JIRA, which takes agonizingly long to do anything reasonable.
Also I couldn't see any explanation of what happens when a network request fails. That's a huge downside of local rendering.
I think for most sites the best option is still server-side rendering but use a fast backend (e.g. not Python) and lightweight frontend.
One thing I would like to point out though is that building a performant sync engine that behaves the way you would like in most cases is a non-trivial thing.
If two users are offline and add, edit, remove issues and come online again, you need to reason about what happens. Sometimes you can get away with Last Writer Wins but what happens if an issue is deleted and then edited. What happens if an item in a list gets re-ordered differently on different clients, what's the final ordering? In which cases can you merge what state and in which do you need to discard something. Do you show a conflict resolution UI? How do you deal with rollbacks. How do you deal with schema drift and updates on items that would be affected by schema drift? Business logic might change between being reconnects. FK constraints can shift. Can you set up your data and the sync engine so that it only syncs the minimum amount of changes and batches them correctly during longer offline sessions so you don't fire 5000 change requests after reconnecting?
I recently had to implement local first + remote sync on some fairly complex dynamic forms and where luckily there is usually only one writer and I can get away with last writer wins and reject if things are too old or if there is schema drift and can just display an error message and roll back. But what I am trying to say is: Whatever can go wrong in an online-first world, can also go wrong in an offline first world but you might get informed of that all at once at a later time - or not at all and your data is not what you think it should be. Some sync engines like zero from rocicorp has opted out of supporting offline writes entirely because of all these problems.
And just to be clear: I love offline first approaches. I yearn for fast performance. And in a lot of cases slapping a sync engine on your app can really be helpful for that if your use case allows it. But it's absolutely crucial to be aware of the pitfalls that come with it.
based on my experience, this is a great description of the sync implementation in many already widely deployed products (say, off the top of my head, OneNote, OneDrive)
In the local first world you might have navigated away already and created 3 more issues of which 2 more failed because of schema drift or other conflicts. And you might have edited one that was deleted. And now you need to figure out what exactly to tell the user - or what not to tell them.
Warn the user that if they leave the website their changes won't be saved remotely.
I would not implement optimistic resolution in key information, prices, for example. They live in the server and backend should keep the total control in the client side, even feedback response time.
Bottom line is, if your app's content is behind a login screen, just use client side rendering. It is way lower complexity and a way better user experience.
Yes, I spent a few months. But it worth it. Every new field, model I need to add, it is so straightforward. I do love frameworks and foundations. They make live easier later by a lot.
https://m.youtube.com/watch?v=WxK11RsLqp4&t=2175s&pp=2AH_EJA...
These are original video. Very clear and a way better than the blog post.
https://performance.dev/skills
https://performance.dev/how-is-linear-so-fast-a-technical-br...
Whenever I use it, I don't feel like I'm doing anything new when compared to all the other issue trackers and Kanban boards I've used before.
A leader of 6 will spend a lot of time in such an app, so the UX is valuable and a differentiator for them.
I am genuinely impressed with their engineering and design — I aspire to attain these levels, though I lack not only the skills, but also several zeroes in my bank account, I think. Still, it's worth looking at what they do and try to get there!
Big props and kudos to the Linear team. It's an impressive app.
I was thoroughly unimpressed. "This is it?" - "It's a tracker"
I feel comfortable saying this because in the weeks after, actually using it is the aha experience. Linear nailed the UX of working where people already work. Which again is really funny because the best part of Linear is how well it works outside of Linear.
(disclaimer: I actually now use their UI a lot. It's a helpful dashboard. But it suffers from every other hard-problem of information dense task-based dashboards.)
Seriously, I hate it, but I've worked in most other competing products, from Trello to Azure Devops to Linear, Jira is a much more powerful engine that can be easily adapted to large organizations where each team has very different processes.
What works for a software team, does not work for sales, which does not work for HR, which does not work for QA or business development. Jira is flexible enough that can accomodate any kind of operation. Linear is like a very small and catchy subset of it.
IMO a good approach is to update the UI immediately but still show some indication that the operation hasn't completed. So in a chat app, for example, add the message to the list of messages, but with contrast reduced slightly to indicate that other people can't see it yet.
Meanwhile after a brief period of Jira being performant, it has felt into ruin again.
In any case, I've tried both, and Jira is on another whole level when it comes to map processes of different teams.
Linear is a good looking toy mostly catered to the average software engineering team, it just doesn't support the flow complexity needed by different business units.
https://github.com/tinyplex/tinybase seems kinda good maybe?
I loved meteorjs and its still my fav framework to this day.
Seeing optimistic ui and browser based databases being used this way makes me happy.
I would like to understand how they do the chunking and only updating part of the graph instead all of it.
And it was doing exactly what is described here, using a reimplementation of mongodb, in the frontend: minimongo.
This is basically a thick client, and comes with according trade-offs. It's interesting and there are some best practices, but I can't help but feeling that either the author is a huge fan or the post is an ad (or "sponsored").
He creates a task called "Create faster app launch", if we believe the article, it's processing that locally rather than going via the server, and then it's allocated an ID "BRO-5". That the ID is so low suggests it's just adding one to the previous issue ID, and so under heavy load, there are almost certainly going to be conflicts with other users creating tasks and getting identical IDs. Even if the system resolves this by changing one of those IDs, the system shouldn't be presenting the ID to the user until it is guaranteed unique. What if they've already pasted it into a document when the system notices the collision and renumbers it?
[1] https://media.performance.dev/posts/p_gAMR6Z7y49Fp/NZrXs70M_...
EDIT: WTH, there are some seriously bad karma people in this thread - just because I dared to have an opinion that the approach taken by this software might not be the best, my post was downvoted in less than a minute after posting! I'm sure whoever did that carefully considered my argument. If I'm wrong, explain why, don't just downvote my comment. If I'm not wrong, shame on you.
He chose the path to a better product rather than the path to a quick buck. That is definitely odd for a silicon valley startup
Feels like AI slop.
Doesn’t address the concurrent update problem except for “optimistic”. At least provide some data why that’s ok.