[HN Gopher] Stop building databases
       ___________________________________________________________________
        
       Stop building databases
        
       Author : thunderbong
       Score  : 234 points
       Date   : 2023-12-01 17:19 UTC (5 hours ago)
        
 (HTM) web link (sqlsync.dev)
 (TXT) w3m dump (sqlsync.dev)
        
       | yewenjie wrote:
       | Is this supposed to be run on the server? Then how does it really
       | solve the frontend side of issues, I'm just trying to understand.
        
         | ranting-moth wrote:
         | I sometimes see interesting links on HN but when I click on
         | them and skim through, I still have no idea what exactly it
         | does. This is one of them.
        
         | hk__2 wrote:
         | It's not exactly clear in the article, but there is a client
         | part:
         | https://github.com/orbitinghail/sqlsync/blob/main/GUIDE.md
         | 
         | > Step 2: Install and configure the React library
        
         | jokethrowaway wrote:
         | Not involved with the project but - this is a database which
         | run client side and sync with a database on the server
        
           | carlsverre wrote:
           | Precisely! The same database (SQLite) is running on both the
           | client and the server. SQLSync provides a custom storage
           | layer to SQLite that keeps everything in sync. As changes are
           | made locally (optimistically) they are synced into the cloud
           | where they are eventually applied to the primary db replica.
           | The clients subscribe to changes from the primary db and then
           | rebase themselves to stay in sync.
           | 
           | I really need to write up a detailed overview of how this
           | works! Thanks for the feedback!
        
       | HatchedLake721 wrote:
       | Unless I misunderstood, feels like I've been doing this with
       | Ember Data since ~2013.
       | 
       | https://guides.emberjs.com/release/models/
       | 
       | There's also https://orbitjs.com/
        
         | no_wizard wrote:
         | Ember.js has had more innovations contributed to modern
         | framework ideas than any other framework, really.
         | 
         | EmberData, Ember Routing, Ember Multi Applications (can't
         | remember what its called, but its a precursor to
         | microfrontends) all in one CLI tooling etc.
         | 
         | I could never understand what holds Ember back from being more
         | used. I think it used to be performance but I think they
         | addressed that with Glimmer many years ago.
        
         | robocat wrote:
         | I think you have misunderstood?
         | 
         | The article is responding to the pattern of yet another custom
         | data model and custom data API (a la Ember).
         | 
         | Instead provide an SQL database (the well proven SQLite) within
         | the front end and use SQL to interact. And sync data from-to
         | the backend DB.
         | 
         | Which one could then slap on a model or ORM layer on top of -
         | should that be one's bent.
         | 
         | It isn't clear how they manage the subscription to data
         | updates/inserts/deletions - it mentions supporting triggers,
         | but that feels icky to me.
        
           | carlsverre wrote:
           | First, thanks!
           | 
           | > It isn't clear how they manage the subscription to data
           | updates/inserts/deletions - it mentions supporting triggers,
           | but that feels icky to me.
           | 
           | Architecture post coming soon. In the meantime, I want to
           | clarify that SQLSync does not use triggers for sync. Instead,
           | I hijack SQLites page storage and added page replication to
           | it. Writes are consolidated through an API I call the
           | "reducer" which allows SQLSync to keep track of which logical
           | writes correspond to which sets of page changes. The actual
           | sync is pretty dumb: we run the reducer on both the client
           | and the server. The client replicates down server pages, and
           | then periodically throws out local changes, resets to the
           | server state, and then replays any mutations that haven't yet
           | been acked on the server.
        
             | frenchman99 wrote:
             | You say things like "X is pretty dumb" and then go on
             | saying stuff I don't understand. Pretty annoying if you ask
             | me.
             | 
             | And that's despite me having worked with Cassandra, Kafka,
             | Postgres and a variety of programming languages, DevOps
             | tools, having worked with Vuejs and React.
        
               | mst wrote:
               | Could you clarify which of:
               | 
               | - page storage
               | 
               | - reducers
               | 
               | - replaying mutations
               | 
               | - acks
               | 
               | you're unclear on?
        
       | matlin wrote:
       | I'm currently writing a very similar article about "full-stack
       | databases" which highlights the same pattern where many apps end
       | recreating the logic of our backend and database in the frontend
       | client code. The solution we're promoting is to choose a database
       | that can run on both the server and in the client and then sync
       | between them.
       | 
       | The reason we aren't using Sqlite for our product is because Sql
       | is frankly not the right tool for querying data for an
       | application. It doesn't easily map to the data-structures you
       | want in your client code and nearly all SQL databases have no way
       | to subscribe to changes to a query without polling the query
       | repeatedly.
       | 
       | So if you like the idea of having a complete database on your
       | client but also want deep integration with Typescript/Javascript
       | check out what we're building at https://github.com/aspen-
       | cloud/triplit
        
         | johnny22 wrote:
         | postgres has some capability to do that, but does need a
         | server.
        
           | matlin wrote:
           | Yeah you can subscribe to overall changes to the data on a
           | row by row basis but can't subscribe to an actual query. Many
           | apps and libraries imitate reactive queries by just
           | refetching all queries from Postgres when any data changes or
           | just repeatedly polling the query every 10 seconds or so but
           | this puts a lot of strain on the database. You can just
           | subscribe to the replication stream but then you're left
           | trying to reconstruct your queries in your application code
           | which is extremely error prone and painful
        
         | culi wrote:
         | I like the implications of this to a "local first" architecture
        
       | pqdbr wrote:
       | Can someone explain me how it's syncing the state between two
       | different devices without any activity in the Network tab in
       | DevTools, not even WS traffic?
       | 
       | I get that you can sync state between browser tabs, but I'm
       | trying on two different devices (iPhone and Desktop).
       | 
       | And as far as I can tell, the Wasm layer can't perform network
       | requests directly.
       | 
       | UPDATE: In the console tab I can see 'coordinatorUrl:
       | 'wss://sqlsync.orbitinghail.workers.dev', but I was expecting to
       | see this Websockets connection in the Network tab, and it isn't.
        
         | jasonjmcghee wrote:
         | Websockets tracking in the browser can be weird. Try refreshing
         | the page while you have WS selected in the Network tab
        
           | pqdbr wrote:
           | I did that!
        
         | carlsverre wrote:
         | Good catch! SQLSync runs in a shared worker to enable cross-tab
         | reactivity and centralise both local storage and the
         | replication system. You can inspect the worker at the magic
         | url: chrome://inspect/#workers
        
       | tootie wrote:
       | The thing I've used for this kind of problem is fusejs which is a
       | lightweight search index. You can load it with a list of JSON
       | documents and do structured or fuzzy string searches. I find it
       | pretty well-suited to the kind of frontend experiences I need a
       | lot of data for.
        
         | carlsverre wrote:
         | This is cool! Thanks for sharing. Sounds like Fuse would be a
         | great solution for a read-only index. But what if you want to
         | collaborate on the data with other people?
         | 
         | FWIW check out SQLite's full text search extension:
         | https://www.sqlite.org/fts5.html
        
       | recusive_story wrote:
       | Local to a webpage, do you feel building wrapper over indexedDB
       | instead of sqlite would be better idea?
        
         | carlsverre wrote:
         | That's a great way to accomplish local storage, but requires a
         | bit of gymnastics to build sync. By controlling the database
         | entirely, SQLSync can provide very ergonomic sync to the
         | developer and performance for the user.
         | 
         | So it's not that one is better than the other. Just the
         | capabilities, performance, and test-ability differs.
        
       | bob1029 wrote:
       | Trying to synchronize state between client & server is a cursed
       | problem.
       | 
       | You can sidestep it altogether if you make mild UX sacrifices and
       | revert to something more akin to the PHP/SSR model. SPA is nice,
       | but multipart form posts still work. Just the tiniest amount of
       | javascript can smooth out most of the remaining rough edges.
       | 
       | Our latest web products utilize the following client-side state:
       | 3rd party IdP claims for auth       1st party session id in query
       | args       The current document
       | 
       | For the first item, I genuinely don't even know where this is
       | stored. It's Microsoft's problem, not ours. All other state lives
       | on the server. We treat the client more or less like a dumb
       | terminal that punches <form>s all day. We don't even use first
       | party cookies or local storage to get the job done. This
       | dramatically improved our development experience for iOS/Safari
       | targets.
       | 
       | So, I would ask this: What is the actual experience you are
       | trying to offer, and why does it justify decoupling of client &
       | server state?
        
         | threatofrain wrote:
         | It's a very common trend for consumer-facing GUI's to have
         | optimistic rendering, and if you're doing that then you're
         | juggling client/server state. I still see spinning loaders here
         | and then but they're generally for initial content load; e.g.,
         | does Gmail make you wait when you archive an email?
        
           | _heimdall wrote:
           | Not the GP, but I would include optimistic rendering on the
           | list of common patterns that really are a bad idea.
           | 
           | Optimistic rendering means your frontend and backend are
           | tightly coupled, error recovery and synchronization is much
           | more complex, and you are locked into (likely heavy) frontend
           | rendering patterns that add even more complexity and
           | coupling.
           | 
           | We've spent well over a decade trying to avoid the fact that
           | frontend actions require backend logic to complete. Its a
           | losing battle that's just made worse by trying to paper over
           | it.
           | 
           | Edit to clarify: this isn't a direct comment on the OP tool.
           | I haven't used this tool directly but having a hunch it does
           | solve some important use cases for common patterns.
        
         | obeavs wrote:
         | ElectricSQL has made massive strides towards solving this fwiw.
         | Write sqllite in client, guarantee sync to postgres.
         | 
         | See: https://news.ycombinator.com/item?id=37584049
        
       | athrowaway3z wrote:
       | This looks interesting and i might give it a try, but after
       | watching the talk i'm still a bit unclear why you choose for
       | wasm-in-wasm for the reducer.
       | 
       | I suspect you would be better off by creating a rust reducer
       | trait, and lifting that wasm-in-wasm complexity into a new crate
       | implementing the reducer trait through wasm-in-wasm for the
       | people who want that.
       | 
       | But maybe i'm missing something.
        
         | carlsverre wrote:
         | Totally fair question. Nothing is set in stone - but this
         | approach made it very easy for me to run precisely the same
         | code on both a generic backend (CloudFlare Durable Objects) and
         | in the frontend stack.
         | 
         | As for wasm-in-wasm specifically. It would be nice to
         | experiment with the component model to load reducers alongside
         | SQLSync - but the UX isn't quite there yet.
        
       | 0xbadcafebee wrote:
       | Anyone remember when "frontend applications" were actual
       | applications and not web pages? I'm willing to bet we have
       | reached that point where new devs literally do not remember that
       | time.                 There comes a time [..] where we [..] need
       | to cache data from an API. It might start off benign - storing a
       | previous page of data for that instant back button experience,
       | implementing a bit of undo logic, or merging some state from
       | different API requests.
       | 
       | The browser is annoying to control, so you're trying to make
       | javascript jump through hoops to do what you want...
       | SQLSync is [..] designed to synchronize web application state
       | between users, devices, and the edge.
       | 
       | So you want your stateless application to be stateful, to sync
       | that state with some other state, so you can cache data easier,
       | so you can make the browser pretend it's not a browser.
       | 
       | Can we not just admit the browser is a shitty client app? I get
       | that like 50% of the software developers in the world have made
       | the browser their literal livelihood and career, but jesus
       | christ, we need to end this madness. Either make a full blown VM
       | and just write normal client applications that run in it, or stop
       | trying to make client applications out of javascript.
       | 
       | It's insane how much of the world's engineering effort and
       | technology investment money has gone into putting lipstick on a
       | pig. If we took all the money invested in browser ecosystems and
       | put it towards spaceflight, we'd be living on Mars right now.
        
         | neilk wrote:
         | You're not wrong, but the web won because it had a superior
         | delivery system: URLs. Everything weird about the web era of
         | development has been about contorting everything to be URL-
         | oriented.
         | 
         | But consider how WASM is now turning the browser into an app
         | delivery client. Not a "html and json bodged into an app", but
         | a real honest to god app.
         | 
         | This project happens to be browser based because that's
         | convenient place to put a WASM app, and it has a decent
         | presentation layer. But it doesn't have to be!
        
           | maclockard wrote:
           | Not just delivery, but also security. Browsers offer a level
           | of isolation and safety that you generally don't get with
           | native desktop apps. Things like iOS do bridge the gap a bit
           | more though
        
             | DaiPlusPlus wrote:
             | > Browsers offer a level of isolation and safety that you
             | generally don't get with native desktop apps.
             | 
             | They didn't originally: Java <applets> and ActiveX
             | <objects> originally weren't sandboxed and had free run of
             | the visitor's computer.
             | 
             | All major OSes today now have built-in support for
             | process/app sandboxing. I suppose if the "rich client"
             | frontend model (WPF, etc) was more popular then I expect
             | desktop OS application isolation to have been introduced
             | much sooner.
             | 
             | Security development happens where the market demands it,
             | and rarely does it happen where it's actually needed.
        
               | e_y_ wrote:
               | I can't speak for ActiveX since I avoided IE like the
               | plague, but Java applets were sandboxed. Just that the
               | sandbox had a lot of holes.
        
               | DaiPlusPlus wrote:
               | Huh - you're right: http://www.securingjava.com/chapter-
               | two/
        
         | maclockard wrote:
         | > make the browser a full blown VM and just write normal
         | programs that run in it
         | 
         | This is actually happening, albeit slowly, with recent efforts
         | around WASM etc. If you want a fun hypothetical of where this
         | all goes, check out the talk "The Birth & Death of JavaScript".
         | Link here: https://www.destroyallsoftware.com/talks/the-birth-
         | and-death...
        
         | mhaberl wrote:
         | > Anyone remember when "frontend applications" were actual
         | applications and not web pages?
         | 
         | I do. And also I remember building those apps. It was not as
         | simple as building webapps today.
         | 
         | Yes, there are downsides to this model (a lot of them) BUT you
         | can whip up a simple app with a beautiful UI in a couple of
         | hours today. It was not like that 25 years ago.
        
         | rglover wrote:
         | > It's insane how much of the world's engineering effort and
         | technology investment money has gone into putting lipstick on a
         | pig.
         | 
         | I'm a JavaScript developer and yes, this is deeply disturbing.
         | Even more so after I built a framework [1] that just copycats
         | what PHP/Rails does (treat the server like a server, and the
         | client/browser like a client--no SPA spaghetti). It works, it's
         | fast, and makes development 100x easier.
         | 
         | I applied the same heuristic to deployments, eschewing all of
         | the containers dogma and lo and behold, you can achieve great
         | performance (and iterative speed) with old school, minimal tech
         | (bare metal/VPS and just install deps and code directly on the
         | machine).
         | 
         | [1] https://github.com/cheatcode/joystick
        
         | bradley13 wrote:
         | History doesn't repeat itself, but it does rhyme. One upon a
         | dark age, we had mainframes and dumb terminals. Then came the
         | first age of the PC - let's pull everything to the client. Then
         | came servers and "thin clients". With faster processors and
         | cheaper storage came the second age of the PC, with only the
         | permanent data storage left on the server. As the Internet
         | grew, centralization came back: web services and the cloud,
         | with clients just serving dumb web pages.
         | 
         | And now we see the beginning of a migration back to client-side
         | computation and storage.
         | 
         | Somehow, though, this latest iteration doesn't make a lot of
         | sense. It's hard enough maintaining data consistency on a web
         | service that may be used by hundreds or thousands of people.
         | Imagine when this data is cached in microdatabases in
         | unreliable browsers.
         | 
         | On top of that, the browser makes an absolutely horrible
         | programming environment for client-side apps. For the
         | programming part, Javascript is an poor language, so you wind
         | up using heavy-duty frameworks like React to make it tolerable.
         | For the UI representation, that's just not what HTML/CSS were
         | ever meant for. So you get frameworks there as well. Young
         | developers think this is just the way it is. No actually, it's
         | more like the worst of all possible worlds. Using something
         | like JavaFX or (I know, I know) even Visual Basic, you can
         | produce a functional, robust UI with a tiny fraction of the
         | effort.
        
           | PH95VuimJjqBqy wrote:
           | years and years ago on a C++ forum someone made an
           | observation that was eerily similar to yours. I still
           | remember it to this day as it stuck in my head.
           | 
           | They made an observation that our industry goes in cyclical
           | centralize/de-centralize cycles and that we we were (at the
           | time) entering into a centralization cycle.
           | 
           | Now here I am reading a comment that we're going back into a
           | de-centralization cycle and I wouldn't be surprised if you're
           | the same poster.
           | 
           | probably 15-20 years ago (maybe more?) I made a prediction
           | that I still think will come true.
           | 
           | The OS will become the "browser" and applications will run
           | directly on the OS and will access local resources through
           | standardized interfaces. WebAssembly and things like WebGL
           | are already moving us in that direction. Honestly HTML5 was
           | the first time I recognized standard updates as moving us
           | towards that reality with things like localStorage, etc.
           | 
           | I honestly think if someone more imaginative had the helm at
           | MS when the cloud started getting big they would have eaten
           | google's lunch by leveraging their desktop dominance into the
           | web. Instead they dd inane things like display websites on
           | the desktop (win98 IIRC).
        
             | bradley13 wrote:
             | Could be - I've been making this observation for a long
             | time. The cycles keep going. On the other hand, probably
             | lots of other people have commented on it as well...
             | 
             | You may be right about the browser becoming the OS.
             | Chromebooks were already a step in that direction. But
             | JS/HTML/CSS really is a horrible combination for
             | application programming. If the browser does become the OS,
             | can we please get decent technology to work with?
        
               | PH95VuimJjqBqy wrote:
               | I expect we'll get back to native applications and move
               | away from js/html/css.
        
         | PH95VuimJjqBqy wrote:
         | I completely agree with you, I'm going to copy part of another
         | comment I made
         | 
         | -----
         | 
         | probably 15-20 years ago (maybe more?) I made a prediction that
         | I still think will come true.
         | 
         | The OS will become the "browser" and applications will run
         | directly on the OS and will access local resources through
         | standardized interfaces. WebAssembly and things like WebGL are
         | already moving us in that direction. Honestly HTML5 was the
         | first time I recognized standard updates as moving us towards
         | that reality with things like localStorage, etc.
         | 
         | I honestly think if someone more imaginative had the helm at MS
         | when the cloud started getting big they would have eaten
         | google's lunch by leveraging their desktop dominance into the
         | web. Instead they did inane things like display websites on the
         | desktop (win98 IIRC).
         | 
         | -----
        
         | Hammershaft wrote:
         | I totally agree! I would love a VM designed for development
         | simplicity & performance that is built with a standard protocol
         | & interface for accessing arbitrary VM applications over the
         | net.
        
         | msie wrote:
         | What I find annoying is the still-existing problem that
         | sometimes apps don't load properly and you have to refresh the
         | browser. You don't get this with desktop apps. There are some
         | caching capabilities in browsers but they are not being used by
         | anyone to cache app code and resources. If I'm using an app for
         | the first time it should properly load all code and resources
         | or else report an error.
        
         | msie wrote:
         | I won't forget that someone at Google didn't have the courage
         | to enable Dart in Chrome as a successor to Javascript. And
         | someone killed SQLLite as a in-browser db.
        
       | neilk wrote:
       | I'm familiar with this project - the creator is a friend. I'll
       | try to get him on here to answer questions.
       | 
       | He's a seasoned database architect. With SQLsync he's made a way
       | for frontend developers to query and update a remote database as
       | if it was completely located right in the browser. Because it
       | basically is. The power of WASM makes it possible to ship a whole
       | SQLite database to the browser. The magic is in how it syncs from
       | multiple clients with a clever but simple reactive algorithm.
       | 
       | It's a radical attack on the whole problem. Much of our work as
       | developers is about syncing data. When you start looking at React
       | and REST APIs as a kind of sync procedure, this approach can open
       | a lot of new possibilities. You don't have to write a weird
       | bespoke database of trees of objects fetched and cached from the
       | API any more. You can just update and query it locally, with all
       | the power of a relational database.
        
         | giancarlostoro wrote:
         | Genuinely curious why not just cache the relevant bits in
         | LocalStorage / SessionStorage? I seem to remember Chrome trying
         | to add a literal SQL database to the browser, but it never
         | panned out, localStorage became king. I don't mean to downplay
         | the usefulness, just I usually opt for what the browser gives
         | me. I'm huge on WASM and what it will do for the browser as it
         | matures more (or grows in features).
        
           | no_wizard wrote:
           | IndexDB is even better, it supports a wider variety of data
           | serialization, can be queried and versioned
        
           | carlsverre wrote:
           | Good question.
           | 
           | First to address the main point: why not cache the relevant
           | bits in some kind of local storage. SQLSync plans on doing
           | this, specifically using OPFS for performance (but will have
           | fallbacks to localstorage if needed).
           | 
           | Second to address the question of why not use built in kv
           | stores or browser side databases. One answer is another
           | question: how do you solve sync?
           | 
           | One approach is using a data model that encodes conflict
           | handling directly, like CRDTs. This approach is easier to put
           | into general kv stores, as syncing requires simply exchanging
           | messages in any order. I find this solution is well suited to
           | unstructured collaboration like text editing, but makes it
           | harder to coordinate centralised changes to the data.
           | Centralised changes are nice when you start introducing
           | authentication, compaction, and upgrades.
           | 
           | Another approach is doing something similar to how Git Rebase
           | works. The idea is to let the application state and server
           | state diverge, and then provide an efficient means for the
           | app to periodically reset to the latest server state and
           | replay any unacked mutations. This approach requires the
           | ability to re-run mutations efficiently as well as
           | efficiently track multiple diverging versions of the database
           | state. It's certainly possible to build this model on top of
           | local storage.
           | 
           | For SQLSync, I found that by controlling the entirety of
           | SQLite and the underlying storage layer I was able to create
           | a solution that works across platforms and offers a fairly
           | consistent performance profile. The same solution runs in
           | native apps, browser sessions (main thread or workers), and
           | on serverless platforms. One of my goals is to follow the
           | lead of SQLite and keep my solution fairly agnostic to the
           | platform (while providing the requisite hooks for things like
           | durable storage).
        
           | justincormack wrote:
           | There is a literal SQL store in the browser its the sqlite
           | Wasm port. Its just panning out a little differently.
        
           | LamaOfRuin wrote:
           | FWIW, Web SQL was always fine, but could never be
           | standardized, because no one was ever going to redo all the
           | work sqlite has done (when every browser already uses
           | sqlite).
           | 
           | https://en.wikipedia.org/wiki/Web_SQL_Database
        
             | LAC-Tech wrote:
             | Firefox fought against WebSQL. Firefox then re-implemented
             | indexedDB with SQLite on their own browser. Firefox has now
             | largely faded into obscurity.
        
               | Moomoomoo309 wrote:
               | Tbf, the WebSQL standard was not well-written from how
               | I've heard that story told. It was bug-for-bug exactly
               | standardized to a particular version of SQLite, which is
               | not a good way to write a standard.
        
           | wouldbecouldbe wrote:
           | Because if this works it's amazing. Realtime sync with
           | offline support out of the box, while not having to develop
           | state management on client and api, but in one place. Those
           | are very hard problems, done with less development. Will
           | definitely give it a shot.
        
         | commonenemy wrote:
         | That sounds awfully like Couchbase, which allows you to
         | query/update databases that will sync to remote and the back to
         | peers. And you can control the process (auth/business logic)
         | with sever side JavaScript plugin with ease.
        
           | jchanimal wrote:
           | Creator of Couchbase Mobile here -- I'm doing a new web-based
           | thing[1] with a similar reactive API. I'm hoping that my
           | encrypted block replication makes it more of a "data
           | anywhere" solution than a "local first" database. But the
           | paradigm of powerful databases in the browser is definitely
           | one I'm glad to see becoming popular.
           | 
           | [1] https://fireproof.storage/
        
       | padjo wrote:
       | Many times the thought "what if we just shipped the database to
       | the client" has crossed my mind in large multi tenant apps where
       | individual datasets were relatively small. I've never gone far
       | with it as it seems sufficiently outside the norm to be a cursed
       | architectural pattern. Would be nice to find out I was wrong.
        
         | carlsverre wrote:
         | I'm also interested to find out if it's cursed :) So far it's
         | been a lot better than I expected. Apps like https://sqlsync-
         | todo.pages.dev are trivialised with this pattern.
         | 
         | Tons of work to do in order to really prove it out though. But
         | I'm pretty excited to keep pushing and see where this goes.
        
       | nikita wrote:
       | My understanding is that we can sync any sqlite state to any
       | other sqlite state using custom built replication.
       | 
       | Is this how it works and how does it update all the web
       | components?
       | 
       | Would it work with all the frameworks or a custom framework is
       | needed?
        
         | carlsverre wrote:
         | That's the dream! Currently SQLSync wraps SQLite in a fairly
         | heavy weight way as it needs to both intercept the storage tier
         | (to replicate page changes) as well as the mutation layer (to
         | provide the reducer api). I'm interested in making it lighter
         | weight and perhaps a regular SQLite extension you could install
         | into any instance of SQLite.
         | 
         | As for the web integration, SQLSync works with any framework
         | but currently only ships with a React library. Most of it's
         | logic is framework agnostic though.
         | 
         | SQLSync also provides a query subscription layer that is table-
         | level reactive. What this means it that the client API can
         | subscribe to a query which will automatically re-run when any
         | table dependencies change. I'm exploring more granular
         | reactivity, however for many datasets re-running on table
         | change is sufficient when coupled with OLTP query patterns and
         | small-medium sized data.
        
       | lifeisstillgood wrote:
       | Don't give the user a mental model that reality can break ...
       | badly, or invisibly
       | 
       | I fear sync'ing databases instead of client server models is one
       | of those - either your sync mechanism will just melt, or there
       | are deep assumptions not met
       | 
       | Inwoukd feel safer building a set of CRDT primitives to work with
       | if I feel the need for fast UI and stick with forms submit for
       | everything else -
        
         | carlsverre wrote:
         | I agree! One of my goals is to make the mental model of SQLSync
         | easy to grok for the developers using it. I'm biased, but I
         | find the rebase model much easier to understand than CRDTs.
        
       | cdchn wrote:
       | Give someone state and they'll have a bug one day, but teach them
       | how to represent state in two separate locations that have to be
       | kept in sync and they'll have bugs for a lifetime -ryg
        
         | hughesjj wrote:
         | Collollary: if you don't represent state in more than one
         | place, you'll eventually run into loss of availability
         | (accessibility), integrity, of existence of data
         | 
         | Thus, bugs forever is a given.
        
           | Waterluvian wrote:
           | Best to have one less major level of abstraction where that's
           | happening then.
        
         | TravisCooper wrote:
         | This is the proper take
        
         | CharlesW wrote:
         | After a bit of digging I learned that RYG is this person, for
         | anyone else who's curious: https://fgiesen.wordpress.com/about/
        
       | svilen_dobrev wrote:
       | i used couchdb (on server, with touchdb on android and ios,
       | pouchdb on web, ..) for this kind of thing. Clients were directly
       | connected to cursors over the localdb. How and when that localdb
       | was exchanging data with server-or-others, was not any more
       | Client's problem :)
        
       | garaetjjte wrote:
       | Does it needs to download whole database on startup, or can sync
       | only what client queried?
        
         | carlsverre wrote:
         | Currently it's full db sync. Partial replication is in
         | research.
        
       | m9t wrote:
       | Offline/local-first based on SQLite seems hot right now. Third
       | one I'm reading about this week. And it sounds good to me!
       | 
       | But how does it compare to ElectricSQL[1] and PowerSync[2]?
       | 
       | [1] https://electric-sql.com/ [2] https://powersync.com/
        
         | carlsverre wrote:
         | Indeed it's a very hot space! So exciting to see all the
         | different approaches.
         | 
         | ElectricSQL and PowerSync are both tackling the very hard
         | problem of partial replication. The idea is to build a general
         | solution which allows a traditional centralized db to
         | bidirectionally sync only what's needed on the client side -
         | while still supporting optimistic mutations (and all the
         | consistency/conflict stuff that goes along with that).
         | 
         | The downside is implementation complexity. Both require the
         | ability to keep track of precisely the set of data on each
         | client in order to push out changes to only that subset of the
         | overall database. In addition, specifying which subsets of the
         | database state to pull down requires a new DSL and is a new
         | thing to learn (and optimize). That said, I'm stoked they are
         | taking on this extremely hard problem so when SQLSync is ready
         | for partial replication someone will have already figured out
         | the best practices.
         | 
         | SQLSync, on the other hand, only supports full db sync. So
         | every client will see a consistent view of the entire database.
         | You might immediately wonder if this is a good idea - and for
         | some apps, it's not. But consider a personal finance app. The
         | main goal is cross device sync, cloud backup, offline capable,
         | etc. In this case having the entire db stored on every device
         | is probably what you want. Another example is a document
         | oriented data model, such as Airtable. Each Airtable could be a
         | distinct database, thus leaving it up to the client to manage
         | which tables they care about.
         | 
         | (added in edit:) By focusing on full db sync, the sync engine
         | is much simpler than solutions that support partial
         | replication. One benefit of this is that the backend is very
         | lightweight. Currently the demo (https://sqlsync-
         | todo.pages.dev) runs entirely within Cloudflare Durable Objects
         | using very little storage and CPU time.
         | 
         | SQLSync has a ton of work to do to make these use cases
         | possible (still very much a prototype), but my initial tests
         | have been extremely promising. Hope this helps!
         | 
         | (edit: clarified language regarding centralized dbs and full db
         | sync. Also added paragraph regarding full db sync)
        
           | goleary wrote:
           | >But consider a personal finance app. The main goal is cross
           | device sync, cloud backup, offline capable, etc. In this case
           | having the entire db stored on every device is probably what
           | you want.
           | 
           | A bit confused by this. If I'm a developer of a PFM, I don't
           | want anything but a single user's financial data synced to
           | their device. This sounds like partial replication to me.
        
             | carlsverre wrote:
             | Precisely. In the SQLSync model - every user would have a
             | private database just for their data. For example, this is
             | how the todo list demo works: https://sqlsync-
             | todo.pages.dev
             | 
             | (Note: currently SQLSync's server tier doesn't support
             | auth, just random 128bit ids. Auth will come as it matures
             | - but don't use this for anything super secure at the
             | moment).
        
           | rococosbasilisk wrote:
           | Phillip from PowerSync here, always good to see more people
           | working on problems in this space.
           | 
           | A few things to clarify:
           | 
           | > _one multi-tenant centralized db to bidirectionally sync_
           | 
           | PowerSync supports syncing from multiple databases.
           | 
           | > _The downside is complexity._
           | 
           | I'd say this is true if you're building a partial replication
           | system yourself. PowerSync gives you a ready-built system
           | that's been proven at scale and therefore lets you avoid most
           | of that complexity.
           | 
           | > _SQLSync, on the other hand, is full db sync._
           | 
           | It's just as easy to sync the full db with PowerSync as do
           | partial sync.
           | 
           | Edit: formatting
        
             | carlsverre wrote:
             | Thanks for the clarifying points Phillip. I'm a big fan of
             | PowerSync! Exciting to see you guys go after the partial
             | replication problem.
             | 
             | I've adjusted my comment to be more clear and hopefully
             | more fair. I didn't mean to mis-imply anything about your
             | service.
        
               | rococosbasilisk wrote:
               | No worries Carl, cheers!
        
       | vemv wrote:
       | This seems to be one of those problems that entirely disappears
       | by ditching SPAs.
       | 
       | Using solutions from the Hotwire or htmx family would mean that a
       | query is just a server query - making those fast is a better-
       | understood problem.
        
         | reddalo wrote:
         | _But_ , if I can be honest, solutions such as Hotwire or
         | Livewire are not as snappy as a SPA.
         | 
         | I personally prefer InertiaJs [1], which is some kind of front-
         | end router system with its state synced with the server in an
         | "old style" fashion.
         | 
         | [1] https://inertiajs.com
        
           | FridgeSeal wrote:
           | I don't know what SPA's you have the pleasure of using, but
           | most SPA's I'm subjected to are an exercise in molasses like
           | interactions and loading spinners.
        
         | myaccountonhn wrote:
         | Recently gave htmx a spin. It is absolutely bananas how much
         | complexity it removes and how much more productive you become
         | as a result. The fact that you can use whatever stack you want
         | is also such a blessing. I tried it with ocaml + web components
         | and it's a 10/10 super productive experience. Only need one
         | build tool that compiles faster than I can blink, no wiring
         | needed between frontend and backend to map json, it is just
         | insanely productive.
        
         | threatofrain wrote:
         | This isn't a problem of only websites. Should mobile and
         | desktop ecosystems start making a big move for thin-client like
         | the browser? Should a simple app like Apple Reminders or Google
         | Tasks have the GUI pause if there are delays or connection
         | issues?
        
           | vemv wrote:
           | Read-only access for coarse-grained pages (as opposed to
           | building a fine-grained ad-hoc DB) seems something reasonable
           | (and easy) to cache for any kind of frontend.
           | 
           | That would allow offline viewing to a variety of apps,
           | regardless of approach.
           | 
           | Last time I checked Google Docs doesn't primarily allow
           | _editing_ offline files, which hints how hard it is to
           | support substantial features beyond mere reading.
        
           | pphysch wrote:
           | The authorization story in letting the client upload a new
           | version of the application database (after a drop in
           | connectivity) sounds like a total nightmare.
           | 
           | I just don't think there are "embarrassingly client-side, but
           | also needs a server for some reason" web apps that would
           | benefit from this in the real world. Even Google's or Apple's
           | version of the simple Todo app has a lot of (useful)
           | integrations, which means having some level of trust with the
           | client.
        
         | skybrian wrote:
         | It disappears if your customers have reliable networks, and
         | they are either close enough to the datacenter that the
         | database is in, or you have sufficiently smart database
         | replication. So, often, the problem comes back, but you're
         | synchronizing between datacenters.
         | 
         | Running server-side does seem to be one of the problems SQLSync
         | wants to handle? I wonder how well it does at that compared to
         | other ways of doing it?
        
           | vemv wrote:
           | Precisely an implied part of my point was, server-side
           | caching, DB replication, CAP, etc are all relatively well-
           | understood problems.
           | 
           | One can solve those without reinventing the database, as the
           | article denounces.
        
         | willsmith72 wrote:
         | i don't get it, how does that solve the same problem for an
         | interactive website?
        
           | vemv wrote:
           | If you want new data, you just fetch it again from the
           | server, and the server returns inherently-fresh data,
           | reasonably fast, along with the HTML fragments necessary for
           | a re-render (over ajax or websockets)
        
             | willsmith72 wrote:
             | i thought the whole premise of the article was that you
             | don't want to do that, you want to cache some stuff, and
             | instead of writing the cache stuff (a db) yourself, use a
             | real db in your frontend.
             | 
             | if you wanted to just fetch data from your server, it's not
             | a problem anyway, right? a spa can also just fetch fresh
             | data from a server. the whole point of the frontend cache
             | was avoiding optimising ux/latency, e.g. for apps with
             | global users but not globally deployed servers
        
         | gonzo41 wrote:
         | These people will be blown away by server side rendering.
         | Caches in front of API's and light weight front ends.
        
       | nusmella wrote:
       | An old company I worked for used project management software with
       | a check-in/out mechanism for making changes. When you "check out"
       | a project it downloads a copy that you change locally, then
       | "check in" uploads it back to the server. A project is "locked"
       | while in the "checked out" state. We all felt it was an archaic
       | mechanism in a word of live updating apps.
       | 
       | After 10 years of building SPA "web apps", that data
       | synchronization mechanism feels ahead of its time.
        
         | fjcp wrote:
         | Looks very similar to JEDI [0], an early Delphi VCS system that
         | worked that way. It gave us the tranquility to know that no
         | conflict would appear, as only one developer could work with a
         | locked/checked out file at a time. There was no merge those
         | days. In contrast, files that were frequently changed in every
         | task would always cause a blocking between developers.
         | 
         | [0] https://jedivcs.sourceforge.net/
        
           | hnlmorg wrote:
           | There were loads of VCSs that operated this way. And I don't
           | miss them one bit.
        
         | carlsverre wrote:
         | I'm a fan of this approach. SQLSync effectively is doing this
         | continuously - however it would be possible to coordinate it
         | explicitly, thus enabling that kind of check in/out approach.
         | As for single-owner lock strategies, I think you could also
         | simulate that with SQLSync - although you may not need to
         | depending on the app. If the goal is to "work offline" and then
         | merge when you're ready, SQLSync provides this pattern out of
         | the box. If the goal is only one client can make any changes,
         | then some kind of central lock pattern will need to be used
         | (which you could potentially coordinate via SQLSync).
        
         | alberth wrote:
         | Sounds like Lotus Notes.
        
         | sodapopcan wrote:
         | Your comment reminds me of
         | https://joearms.github.io/published/2014-06-25-minimal-viabl...
        
         | RHSeeger wrote:
         | Sounds like RCS [1]. I remember, back when a company I worked
         | for switched from RCS to CVS, one of my coworkers was annoyed
         | that CVS didn't support locking checkouts.
         | 
         | [1] https://en.wikipedia.org/wiki/Revision_Control_System [2]
         | https://en.wikipedia.org/wiki/Concurrent_Versions_System
        
           | ethbr1 wrote:
           | And, of course, the default mode of Microsoft Team Foundation
           | Server [0], decades after there were better patterns.
           | 
           | So many forgotten locks from lazy devs...
           | 
           | [0] https://en.m.wikipedia.org/wiki/Azure_DevOps_Server#TFVC
        
             | throwaheyy wrote:
             | Are you sure? My experience of using TFVC was that it would
             | warn you if someone else had opened the file for editing
             | but would not actually lock it. Multiple people could edit
             | the same file concurrently with standard
             | automerging/conflict resolution afterwards.
        
               | RHSeeger wrote:
               | I'm definitely not sure. Could very well be the
               | transition from CVS to Subversion that I'm remembering.
               | It's been a long time :)
        
             | nemo44x wrote:
             | Back in the early days of TFS I was briefly at a company
             | that went all in on MS tools. TFS was used and to avoid the
             | lock each developer had a clone made and after checking
             | their clone in the "TFS Guy" in the office would merge it.
             | He also had to merge things when later checking had
             | conflicting changes.
             | 
             | Now, the best part of this shit show was they had ~30
             | different customers and each of these customers had a clone
             | of the main thing that would be customized. So the "TFS
             | Guy" had to determine if to keep in the customer clone only
             | or to propagate to the main and then to all the other
             | clones!
             | 
             | Needless to say the "TFS Guy" made a lot of money.
        
               | JohnFen wrote:
               | I have to use TFS for a couple of projects where I work.
               | I really wish we had a "TFS Guy"!
        
             | partomniscient wrote:
             | Now I feel old, I remember "Anything but sourcesafe" [0],
             | which was a followup to "Visual Sourcesafe Version Control
             | tunsafe at any speed", and having my trust evapourate when
             | I found out Microsoft didn't dogfood their own version
             | control system.
             | 
             | So long ago I can't remember exactly which but I was
             | running a local cvs and/or subversion repository for my own
             | work just to avoid issues like the above. s [0]
             | https://blog.codinghorror.com/source-control-anything-but-
             | so...
             | 
             | [1] https://developsense.com/visual-sourcesafe-version-
             | control-u...
             | 
             | To get back on topic, the key thing an explicit database
             | gives you is a purpose built-language (and data-integrity
             | enforcement etc. if you do it properly), that everyone
             | knows. (Or used to? SQL is getting more hidden by
             | abstraction layers/eco-systems these days). I'm old, so I
             | reach for my older, well understood tools over new and
             | exciting. Get off my lawn. It may be over-architecting, but
             | I'm also not working in maximising 'performance in
             | milli/micro-seconds is vital' high load environments, or
             | releasing updated software every other day.
             | 
             | The other issue is tool/eco-system fragmentation.
             | 
             | But when you're young and have the energy and mental
             | capacity to abstract out the wahoo for
             | effeciency/performance, you do, because you can, because
             | its better at the time. In our day everyone was writing
             | code to write to code which were effectively the pre-
             | cursors to ORM's. It's just part of being young and
             | committed to your craft, and wanting to get better at it -
             | this is a good thing!
             | 
             | It's only as you get older you start to appreciate the
             | "Less is More" around same time that job ads appear with
             | "Must have 3 years of SQL-Sync experience" (no offence
             | intended here). There are both costs and benefits but which
             | and how much of each you only find out years later.
        
         | ozim wrote:
         | It solves so many problems and makes it so easy to implement if
         | you go this way.
         | 
         | But just like mentioned it is hard to convince people that it
         | is what they actually want.
         | 
         | People fall into some grand illusion that everything should be
         | always available but in reality then one person is doing
         | changes at a time and if somehow 2 or more people have to work
         | on something - more often than not they should be talking or
         | communicating with each other anyway to synchronize.
         | 
         | Even with GIT and fully distributed development you cannot
         | solve conflicts automagically. You still have to communicate
         | with others and understand context to pick correct changes.
        
           | calvinmorrison wrote:
           | you can only have one person work on the code at a time? that
           | seems, very very obviously dumb
        
             | SkyMarshal wrote:
             | Multiple people can work on the code simultaneously and
             | asynchronously, but conflict resolution must be done
             | synchronously.
        
             | ozim wrote:
             | I can change A to B on my own, you can change A to C on
             | your own.
             | 
             | At some point we have to communicate which change is
             | correct.
             | 
             | It does not have to be synchronous and it might be via
             | commit message - but still change alone is not enough for
             | conflict resolution.
             | 
             | If you edit word document and someone then changes
             | something there is no commit message but might be comment
             | on document, email or im.
        
       | frenchman99 wrote:
       | Interesting. How does server side validation and access control
       | work with this?
        
         | carlsverre wrote:
         | Good questions!
         | 
         | Validation can be handled in the reducer layer. Since the
         | reducer logic re-runs on the server, it can do anything
         | including reaching out to server-side resources like
         | authorization or other dbs to ensure the client isn't doing
         | anything fishy. It's also possible to use the full capabilities
         | of SQLite to execute automatic in-db validation via triggers,
         | constraints, checks, etc.
         | 
         | Access control is more difficult. Currently SQLSync is full db
         | sync, so a user either has read or read+write access to an
         | entire db. Validation can stop certain users from writing to
         | portions of the db that they don't have permissions to - but
         | the only way to restrict reads is to split the data across
         | multiple dbs. For some apps this is not ok - and thus I'm
         | researching different ways to achieve partial replication.
        
           | fghorow wrote:
           | Please, please don't store any passwords, health, or
           | financial information in your stack unless you solve this!!!!
        
       | uberdru wrote:
       | Stop writing blog posts about why you should stop building
       | databases.
        
       | swader999 wrote:
       | My front end db would look a lot different than the back end. A
       | lot of mutations involve submitting work and waiting for
       | distributed jobs to roll up into some kind of partial answer.
       | This worked, That part didn't etc. Long running transactions,
       | workflow that spans months until the final sign off.
       | 
       | I do need better in the moment state in the client though. Was
       | looking at react query with perhaps websockets for cache
       | invalidation. It's nice to see this sqlsync idea too though to
       | consider.
        
         | carlsverre wrote:
         | This is solid feedback. One integration I'm stoked to
         | build/find is some kind of durable job queue that can sync
         | directly with SQLSync. Would be so nice to just commit a job
         | request into the db and know it will eventually run and update
         | the state. If anyone wants to experiment with this let me know!
         | :)
        
       | amelius wrote:
       | In other words, "let me show you how to turn your super cool
       | project into a CRUD app".
        
       | carlsverre wrote:
       | Author here. Finally got through most of the questions, will keep
       | checking periodically for ones I've missed (has someone built a
       | better way to track HN discussions?).
       | 
       | I'm very happy to see the discussion thus far. This first post
       | focused on the parts of frontend engineering that motivated me to
       | create SQLSync rather than specifically how SQLSync works. I'll
       | be addressing that in my next post. Thanks for all the great
       | questions! Keep them coming :)
        
         | tegmarks wrote:
         | Thankyou for the very informative article, I appreciate the
         | irony using a post titled "Stop building databases" to announce
         | a new database :-)
        
           | carlsverre wrote:
           | You're welcome! And I'm glad you enjoyed it. Once I thought
           | of that title I had to use it.
           | 
           | My only saving grace is that technically I didn't make a new
           | DB - just using good ol SQLite. Mostly. :)
        
       | crubier wrote:
       | This is very exciting, I really love the LoFi (Local first) wave.
       | 
       | The need to write the reducer in Rust for now is a big bummer.
       | Rust is cool, but JS is easier to get started quick.
       | 
       | ElectricSQL is an alternative which is cool too.
        
         | carlsverre wrote:
         | Yea, 100% agree. I'm starting to figure out what that looks
         | like in this issue:
         | https://github.com/orbitinghail/sqlsync/issues/19
        
       | roenxi wrote:
       | There is an interaction here between the "what gets measured gets
       | managed" principle and the sunk cost fallacy.
       | 
       | The problem with databases is actually complexity. Any individual
       | feature is more or less safe, but around the time reliability,
       | caching and indexes get matched together there is a complexity
       | explosion and it doesn't (normally, anyhow) make sense to
       | implement a domain-specific DB (call is a DSD?).
       | 
       | But, around the time a company has invested in implementing those
       | 3 features and discovered that it has sunk a lot of resources
       | into the DSD, is politically averse to recommending it be
       | stripped out and there is a high real cost to taking out the tech
       | debt in one go.
       | 
       | Really the problem here is SQL's syntax. If using a basic
       | relational database was a pleasant experience that involved some
       | familiar C-like syntax instead of broken English people would be
       | more tempted to go with a DB instead of rolling their own. The
       | NoSQL databases were a good step in that direction, but then they
       | by and large overfocused on big data instead of everyday
       | usefulness. Things like Redis took hold which is nice.
       | 
       | Making it easy to run SQL is a reasonable approach, but the
       | problem is that the good databases - I like postgres - are SQL
       | native and it is hard to get efficiency without speaking the DB's
       | language. We really need a PostgresPostSQL database that is a
       | perfect postgres clone but primary parser supports a language
       | with good syntax.
        
       | ozim wrote:
       | Isn't this idea something like couch-db? Then there is pouch-db
       | which is browser implementation using local storage.
       | 
       | So nothing new but it is not bad not to be first. Maybe it is bad
       | not knowing prior work and writing up your idea like it is
       | something no one ever thought earlier about ;)
        
       | rcvassallo83 wrote:
       | Reminds me of an observation that any sufficiently large C / C++
       | program ends up writing it's own garbage collector
        
       | KolmogorovComp wrote:
       | How does this compare to using directly an ORM lib that supports
       | browser like TypeORM [0] via SQL.js [1]?
       | 
       | [0] https://typeorm.io/ [1] https://typeorm.io/supported-
       | platforms#browser
        
         | carlsverre wrote:
         | Good question! You can use a ORM with SQLSync. Currently
         | SQLSync doesn't provide an ORM layer for two reasons: 1. there
         | are many that exist, it's better to integrate 2. it's a
         | prototype so I started with the lowest common denominator which
         | is raw SQL.
         | 
         | SQL.js is an inspiring project in the space and led to official
         | upstream support for compiling SQLite to Wasm. Without these
         | projects SQLSync would have been much more difficult (akin to
         | the original difficulty of SQL.js in the first place). That
         | said, SQLSync is also unique from SQL.js in that it includes a
         | synchronization layer that coordinates with the SQLSync server
         | to provide real time collaboration between users.
        
       | rcvassallo83 wrote:
       | Reminds me of the observation that for a sufficiently complex C
       | program, one starts to build their own garbage collector.
        
       | foobarbecue wrote:
       | So this person is building meteor.js minimongo, but for sqlite.
       | Awesome!
        
       | zlies wrote:
       | I'm trying to achieve something similar with SignalDB:
       | https://signaldb.js.org/ It uses signals for reactivity and is
       | framework agnostic with a mongodb-like query syntax
        
       ___________________________________________________________________
       (page generated 2023-12-01 23:00 UTC)