Software engineering and system design guides
System design and software engineering in plain English: APIs, caching, queues, scaling, architecture, testing and technical debt.

How to undo mistakes in Git: restore, reset, revert and reflog
Undo almost anything in Git: unsaved edits, a bad commit, a pushed commit or a lost branch, with the right command for each and when it's safe.

A simple Git branching workflow for small teams
A Git workflow for teams of one to ten: short-lived branches, pull requests and a main branch that’s always deployable, with the exact commands.

Technical debt explained: what it is, what it costs, and how to pay it down
What technical debt means in plain words, how it slows a project down, how to spot it, and a practical way to pay it down without stopping new work.

The testing pyramid explained: unit, integration and end-to-end tests
What unit, integration and end-to-end tests are, how many of each to write, an example with Node’s built-in test runner, and what to test first.

How to structure a Node.js backend: routes, services and data access
A proven way to organise a Node.js and Express backend into routes, services and repositories, with folders by feature and code that’s easy to test.

Monolith vs microservices: which architecture should you choose?
The real trade-offs between a monolith and microservices, why most projects should start with a modular monolith, and when to split off a service.

How to scale a web app: a step-by-step guide to system design basics
How a web app grows from one server to many: load balancers, caching, read replicas, queues and CDNs, and when each step is worth it.

Message queues and background jobs explained, with a working example
Why slow work like emails and API calls belongs in a background job, how queues, workers and retries fit together, with a small working job queue.

Caching explained: where to cache, for how long, and how to keep it fresh
How caching makes sites and APIs faster: browser, CDN and server caches, Cache-Control headers, a Node.js example, and how to avoid showing stale data.

Rate limiting explained: protect your API from abuse and overload
What rate limiting is, how fixed window and token bucket limits work, a working Express middleware, and how to set limits that don’t block real users.

Idempotency explained: how to make API requests safe to retry
What idempotency means, why retries create duplicate orders and charges, and how idempotency keys and unique constraints make requests safe to repeat.

Authentication explained: sessions, JWTs and API keys, and when to use each
How login works on the web, authentication vs authorisation, and when to use session cookies, JWTs or API keys, with the security settings that matter.

REST API design best practices: URLs, status codes, errors and pagination
How to design a REST API that’s easy to use, with examples for URLs, HTTP methods, status codes, error messages, pagination and versioning.

Database transactions explained: ACID, rollbacks and race conditions
What a database transaction is, ACID in plain words, BEGIN, COMMIT and ROLLBACK in code, and how to stop two orders selling the last item twice.

SQL vs NoSQL: how to choose a database for your project
The real differences between SQL and NoSQL databases, with the same data stored both ways, the kinds of NoSQL, and a simple way to choose for your project.

Database indexes explained: how to make slow queries fast
What a database index is, how it turns a full table scan into a quick lookup, which columns to index, how column order works, and what indexes cost.

Database design basics: tables, keys and relationships, with a real example
How to design a relational database step by step, with a small shop example covering tables, primary and foreign keys, relationships and constraints.