Generate custom courses on any topic — with hands-on practice, AI guidance, and visuals built in.
Already have an account?
A database is the part of an app that stores data so it still exists after the app restarts, the server crashes, or the power goes out. The app can later ask for that data back in specific shapes, like one record by id or a list filtered by a user.
To make “data” concrete, use a tiny task list product. Each task is a record with fields like task_id, user_id, title, completed, and created_at, and the app needs two basic actions. One action creates a task, and the other lists a user’s tasks.
With a single-server baseline, the client sends HTTP requests to an app server, and the app server reads and writes rows in one database. The database creates correctness by enforcing rules like “a task row is written once per request,” and it creates latency because reads and writes take time on disk and in memory. Let’s trace the two request paths on one box diagram.
On a create-task request, the app server validates input, then asks the database to insert one new task row, then returns the new task_id to the client. The client experiences the write as durable only after the database confirms the write, which is why the database sits on the critical path for correctness.
On a list-tasks request, the app server asks the database for all tasks where user_id matches, often sorted by created_at, then the app server formats the response. When that query scans more rows than it needs, the database does more work and the client waits longer, so performance starts to hinge on how the database finds matching rows.
As more users add tasks, the first visible failure is usually that list-tasks gets slow because the database reads too much data to answer one query. Next, a hot user or shared list can create lock waits where many writes try to update the same row or set of rows, so requests queue behind each other instead of completing in parallel. Finally, if the single database process or machine dies, the whole app stops serving because every request depends on it. The next diagram marks those three pressure points on the same baseline.