HN user

andersmurphy

938 karma

https://andersmurphy.com

Posts11
Comments433
View on HN

Maybe maybe not. In large organisations for each person creating value with LLMs there are probably more destroying value. Bob used to only waste one person time with LLMs he can waste the entire organisations time.

Anyone can use an LLM make a bad ideas sound like a good idea. I imagine this will lead to insane amounts of productivity loss as the entire organisation ends up pivoting to follow the bad idea of a mediocre VP etc.

Lisp/smalltalk programmers have been going on about this tradeoff for a long time. It mattered before LLMs too. Lisp/Clojure repl allowing you to compile tiny parts of your program inside your running program is incredible for your feedback/iteration loop.

Ironically, this is also what makes them shine with LLMs, the LLM has access to the running program and can modify it while it's running to get feedback instantly.

Complex type systems are cool. But, they are not free. I say this as someone who's first programming language was Haskell.

Yeah, it's an intellectually intoxicating idea but incredibly hard to get right.

For me the problem is that in practice it only fits really well with quite a specific subset of problems, but we desperately want it to be a general solution that can apply to all the things (or at least it's often marketed that way).

Generalization breaks down for offline-capable applications. Offline writes require conflict resolution, create authorization edge cases, and demand coordinated schema management across server and client replicas.

...These constraints are structural; engineering effort cannot remove them...

The trade-off analysis shows that three sync engine vendors converged independently on this conclusion from different starting positions.

This is the big irony. That the vendors all converged on the fact that sync engines only really "work" when you remove the offline part. But, at that point they are a complicated/over engineered cache or worse introducing hard distributed computer science problems unnecessarily.

User permission can often be very dynamic. Sync engines (local first ones even more so) give them access to a much larger set if that data in a client side database.

This also makes them much more vulnerable to a data leak/breach if their device gets compromised or stolen as the data is all on their device.

The client having access to only what it needs in terms of data and making that as ephemeral as possible is a big part of defence in depth.

Sync engines are fast to a point but if you start working with large enough datasets and/or care about security you ultimately end up with something closer to streaming immediate mode HTML. Of course that means sacrificing local first.

I've updated the article with the correct rowid alias (integer not int) so the rowid version is now 715ms. I've also added an example of rowid and a secondary index UUID4, and that also seems to be bad for performance (as although it's not a clustered index it's still random inserts into a b-tree).

That's a good question. I don't know the answer. I will say, generally you can get higher write throughput with a single writer. Even more so if you're prepared to shard along boundaries where you don't need atomic transactions.

Contention and coordination are real killers, concurrent writes (that require coordination like postgres) often underdeliver.

Yes this matters even more if you are doing a lot of joins. Naive string UUIDs are 32 bytes (though I use binary uuid in the post which is 16) compared to 8 bytes for a 64-bit int. This matters even more with sqlite as it uses varint encoding. The upshot of all this is your indexes take up a lot less space in memory.

Yes it's writing to disk (on a M1 mac which has terribly slow fsync). But, because of the transaction the fsync dance is done once per batch. Each row is the id + a 50 byte data blob.

There's only one index so there's no real write amplification. The numbers will go down as you add more data and indexes.