SQLite Is Serverless
sqlite.org
sqlite.org
I'm not saying ALWAYS use SQLite for these cases, but in the right scenario it can simplify things significantly.
Another similar use case would be AI/ML models that require a bunch of data to operate (e.g. large random forests). If you store that data in Postgres, Mongo or Redis, it becomes hard to ship your model alongside with updated data sets. If you store the data in memory (e.g. if you just serialize your model after training it), it can be too large to fit in memory. SQLite (or other embedded database, like BerkleyDB) can give the best of both worlds-- fast random access, low memory usage, and easy to ship.
With the right pragmas it is both faster and more compact than JSON. It is also much more "human readable" than gigabytes of JSON.
I only wish there was a way to open an http-fetched SQLite database from memory so I don't have to write it to disk first.
The sqlite3_deserialize() interface was created for this very purpose. https://www.sqlite.org/c3ref/deserialize.html
[1] https://stackoverflow.com/a/53453338/3063 [2] https://www.sqlite.org/loadext.html#example_extensions [3] https://www.sqlite.org/src/file/ext/misc/memvfs.c
Also check https://github.com/lmatteis/torrent-net
$ mount -t tmpfs none /some/path
$ write db.sqlite /some/path/db.sqlite
$ read db.sqlite
We've been abusing tmpfs for more than 10 years to get around the IO layer's failings. It's probably still a valid pattern.Could you talk more about what Pragmas you’ve been using and why?
Ramfs?
https://www.jamescoyle.net/knowledge/951-the-difference-betw...
I'm still remembering old-school ramdisks under Linux which were finite in both number and size, both to quite small extents. I think there were 8 (or 12 or 16?) total ramdisks available, of only 2-4 MB each, configurable with LILO boot options.
That's now ... mostly taking up valuable storage in my own brain for no useful effect.
Figuring out how to enter "sql" mode in lnav, generate a logfile table, and then persist it from an in-memory sqlite db to a saved-to-disk sqlite db .... was frustratingly annoying.
It boils down to:
:create-logline-table custom_log
;ATTACH DATABASE `test02.db` AS bkup;
;create table bkup.custom_log as select * from custom_log;
;detach database bkup;
if i recall you cannot call sqlite commands ".backup" or similar in lnavs sql mode. So lnavs interjection into the sqlite command processing is annoying (I'm actually very familiar with sqlite).I construct the .sqlite database from scratch each time in Python, building out table after table as I like it.
Some configuration data is loaded in from files first. This could be some default values or even test records for later injection.
The input data is loaded into the appropriate tables and then indexed as appropriate (or if appropriate). It is as "raw" as I can get it.
Each successive transformation occurs on a new table. This is so I can always go back one step for any post-mortem if I need to. Also, I can reference something that might be DELETEd in an a later table.
Often (and this is task-dependent), I will have to pull in data from other server-based databases, typically the target. They get their own tables. Then I can mark certain records as not being present in the target database, so they must be INSERTed. If a record is not present in my input and is there in the target, that would suggest a DELETE. Finally, I can compare records where some ID is present in my input and my .sqlite, they might be good for an UPDATE. All of this is so I can make only the changes that need to be made. Speed is not important to me here, only understanding what changes needed to be made and having a record of what they were and why.
I am happy to say that an ETL process I wrote using this general method back around 2009 is probably still running. I haven't had to touch it in years. Occasionally I will receive questions as to "why did this happen?" and I can just start running queries on the resultant .sqlite database file, kept with the logs, for answers.
Similarly, I can use these sorts of techniques when I am analyzing other datasets. The value here is that I can just refresh one table when the relevant data comes in, rather than having to run the ingest process for everything all over again. This can save me a lot of time.
I've been working on doing similar with containerized dababase servers for testing, while still having versioned scripts for prod (multiple separate deployments).
In the early stages of development of whatever the ETL process is, I keep the database and just empty it out each time. As I got more of a sense of what I needed, I started DROPing my TABLEs more often and remaking them. Eventually I would make the whole database from scratch once I was along the way and had most everything fleshed out.
We initially used json but ran in to memory issues; sqlite is more memory efficient and being able to use SQL instead of the wild SQL-esque is both faster and more reliable.
I do not think LMDB could load from in-memory only object (as it has to have file to memory-map to), however.
But same design reasons, I wanted something that
a) I can move across host architectures
b) something that can act as key-val cache, as soon as the processes using it are restarted (so no cache hydrating delay)
c) something that I can diff/archive/restore/modify in place
We tested sqllite for the above purpose at the time, and writing speed and ( b ) - lmdb was significantly faster.
So we lost the flexibility of SQLite, but I felt it was a reasonable tradeoff, given our needs.
I also know that one of the Intel's python toolkits for image recognition/ai, uses LMDB (optionally) store images that processing routines do not have incur the cost of directory lookups when touching millions of small images. (forgot the name of the toolkit though)…
Overall, this a very valid practice/pattern in data processing pipelines, kudos to you for mentioning it.
We get a gnarly csv log file back from our sensors in the field, which is really a "flattened" relational data model. What I mean by that is a file with "sets" of records of various lengths, all stacked on top of each other. So, if you open it in Excel, (which many users do), the first set of 50 rows may be 10 columns wide, the next 100 rows will be 20 columns wide, the next 45 wide, etc. And, the columns for each of these record sets have different names and data types.
Converting to JSON is obvious, but I've thought about just creating a SQLite file with tables for each of the sets of records. Then, as others have said, can use one of any number to tools to easily query/examine the file. Also can easily import into a pandas data frame.
One concern is file size. Any comments on this? I can try it, but wonder if anyone knows off the top of their heads if a large JSON file converted to an SQLLite file would be a lot larger or smaller?
edit: clarity
You only have to read the CSV file once, and after that you have a nice set of tables you can query any which way you want.
I use SQLite as an intermediate step between text files and static HTML, for example.
> The SQLite file format is cross-platform. A database file written on one machine can be copied to and used on a different machine with a different architecture. Big-endian or little-endian, 32-bit or 64-bit does not matter. All machines use the same file format. Furthermore, the developers have pledged to keep the file format stable and backwards compatible, so newer versions of SQLite can read and write older database files.
Our current setup is having all our services in kubernetes but our databases in stateful VMs. I do occasionally stuff job-reports and similar data into postgres rows since it's already there, but I've been unhappy with our ETL setup and would be interested in hearing techniques to improve it.
I'm in favor of leveraging ISP dbaas and persistence offerings over trying to home grow something. It just depends on where you are coming from and/or what you are trying to do... K8s alone avoids so much lock in, and as long as whatever storage option (container mount) or dbaas you use is portable, I don't think it's so bad in either case.
ETL = extract, transform, load
"... causes them to accumulate output as Comma-Separated-Values (CSV) in a temporary file, then invoke the default system utility for viewing CSV files (usually a spreadsheet program) on the result. This is a quick way of sending the result of a query to a spreadsheet for easy viewing"
IIRC, MS Access allowed that, which explained a lot of its popularity.
Apart from quality (!), SQLite's main advantage over these products is broad platform support. And continued existence.
Access is really meant for single-user scenarios I feel. Maybe the locking mechanism has gotten better but for multiuser access I tell people to use a real SQL database.
It was quite frankly the most productive custom business software package I have ever used. Literally would take 10 people a week to do something custom you could do in an afternoon with 1 person in Access. I suspect the same is true now.
In a lot of cases, I've found it to be the best tool for a temporary or one-off (preferably smaller scale) data mining/massaging project. The query-building interface was the way I originally learned the basics of relational databases, and it also helped me get a better grasp of SQL-- the ability to flip back & forth from the GUI query builder to the SQL it generates is nice.
On the multiuser side, however, I have found a couple workarounds in the past. If you have everyone operate locally and space out their central database connections to intermittent, automated burst queries, you can get more concurrent users than you might expect. It helps to have fewer users per table, as well, and of course it really helps if they don't need to see the most recent adds/changes in real time.
[https://en.wikipedia.org/wiki/Microsoft_Jet_Database_Engine]
I loved the Clipper 5 OOP capabilities, sadly Visual Objects tried to be too much like Visual Basic and some of the easiness was lost.
Berkeley DB also supports multiple processes accessing a database concurrently, as far as I know.
I was wondering if the authors were referring to SQL-like databases, but MS Access seems to be one?
> Most SQL database engines are client/server based.
I skipped it for brevity.
The reason access was popular was it made any middle manager that could wield an Excel spreadsheet think they could build a database.
And plenty of other file-based DBs such as Borland’s Paradox and the db engine, dBase; pretty sure FileMaker, too.
A server is something that listens for commands from various clients and executes them.
If we reduce things to the absurd we stop being able to reason about things.
Sorta but not really. The fact people have worked backwards from marketing names to try and constructively define inherently self-contradictory branding (rather than create a descriptive category into which we place questionable names and ignore them) is an embarrassment for everyone except the marketing departments.
It's really not important to understand that distinction, because this author seems to be the only one making it. Everyone knows what "serverless" means at this point, and it's not an embedded DB.
(here's SQLite's "Serverless" page the way it was in 2007: https://web.archive.org/web/20071115173112/https://www.sqlit...)
At this point trying to use the word in this way just creates a bunch of unnecessary confusion. Call it something else so we can move on to more important (and clear) discussions.
(Also there are a lot of assumptions and snarky comments in these responses about my age, which is quite rude and pretty elucidating.)
Moreover, the cloud as a service definition isn’t even accurate. There still is a server — it’s just not one the developer has to worry about.
Is your argument that they should replace "serverless" with "runs without a server?" That seems like a strange position to me.
Imagine if Uber called itself a "carless" taxi.
I think it highly ironic that the marketing hype just upended what's really going on. The new stuff's 100% server bound, as most people realise.
Serverless databases and what have you have been around longer than the current batch of folks trying to redefine things (or more charitably, ran out names to call things). Like or not, there is a distinction even if the old definition was before your time.
There is a vocal minority of reductionists here on HN who dismiss the accepted definition of serverless because the literal meaning doesn’t make sense. It’s just noise though. “Serverless” does have a specific meaning and it’s not “there are no servers anywhere”.
I was around when there was no serverless. Things change, new words arise. Time for us to get with the times.
We used to call it /cgi-bin/ ;)
Serverless is a marketing term at this point (as it was when it started). This post brings some welcome definitions and expands it to something that has many of the same attributes but wasn't appreciated as such.
What parts of SQLite have these properties?
In the case of cloud "serverless" it doesn't have a physical ser-- Wait did you just mention "managed servers"?
I had more trouble with the assertion that the embedded DB would be maintenance-free. I started a top level comment asking for someone to explain how that would work. The part of my brain that protects me from scams is screaming “something for nothing”.
When is the last time a certed-up DBA had to do any maintenance on your Firefox install's places.sqlite database? That's what's meant by maintenance free; you can reasonably employ sqlite databases on users' computers, without users having the foggiest idea of what a database even is.
In case of a neo-serveless setup, I also have two servers: one with the app, the other one with the db server.
So what are the benefits of the Xqlite setup? I looked into that before and for one thing, Xqlite is slower (obviously) then just sqlite. So speed is not a key benefit. I also will have to manage both servers myself.
At least for a seperate db server I have the benefit that I can buy that as a service, incl management, backups and such.
As to why you'd want a separate DB server process: long lived mutable structures tend to drift into unexpected states, which is why the standard computer troubleshooting procedure since forever is to restart. Database management systems specialize in not having that problem. You deploy one that's widely used and hardened over many years, change it infrequently, and operate it with great care. Or pay a cloud provider to do that.
Then everything else gets to outsource the burden of persistence to it, and the vast majority of the workloads you develop and operate are stateless. These are drastically more convenient and more resilient to mistakes. They're effectively "restarted" with each API request, and you can stand them up, tear them down, migrate them to new machines, etc. as much as you want without fear of data loss.
Why are those "tend to drift" ? As an example I wrote sort of like game server for one of my applications. Internally it has those exact forever lived mutable structures. I've never observed it to drift into any unpredictable state. Works like a charm and running for many month. I only reboot it when I need to update it to a new version.
The only catch here is that all data fit into RAM. With the amount of RAM modern computers can be stuffed with I do not really see if my server would ever run out of it.
Of course it backed up by database but it merely serves as a persistence layer for this particular application.
In the real world, let's say you have a shipping address and a billing address for a customer, and they are usually (but not always) the same.
Eventually, a customer moves, changing both of their addresses. But the user forgets to change their billing address with their delivery address.
A proper database would have a 'billing address is same as delivery address' logic, following the principle of DRY (don't repeat yourself).
----------
There are lots of examples here of what can go wrong when you repeat yourself in a database application. The user may have an error when repeating themselves over the dataset (delivery address is correct, but zip code on billing address has a typo).
Dealing with these issues at scale, with hundreds of thousands of customers, is certainly a problem. Normal forms can formalize these issues and help the business owner avoid the problems.
Where do you verify the existence of zip codes and cities? Where do you check for typos? How do you prevent contradictions on the submitted information?
Your human customers will make many mistakes. Your logic must hold up even in the presence of faulty data.
Many years ago I happened to meet the creator of Prevayler, an open-source persistence framework that provided ACID guarantees and was thousands of times faster than a database as long as your data fit in RAM. I tried it out for a project and we loved it. Our hundreds and hundreds of unit tests ran in a few seconds. Our pages rendered in ~5 milliseconds. It was structured around a log of actions, so if you wanted to know how the data ended up like it did, every change was logged.
What people who haven't worked this way often miss is that a database doesn't make things simpler, it just makes certain things easier. Once you add a traditional database to your project, you're importing a million lines of mysterious code into your project, and demanding to pay a serialization/deserialization penalty any time your code wants to look at data. When it works, it can be swell, but when you have a problem, suddenly things can get hairy. Database performance optimization is a murky art in a way that just isn't true if all your data is right there in RAM.
Prevayler of course didn't catch on. It was just too weird for most people, who had grown up on databases and for whom data structures were something that they hadn't really thought about since their last CS exam. But I sometimes dream of the world where it did catch on. At the time, fitting in RAM was a big limitation. But now I can get an off-the-shelf desktop with 768 GB of RAM, and Amazon's servers go up to 24 TB of RAM. If you're going past working sets at those levels, traditional databases have anyhow fallen out of favor of big data tools. But it would have been a much better fit for today's world of microservices and distributed systems.
I’m a big fan of Redis, but I was bitten many years ago when I tried to use it as a replacement for an RDBMS. There were two reasons for this: 1) lack of development libraries and operational tools, and 2) lack of data integrity checks.
1 has changed these days, but 2 is still very much the case (and rightly so, IMHO). Perhaps Prevayler had this?
But yep, it was fast at a time when our competition’s software was slow and clunky. It made a difference.
With Prevayler, all data is kept in RAM, reachable from one root object, which Prevayler holds. All changes to the data model must be expressed as command objects. Each object is handed to Prevayler, which serializes it to a log and then executes it. Once in a while, you can snapshot the data out and start a new log. If there's a crash, you just load the latest snapshot and replay the log.
You got exactly as much data integrity as you wrote into your objects and your commands. Which without much work could be quite a bit, because you get a lot of data integrity by not writing things. E.g., if a kind of object should never be deleted, you just don't write any deletion code. If, say, account balances should never be changed directly, but only as part of properly structured credits and debits, then you just write your code like that.
Most databases, Redis I think included, are made for arbitrary operations on data. Developers add integrity and security later, hopefully. And that is often duplicative of the code base, so that one ends up having integrity checks both in the code and in the database.
I should say that made a lot of sense for the era databases came out of. Databases were a huge step forward in the 1970s and 1980s. My dad was a developer in that era and it was a big relief not to have to get a bunch of programmers to all follow the same conventions for exactly which record was stored in exactly which spot on their precious and expensive disk drives. Not having to know the minutia of the hardware let a lot of people just get in there and build business reports. But if we were starting fresh today, I don't think we would do anything like a SQL database. Redis was definitely a step away from that era, and I look forward to many more.
Most file systems will start to get slow at some point with too many files in a folder.
I would go so far as to argue that SQLite could be used to store all of the assets for any large piece of software (I.e. a AAA game). This would probably wind up faster and more reliable than most alternative solutions out there today.
The killer feature of databases, including no-sql or older ones like BerkeleyDB, is multiprocess synchronization.
If two programs (or two copies of the same program) need to coordinate their data, a database is often far easier to use than writing your own transaction layer through files, mutexes, and other primitives.
Web applications, such as forums or discussion boards, have many users and processes adding data simultaneously. That's why databases are so popular in web backends.
If your state consists of a single data structure you could write it to disk into a new file and move-replace the old file. This works as long as you have a single instance of your application.
For anything more complex SQLite is a good way to keep your data in a consistent state. If you store it on a local drive, the performance is stellar.
Thinking about going multi-process or multi-user? SQLite can still give you an easy head-start because it performs OK in most situations with a database stored on a network drive.
You can get by with files, but they're slower. A DB is the right choice.
Structured data anytime you're hitting multiuser - web, networked games, collab programs, live maps, etc.
Anything that's massively stateful. A DB hands you a lot of guarantees. The filesystem has some of them, but is much slower.
When you want to persist data beyond the lifespan of your process?
as soon as you need any of these:
* a relational model -because you need to model your data that way or you are required to because someone wants to consume it with tableau-.
* concurrently read/read data between 1+ instances.
* a standard way of doing backups.
moving from that to a database would probably equal a rewrite.
As soon as i connect using the command line interface, it slows down significantly.
Just something to bear in mind if you want to use it with multiple processes!
Increasing the retry timeout can help, using WAL can help. I'm sure you've tried all this though.
1) Implement another process which will have exclusive ownership of the shared SQLite database, and then use some IPC scheme to delegate database operations from multiple processes.
2) Give each process its own copy of a SQLite db if there is no effective shared state between these processes (I.e. you are just map-reducing web crawler results). Upon completion of each process you could aggregate each into a final combined db.
3) Use a hosted database solution such as Postgres.
The bigger question for me would be what are you going to do with this data once you collect it. If you plan on having another series of processes that then use the SQLite db to provide reporting views or execute business logic, I think a hosted solution might be a better option. If scalability is a serious concern, option 2 is probably your best bet.
I always conclude these things are advocated by people who have no experience in large multi user systems. The same as the NoSQL movement. They'll eventually build a database server. They build a system using the cool thing which works fine when they test it on their single user system. Go live - aagghh what's happening, why are all these people trying to access my data simultaneously? and so on.
One I'll always remember was when XML was the next big thing - they decided to store the raw XML in a database. It was a commercial product, and we were interfacing to it from our system. Once we found out this we started asking questions - no no it works fine we were told, laughing at us old database guys. Went live couldn't handle 5 TPS - what a surprise, it never worked as far as I'm aware. There is this continuous circle of databases are bad, no no do this you don't need to do this, no things have changed - what do you database guys know. Its entertaining to watch if nothing else, my advice - learn SQL, and some database tuning, its not that hard, at least compared to writing your own database engine.
These advantages of purpose-built functionality would also extend into the arena of handling replication and clustering. I.e. multiple distributed processes each with independent databases synchronized via some custom protocol that operates in terms of specific business models and processes.
I've used SQLite as an embedded database, as a log file, it's even possible to use it as a virtual filesystem in tcl starkits. But a high demand, multiaccess data solution it is not. Yes you can make it work but you need to justify the costs of doing all that server work when you could just use a SQL server that already meets your needs.
(Honestly, once you are at the point where concurrency causes performance issues with SQLite, you are better off moving to databases designed to handle concurrency rather than trying to cobble together your own workaround - you have reached the point where the drawback of SQLite‘s architecture outweigh its advantages and the advantages of other databases architectures outweigh their drawbacks)
It's just that for 99% of the projects I ever worked on, writes are like 100x less than reads so wrapping the writes in a queue of sorts has been quite okay and performant.
It can and it has been coming to a point when it's easier to use a full-blown database server, too.
I was simply pointing out that for a lot of classic workflows wrapping/centralising writes works quite fine.
Aside, adjusting schema over time also becomes easier as archived projects don't need to be updated, they just continue to exist with the older schema.
so if everyone's saying this, is there such a standard dummy program?
I vaguely recall trying to use multiple threads to write to an SQLite DB some years ago, and I think it actually locked the entire file for writes. I might remembering wrongly, but I think I switched to reader/writer locks in c# instead, and seeing a huge perf boost.
My point, not well made :), was that a lightweight locking mechanism worked much faster than SQLite's file-based locking mechanism. This was on Windows, mind, so things might be very different on Linux.
As for particular case with WAL, all it does in this particular scenario is act as a queue. If your database load is spiky then it can even out load and make an impression of faster response. Under constant load it will not speed up the things and will internally serialize all actual updates
Shameless plug, but I made a fun side project that allows Amazon Athena to read SQLite databases from S3. https://github.com/dacort/athena-sqlite
https://github.com/dacort/athena-sqlite/blob/master/lambda-f...
Implemented the VFS side in Python, thanks to the awesome apsw library.
Furthermore, it doesn't solve the multiple writers problem, because (afaik) there's no way to lock a file on S3.
Is this the cost of network transfers changed by AWS or GCP? What if I'm hosting my app on e.g. EKS or GKE respectively?
The interface will be either HTTP or Redis protocol, you create your database, and daily I will back it up on S3.
(If interested you can subscribe for updated here: https://simplesql.carrd.co/
[1]: https://redisql.com/
1. I do not want my production instance to shut down for WHATEVER reason. This is just not an acceptable risk for most businesses. The only time a DB can go down is something goes wrong.
2. As an engineer, I understand that 3 counters that are not accurate aren't a big deal. I can even look into the source and see that they really do as you say. Justifying this to a security org will be a complete nightmare, as most security orgs in enterprises are staffed with barely technical folks masquerading as "security".
So, it seems like a pretty good way to coerce enterprises to pay up while letting hobbyists continue using it. Very smart, I wish you the very best!
APSW exposes the sqlite backup api so you could do them online without shutting down the database.
Here's the deal: SQLite is a file format with a nice API that uses SQL as the paradigm for reading/writing to the file.
That's it. Stop overthinking it.
Can you write a microservice that stores its data in a big JSON file that you've built some code around to read/write to? Yes. It's just a file, but you have to build all the read/write methods. SQLite is not really any different, except the read/write work is already done, and you use SQL to format the data values and encode the read/write logic instead of the language you are working in.
The file format has some cool extensions like text indexing, geospatial, etc. But it's no more a RDBMS than reading and writing a JSON file is.
"But there's indexes!" Yes, just liked you might build an index on your JSON file and read that before reading the JSON file to know where things are faster -- and then you have to write all the code to do that. SQLite is just a file format, where you can also build indexes and all the code for that is already done for you.
It's just a file format with an API that's similar to the ones you'd use for any regular old RDBMS and uses SQL as the domain language to read/write data.
It's just a file format. Anything you can do/can't do with a file format you do with SQLite.
It's just a file format. A nice convenient one that you are probably better off using than most other things for most purposes.
It's just a file format.
edit
I'm glad this comment is getting such a response. I'm not trying to be mean, just help clarify thinking.
Here's two thought experiments:
1) If SQLite didn't require you to use SQL as the read/write logic and was called "datalite", and instead just forced you to use C function calls, exactly like you would if you were working with literally any other file format on the planet, would you still be confused as to what it is?
2) Do you consider reading and writing to any other file format anywhere in the hierarchy of RDBMSs? Consider Python's csv module. Is that an RDBMS? Let's move away from tabular data, how about python-docx?
> It's just a file format.
This is clearly incorrect. It does encompass a file format, but it also contains code to manage that file. The existence of sqljet does not change this, it's merely a different database management system that uses the same file format.
You also seem to mostly ignore that the data it's managing is a relational database, not some other form of data. This is why you can't compare it to python's csv module or python-docx, neither of these do anything to restrict you to a relational data model, nor do they provide a system to query them as if they were a relational database. On the other hand, if for some unknown reason you rewrite the storage engine of postgresql to use the either the sqlite file format or csv/docx, I assume you agree it would still be an RDBMS.
Ultimately I think you're just adding to the confusion by saying that a project with 139,000 lines of C code is "just a file format".
What are the aspects of "approaching it from a classic RDBMS angle" that are incompatible with it being "just a file format"?
I've always seen it as "just a file format" myself, and I think I've always approached it "from a classic RDBMS angle", but I've never felt confused, and I don't see what I'm overcomplicating.
Have you tried to figure out where to install the server or asked what the system requirements were for it?
Have you grown concerned that once the system moves into production the O&M team won't know how to operate "yet another database"?
Do you spend agonizing hours trying to figure out if it supports multithreaded connection pools for multi-user writes?
Have you wondered if your organization has the budget to add another DBA to the team if you add SQLite to your tech stack?
If the answer is no to all of the above you aren't approaching it from a classic RDBMS angle. Believe it or not, there are tens of thousands of questions about SQLite struggling to figure out the answer to the above questions.
The people asking these questions are not stupid, they're just approaching the technology from the wrong direction.
This post is no different than "CSV is serverless" or "JSON is server-less" with a blog post about classic vs neo-serverless JSON technologies.
Not exactly, but asking "where to install the server & client and what are the system requirements for each" is not that different to asking "where to install the client and what are the system requirements for it", even when there is no server.
> Have you grown concerned that once the system moves into production the O&M team won't know how to operate "yet another database"?
Yes. Because the production concerns of SQLite are not nil.
> Do you spend agonizing hours trying to figure out if it supports multithreaded connection pools for multi-user writes?
Not agonizing hours, but it is just a slightly rephrased version of a valid question about SQLite w.r.t. concurrent file access (as with locks on file access for any file). Other commenters have brought this up in terms of multi-user access slowing down applications, and setting up intermediary DB access processes using IPC to facilitate this.
> The people asking these questions are stupid
I disagree
> no different than "CSV is serverless" or "JSON is server-less"
CSV and JSON lack any protocol or queryable interface: unless you're using some ancillary tool like `jq` as a comparison, CSV and JSON as filetypes are both "serverless" and "clientless" so not particularly comparable. An article on those would be quite different.
Calling Sqlite just a file format is kind of like calling Python "just a syntax specification." That's part of it, but we're talking about the actual implementation of it (probably CPython).
Such an instance of “embedded Postgres” would still have a huge sprawling catalog (PG_DATA) directory attached to each use of it, so it wouldn’t be contained to a single file. But neither is SQLite contained to a single file—SQLite maintains a journal and/or WAL in a second file.
And, yes, this “embedded Postgres” would require things like vacuuming. But... so does SQLite. Have you never maintained an application that maintains a long-lived “project” as a single SQLite file, where changes are written into this project file repeatedly over a long period? (Think: the “library” databases of music/photo library management software.) SQLite database files experience performance degradation from dead tuples too, and need all the same maintenance. Often “database version migrations” of such software is written to either rewrite the SQLite file into a clean state, or—if it has the possibility of being too big for that to be a quick task—to call regular VACUUM-like SQL commands to clean the database state up.
——
Now, I get what you’re trying to say; the point that you’re trying to make—that SQLite might be a relational database, but it’s not a relational database management system in the sense of sitting around online+idle where it can do maintenance tasks like auto-vacuuming. Unlike an RDBMS, SQLite doesn’t have its own “thread of execution”: it is a library whose functioning only “happens” when something calls into it. By analogy, regular RDBMSes are like regular OS kernels, while SQLite is like a library kernel or exokernel.
But that doesn’t mean that SQLite is a file format! It can be used as one, certainly, but what SQLite is is exactly the analogy above: the kernel of an RDBMS, externalized to a library. As long as you “run” said kernel from your application, and your application is a daemon with its own thread of execution, then your application is an RDBMS.
This can be seen most directly in systems like ActorDB, that simply act as a “transaction server” routing requests to SQLite. ActorDB is, pretty obviously, an RDBMS; but it achieves that not due to its own features, but 99% due to embedding SQLite. All it does is call into SQLite, which already has the “management system” part of an RDBMS built in, just not called unless you use it—just like exokernels often already have things like a scheduler, just not called into unless you as the application layer do so.
The other thing I would mention is that SQLite can operate totally in memory which makes it useful without even using it to persist data (say you have a language with a slow dataframe API, just use SQLite in memory to process your data).
I worked on a project a few years ago, where I chose Firebird so I could use literally the same database on potentially offline sites that regularly sync up to a main office (shared) deployment. I worked pretty well and was still a lot of work.
Approach it exactly the same way you'd approach using a CSV file and all the confusion and overthinking about it goes away. Approach it as a stripped down RDBMS and you end up with all kinds of questions about support for this or that RDBMS familiar service.
You can write your own SQLite file reader/writer. Here's the specs (includes the specs for the Journal and WAL files and semantics as well) https://www.sqlite.org/fileformat.html
Here's an example of somebody who's done this. https://sqljet.com/ - this is not a wrapper on the sqlite C code, this is a re-implementation of that code that is binary compatible with SQLite files.
The Journal file only exists as a temporary file until transactions complete. The .sqlite file you make is the entire atomic file that follows the SQLite file format. The Journal has its own file format. Same goes for the Write-Ahead log.
RDBMSs also manage connection queues, account management, rights and permissions, and so on. Many overcome various OS limitations by providing their own entire file management, fopen(), virtual memory and other subsystems that are tuned to their workloads.
SQLite is a file format. SQLite uses familiar relational paradigms to make it easy to read/write data to the format without having to learn yet another API and domain language. The API code is extraordinarily well tested, and it makes simple complex logic like transaction journaling, indexing and so on.
>Consider: it’s totally possible to strip down Postgres until all you have left is an embedded RDBMS of the style of SQLite.
No! SQLite is not an embedded RDBMS. It's a file format.
If there was a library you could import, and it provided methods to read and write directly to files that PostgreSQL could read/write to and there was nothing else to install, no runtime, no daemons, no servers, etc., then we could pass around self-contained PostgreSQL files to each other. Then PostgreSQL files would be a file format as well.
Have you ever used a library to read/write from a CSV, JSON, JPEG? It's no different than doing so for a SQLite file!
SQLite is a file format.
The main argument I hear for why Sqlite deserves second class status in the DB marketplace is the difficulty in handling multiple writes simultaneously.
To that point I'd say it's more of a simplicity in design choice. Search for 'DB race conditions' and you'll see that every database struggles with handling multiple writes nested inside complex transactions. Sqlite avoids the whole mess and requires the programmer to think through I/O instead of offloading all that logic to the rdbms software.
SQLite is not in the DB marketplace. It's in the file format marketplace. It handles multiple writes in exactly the same way CSV handles multiple writes. If you want to handle multiple writes with SQLite, you handle it the same way as CSV.
And I'd say that not only is sqlite in the db marketplace (albeit for a specific subset of database application types) it's one of the largest players.
Moreover I'm having trouble coming up with things that I'd associate with a RDBMS and not "just a file format" that SQLite doesn't support. Transactions? SQLite has them. Relational constraints? SQLite has those too. Could you elaborate on some of the confusion that you've seen around this?
Longer answer:
SQLite files do not guarantee ACID compliance. You can write code tomorrow that produces SQLite files, and so long as you follow the specification (https://www.sqlite.org/fileformat.html) it will be readable by any other code that implements the specification (e.g. https://sqljet.com/)
An RDBMS is not a database, nor is it SQL, nor is it data. It is a kind of DBMS software that manages relational databases, and access to the data (such as users and user rights). Most modern RDBMSs run as servers and offer network connectivity, connection pooling, advanced buffering options, various memory usage schemes. Many have their own memory allocation and file handling routines that are separate from the OS. Some offer clustering, partitioning and so on. SQLite does not offer any of these things. If you were to write a comprehensive list of things that Oracle, MS SQL Server, DB2, PostgreSQL, MySQL and SQLite offer, SQLite would offer almost none of the features that the rest do.
A relational database uses the relational model to store data. SQL is the most common language for describing what you want to put into or retrieve from the relational database, but it is not required.
There are many kinds of databases. Some of them store data in memory, in a file, in multiple files, and so on. Some of them follow various models, some of them are unique. If you have the file format for a database that stores its data in files, you can read/write to the file freely without any management system and without ACID compliance. SQLite files are examples of a kind of database file that stores data using a relational model. So are MDB files that Microsoft Access uses.
By conflating a file format with an RDBMS, it's like conflating a fork for a restaurant, or a chair for a house.
ACID compliance is not something guaranteed by the file format. SQLite files do not guarantee ACID compliance. If you write some code tomorrow that can read/write SQLite files based on the spec, you haven't created and ACID compliant SQLite file, nor is your code ACID compliant.
The SQLite library implements the properties that make SQLite ACID compliant. It does so by various clever means like a journal file format, and a write-ahead-log file format and various other well thought out approaches. If you were to write your own code that implemented the SQLite file spec, and you wished your code to also offer ACID compliance, you would have to implement those things yourself -- and you are under no obligation to use the SQLite journal and WAL file formats nor the internal logic that the SQLite library uses. You can do it entirely your own way!
SQLite is just a file format. If you want it served up over some kind of server, you have to build your own (and most people do), or use a server that somebody else has built for you (there's a couple out there).
Being a RDBMS is not defined by whether the engine runs in-process or as a server in its own process.
Saying that a program that opens and reads/writes a file through a file format API is a light RDBMS turns almost every program in history into an RDBMS.
If SQLite didn't force you to use SQL as the read/write logic, absolutely nobody would confuse it for an RDBMS. That's because it's a file format.
<insert-your-favourite-relational-database-management-system-here> is a collection of bits with a nice interface that uses a query language as the paradigm for reading/writing data.
SQLite provides almost no RDBMS features.
This isn't just semantics.
A car is not an engine. A fork is not a kitchen. A SQLite file is not a DBMS.
>Connolly and Begg define database management system (DBMS) as a "software system that enables users to define, create, maintain and control access to the database".[24]
>The functionality provided by a DBMS can vary enormously. The core functionality is the storage, retrieval and update of data. Codd proposed the following functions and services a fully-fledged general purpose DBMS should provide:[25]
[x] Data storage, retrieval and update
[x] User accessible catalog or data dictionary describing the metadata
[x] Support for transactions and concurrency
[x] Facilities for recovering the database should it become damaged
[ ] Support for authorization of access and update of data
[ ] Access support from remote locations
[x] Enforcing constraints to ensure data in the database abides by certain rules
Under this definition SQLite - the library - clearly is an RDBMS that leaves out some common features that do not make sense within its niche but is otherwise fully functional and under this definition the files that SQLite manages are the database, not just merely a file format.
Lodash, for instance, is much smaller than 22k lines, and it “just” manipulates objects and lists.
If you downplay others like this, I wonder how you feel about your own work. Have you been working hard for years on something that “just” accomplishes a straightforward task? Are you happy? I know I wasn’t.
The people in this thread seem to be very resistant to this simple clarity of thought, but whatever, they can stay confused and keep coming up with feature comparisons of SQLite vs Redshift vs Elasticsearch or some such.
If one were to draw a spectrum:
file-format:<-x----------------------------->:DBMS
SQLite is the x on this line and .txt files are about the only thing that any further left on it. file-format:<------------------------x------>:DBMSI'm a noob and just curious.
If you want to build an RDBMS using SQLite as the core, you can. You can also do it using uncompressed WAV audio files if you are clever and hate yourself enough.
To use SQLite in such a scenario you simply have to write the entire RDBMS minus the file handling routines. This includes a connection pooling mechanism and a single process to isolate the connection to the SQLite file so that the OS doesn't get angry when you try to have multiple things writing to it.
I think not, but I wonder if some hack is available by virtue of it simply being a file that you can read (and somehow) write to.
The best I came up with: let's say you have a toy project, and you call the Github API and replace the file upon every write. Implementing a read is easier as you know where the file is located. This hack shows that you somehow need write access to get any form of performance out of it, because this hack is super slow.
You can run SQLlite in the client via webassembly therefore open a SQLite file in the browser to query it yes, you just can't write anything in it and expect it to persist somehow on the static hosting service itself.
> The best I came up with: let's say you have a toy project, and you call the Github API and replace the file upon every write. Implementing a read is easier as you know where the file is located. This hack shows that you somehow need write access to get any form of performance out of it, because this hack is super slow.
No you'll need a server for that, you can't make random HTTP requests to any server in the browser, because of CORS/SAME ORIGIN policies.
"SQLite is serverless" is meaningless buzzword. It just means that SQLite is equivalent a flat file where you'd shove some data, just that you can use SQL to query that file instead of having to index data in it yourself.
A quick search of usenet shows "serverless" being used in 1994. It wasn't a term or a buzzword, it wasn't common, it was just English: https://groups.google.com/d/msg/comp.os.linux.misc/r76oNl98C...
That was never a common usage of the term serverless.
The meaning of that 'serverless' and this 'serverless' is incompatible, since the web inherently needs servers.
I think the best you can do is uploading the SQLite file to a static hosting platform & decoding it in the browser. You can then use it as a file storage with DB capabilities. (Which is what basically really SQLite is.)
I am the main author of RediSQL [1] and I am about to launch a managed service for it.
It will allow to write SQL (SQLite dialect) against an HTTP or Redis protocol, to make thing clearer: https://simplesql.carrd.co/
Eventually it will upload your database to an S3 bucket for backup.
[1]: https://redisql.com/
I can imagine it would be useful for data-science projects, if the pricing is right.
Author creates two definitions for serverless which don't match the common usage. Serverless is more about DevOps / deploy experience than how the program leverages OS processes internally.
Apparently MS and AWS are ISPs?
Maybe SQLite could be serverless if you defined it as incapable or running as a server on its own?
You don't need an ISP to have a server. Any computer or program that listens to a network port is a server.
They have their own IPs and global networking infrastructure
In the sense you don't need to provision an additional piece of infrastructure to power your application :-)
Can we back away a bit from the bandwagoning of misused terminology? Serverless literally means "running your apps on somebody else's server". S3 is not a server you run your apps on, it is SaaS that you manipulate through an API - you don't put your apps on it. If S3 is serverless, then literally every network service of any kind is serverless.
I use sqlite for local tests for cases where the live app has a 'neo-serverless' database. It is very, very fast so the tests run almost instantly.
https://www.sqlite.org/backup.html
There's a ".backup" command:
* https://sqlite.org/cli.html#special_commands_to_sqlite3_dot_...
Alternatively, given that it's ACID, you could just take a snapshot of the file system/volume in question, and do a recovery on restore.
Edit: SQLite also has WAL files, so presumably one could just use tar/rsync to create the backup, and only the last file would be 'corrupted', so you'd lose the last (few) transaction(s):
Also I don't think any cloud provider/database provides an always up to date backup other than a standby replica (which isn't also a backup exactly).
Also, it's comparatively simpler than other DBMS's like Postgres or MySQL.
I’m having a failure of imagination here.
What would I use a database for that I could reasonably assert to my peers and superiors that no maintenance whatsoever is required? Backups and restores count as maintenance. Multi region is now common, if not pervasive.
Are there public datasets that are so common that it would be worth it to provide it as a service? What other service would behave like S3 but look like SQLite?
I get that one might be safe to assume that “serverless” isn’t just pure functions. It could reach out to other services that are not serverless and still not consume (further) resources on a set of machines while not in use.
But a severless database... I’d have to have something aggressively read-mostly, written to S3 at intervals and read from serverless processes. But is that a new thing or reading data from S3?
So my system is also "serverless" in that meaning.
Acronyms used to be confusing, this is just ridiculous.
But somehow the word annoys people. Maybe we should find a better word?
There is already a term for that concept: managed services. There is no such thing as a managed service that's designed not to be scalable. Some implementations may be better at scaling than others, but that's it.
The serverless buzzword is pure marketing.
On the other hand, there's a certain amount of amusement I get from seeing "the cloud" become a marketing buzzword in the mid-late '00's, and now seeing the same thing happen with "serverless."
When you look at the implementation of the two "technologies", they're about 95% the same. Yet somehow they're pitched as these big revolutions.
In another decade when terminals or p2p become popular again we'll be hearing about some new buzzword like "Terran" computing, or "social" architecture or something.
Some services labelled serverless really do reach very close to this ideal (S3, for instance), while others fall short in various ways. "Serverless" Aurora, for example, can't scale writes beyond a single instance, so while it can take you quite far (a 96 core db instance can handle a lot of writes), past a certain point it's no longer really serverless anymore since you'll have to figure out some kind of sharding strategy to keep scaling writes. With S3 or DynamoDB, this doesn't happen. While even those services do have some sanity check limitations, they can scale seamlessly up to the point where you start to approach the scale of AWS itself.
Yes, a better word would be great. I think that ship is sailed though...
Not just the "same computer" ... it's the same process id (PID).
Extract of relevant text from that webpage:
>Classic Serverless: The database engine runs within the same process, thread, and address space as the application. There is no message passing or network activity.
In other words, when you compile and link "sqlite.c" into your own executable, the same PID (process) that handles text input and paints pixels on the screen -- is the same PID that writes to the sqlite database file. It's all the same process. That's what they mean by "classic serverless".
In contrast, if you make a Go executable that writes to MySQL/PostgreSQL db and make them both run on the same physical computer, that's not "classic serverless". It's because when you enter "ps -aux" to list all running processes, you see separate PIDs for the Go executable and the MySQL db engine.
Other jargon used might be "in-process" vs "out-of-process" or "embedded" vs "external". SQLite is sometimes characterized as "in-process embedded database" but MySQL is an "out-of-process" db.
It's a bad definition. I would stick with the terms "embedded" or "in-process" which have been around for decades and are well-understood.
I heard many, but what they're writing isn't one of them.
As far as I can tell SQLite was always called an embedded database, and never a serverless one.
It's like someone found this page and felt very smart about it, because they stick it to the serverless crowd.
Well, it's bending the overall consensus defining serverless as a managed / and or stateless service.
I never saw anyone using the term "serverless" to mean "embeded".
Using this definition, anything and everything that is not requiring a specific server to be served / distributed can be described as serverless.
> Using this definition, anything and everything that is not requiring a specific server to be served / distributed can be described as serverless.
The distinction is useful to make when similar systems traditionally rely on a client/server model. Which many DBMS do, to say nothing of RDBMS. That it is server-less is a distinctive feature of SQLite as an RDBMS.
That assertion is quite the stretch because there is no consensus on what serverless actually means. The only thing that exists is that the concept of function-as-a-service is being forced as a placeholder for serverless, but some vendors try to manipulate the definition to include their managed services offerings.
It'd be a better idea to just delete the page. It may have been written long before the meaning changed, but it's pointless to fight a losing and completely insignificant battle over language.
In SQLite's particular case, it's subverting the expectation that has persisted since the beginning of time (of databases) that a database must be managed by a server.
Re: downvotes - what are people disagreeing with? That the term is not convoluted? That it's actually useful? That it helps to have more sub-definitions in an industry known for overloaded terms? I guarantee not a single person here has used "classic serverless" over "in-process" or "embedded" in their entire career.
Also, this page was first written in 2007 (or perhaps earlier) [1], long before 'serverless' was applied to things like Amazon Lambda.
[1]: https://web.archive.org/web/20071115173112/https://www.sqlit...
Just as the term serverless itself?
I find this, old version, superior.
Actually seems more like the original than yet another. And also it makes more sense “serverless” as in “there is no server” and not as in “someone else manages the server for you”.
I'm sure people will google stuff like "Is SQLite serverless?". There are no such thing as stupid questions, you're only stupid if you choose not to learn.
There is a fundamental point the the argument: you can distribute a database without segregating it.
Three methods to building a 1M+ users webapp:
1. A centralized database, eg. PostgreSQL. Typically it has a single-writer beefy machine.
2. A decentralized newSQL. Tables are automatically sharded for writes, among a set of database-only servers. Typically offered as cloud: CosmosDB, Cloud Spanner, Aurora.
3. A distributed system segregated per app. Each user has a dedicated sqlite file.
The third option would be simpler to code for, since it won’t have substantial scaling issues.
It is also easier for a lambda-like platform to provide: load the sqlite corresponding to the authenticated user, and the lambda code, and execute the code in sandbox.
Although one negative aspect for the AWS of this world would be lack of lock-in. It is relatively easy to migrate to another cloud service, or to mix cloud services.