I'm new to web development and used to simpler single-language projects, so server-side storage feels surprisingly complicated. If an application only needs to save small pieces of user data—such as a preference—what prevents me from writing that data to a JSON file in the same directory as the application? When is a proper database necessary, and are there simple alternatives for a small project?
4 Answers
You do not necessarily need a large hosted database service. For learning or a small single-server project, SQLite is usually enough. PostgreSQL becomes a good choice when you need multiple application instances, more concurrent writes, complex queries, or room to grow. Uploaded files are commonly kept in a file storage area or object storage, while the database stores their paths and related metadata.
For a tiny app running on one machine with very few users, nothing technically prevents you from using a JSON file. The trouble starts when requests overlap, because two writes can race with each other, or a crash can leave the file only half-written. You also have to rewrite and parse the entire file for small changes. SQLite is often the best beginner-friendly compromise: it is still just one local file, but it handles transactions, locking, indexes, and recovery for you.
Data integrity is another major concern. With a JSON file, one failed write could make the whole dataset unreadable, and you would need to build safeguards yourself. For a small read-only cache or a private tool with one person editing it, JSON can be perfectly reasonable. For orders, accounts, payments, or anything important, you generally want transactions, backups, permissions, and reliable recovery rather than inventing all of that around a file.
The biggest scaling issue is that a local file belongs to one machine. If the application later runs on several servers behind a load balancer, each server may have a different copy of the file. You can add shared storage or sticky sessions, but those introduce their own problems. A database gives all application instances a shared source of truth and can handle queries without loading millions of records into memory.

That makes sense. SQLite sounds closer to the simple file-based setup I was imagining, while avoiding the worst failure cases.