I Went in Search of Decentralized Relational Storage
I don’t buy into the Blockchain hype, but I do see the value of decentralization and peer-to-peer (P2P) computing. That said, this past weekend I went in search of an open-source peer-to-peer relational database. If you are not interested in this journey, I’ll tell you now, I did not find decentralized, P2P, relational database.
Relational databases hosted on a central (logical or physical) server make a ton of sense. It’s easier to bump performance specs, merge changes without conflicts, there’s no need to handle node discovery management, and the list goes on.
The Web3 Offerings
From everything available, web3 promises us another hell of enclosure and private property. I ended up scouring these fields because the hype cycle and VC money means there’s a lot of people whose job is to write software towards the ends of financialized everything under the guise of decentralization. Also, these terms have become so loaded by the web3 people that all search engines lead to blockchain and its relatives.
One protocol, the Interplanetary File System (IPFS), seemed promising. After giving it a cursory read and concluding that it looked similar to what I wanted (offline first, peer-to-peer storage), I went in search of libraries that utilized this protocol to create a database.
I spent the better part of my Saturday reading documentation, pulling down code, and making test main.go files. The experience wasn’t great, it didn’t leave me feeling productive, and none of the solutions I found were relational databases.
Content Addressing Systems
The best documented resource was the IPFS itself. It took minimal time to download a binary and have the daemon serving files. The immediate problem with IPFS is that instead of location-based file sharing, it uses a content hash. Rather than ask a computer where it is, you ask what it is. The issue with this is that every time you edit a file, the file (and thus its hash) changes. It would be like if you and your coworker were editing a Google Sheet but instead of merging the changes between the two of you, every change would create a new sheeting.
Except content addressing is worse than this because it is all hashes, so, instead imagine every time you make an edit the file name changes, but the names look like the following:
To the credit of the IPFS developers, they do realize this is a concern and have built a tool to handle the potential to infinitely create new files any time they are changed.
Because files in IPFS are content-addressed and immutable, you can’t edit files; instead, a new file is created with every change. The Mutable File System (MFS) is a tool built into IPFS that lets you treat files like you normally would in a name-based filesystem — you can add, remove, move, and edit MFS files and have all the work of updating links and hashes taken care of for you. It’s an abstraction that lets you deal with immutable data as if it were mutable. (Source)
In addition to the potential headaches of immutable files —even if abstracted away —I noticed that the web3 folks seem to hate relational data, a requirement.
At this point, I’ve wrecked my search history and am I going to get nothing but ads for NFTs because I used all the keywords. Nevertheless, I persisted.
I did find a handful of great libraries during this search, just none of them handled the P2P component.
Litestream provides a great way to replicate an SQLite database, but it can’t do bidirectional syncing out of the box and the maintainer rightfully pointed out that you quickly get into the land of conflict-free replicated data types, which pose their own challenges. Not worth it for this endeavor. rqlite it’s a distributed relational database, but there doesn’t appear to be mobile support, so I excluded it as a solution. dqlite I didn’t get far enough into reading about all the capabilities, but it looks similar to rqlite, and by this point I’ve spent my entire weekend fumbling through different options.
Distributed and Decentralized Computing is Hard
I did not find an out-of-the-box solution for what I wanted this weekend. What I landed on for this application is just using the free tier of ElephantSQL as my backend because there is no good reason to make it P2P nor distributed outside my own interest in computing at the edge. This time, like many other times, Postgres is often the solution.
I did find one proprietary SQLite implementation that supports P2P relational data. The problem is that the free binary limited to one table. At the time of this writing, the paid version was discounted to $750. If I can think of a single table peer to peer application, I’ll give the free binary a whirl.