Where does your work go when you close the tab? · slopware 101

slopware 101 · step 6 of 35

Where does your work go when you close the tab?

by · 3 min read

The browser can send a request and the service can answer it. But when that request adds a task, where does the task stay? Close the tab, open a second device, or restart the server, and the answer starts to matter. Each place we can keep it has different limits.

Take a to-do app as the example and walk it through four homes.

In a variable

let tasks = [];

A variable is the shortest promise. It lives in the memory of one tab and goes when the tab is refreshed or closed. That is fine for things like which filter is selected, and not fine for the tasks themselves.

In the browser

localStorage.setItem('tasks', JSON.stringify(tasks));
const saved = JSON.parse(localStorage.getItem('tasks') ?? '[]');

localStorage holds strings, so the list is turned into JSON on the way in and back on the way out. It belongs to one origin, which is the scheme, host and port together, so localhost:3000 and localhost:5173 have separate storage. It lives in one browser on one device. Your phone has never seen the tasks on your laptop.

It has a size limit set by the browser, commonly a few megabytes per origin, but that number is the browser's choice and not something to design around. When it is full, setItem throws an error. For larger or structured data the browser offers IndexedDB, which has its own limits, also decided by the browser.

localStorage is not the cache. The cache holds copies of files the browser downloaded, so pages open faster, and the browser drops them whenever it likes. localStorage is site data your code wrote. Clearing cached files leaves it alone. Clearing cookies and site data removes it. Private windows discard it when they close, some browsers clear storage for sites that have not been visited in a while, and the user can wipe it at any moment. Browser storage is a convenience the browser offers, not a promise it keeps.

For a local measurement calculator, keeping inputs on the device can be a deliberate choice. The question is whether losing those inputs is acceptable and whether the person needs them on another device.

In a file on a server

A JSON file on persistent server storage can survive a restart and serve the same tasks to several devices. A temporary container filesystem may not survive replacement. Concurrent updates need coordination: consider a simple read-modify-write handler with no locking. Both read the file, both add their task to what they read, both write it back, and the second write erases the first task. A crash halfway through a write can leave half a file.

Someone who chooses a JSON file for a small tool and can name that limit has made a good decision. Someone who chose it without knowing has made the same choice and a different decision.

In a database

A database is not the mysterious drum in the diagrams. It is a program running on a computer, keeping files on its disk, and what it sells you is two things.

In a relational database, a schema describes the row and constraints enforce the rules you actually declare. A NOT NULL constraint can reject a missing title; rejecting an empty title requires an additional rule. The database cannot infer what valid means for your product.

The second is the transaction. Moving a task from one list to another is two writes, and a transaction makes them one: either both happen or neither does. Its scope is the database. If your code sends an email or charges a card in the middle of a transaction and the transaction is rolled back, the database cannot take back the email. Know what is inside the transaction and what is outside it.

A change to the schema travels in the same git history as the code, and later chapters are about doing that safely and about the difference between having a backup and being able to restore one.

How long data lives is a decision

Once data reaches your side, how long it lives is something you write down rather than forget. Write what each field is for and when it should be removed. The technical mechanism is concrete: a deletion job must run, reach the copies you control and report failures. A later chapter follows that lifecycle.

Your data

Open your project, pick one thing a user creates, and find where it is stored. You can see localStorage in the Application panel in Chrome or the Storage panel in Firefox. Then write three short answers: where it lives, who can read it, and what would erase it.

Further reading: MDN: cache and storage are separate.