[NTTP]
Developers

How to write good commit messages and PR descriptions

August 21, 2026 · 4 min read

Why the diff is not the message

A diff already shows what lines changed. A commit message or a pull request description that just restates the diff in prose is wasted words. What a reviewer or a future you actually needs is the reasoning: why the change happened, what problem it solved, and what was considered along the way. Write for that gap, not for the parts a tool can already show.

A commit message is two things, not one

The first line is a short, imperative summary, under about 72 characters, written as an instruction: “Fix session expiry retry logic”, not “Fixed” or “This commit fixes”. That line alone is often enough. Only add a body paragraph when the change genuinely needs explaining: a non-obvious bug, a tradeoff you made, or something a reviewer scanning history later would want to know. A small, self-explanatory change does not need a body at all. Padding every commit with a body is as bad as never writing one.

What a good PR description actually contains

Open with two or three sentences on what changed and why, leading with the motivation rather than the mechanics. Follow with a “What changed” section as bullet points, one change per bullet, specific rather than vague. Add a “Testing” section only if you actually tested the change and can describe how. Never invent test steps just to fill the section; an honest description with no testing section beats a fabricated one.

Commit message: Fix session expiry retry logic Sessions were expiring mid-request under load because the refresh call had no retry. Added a single retry with backoff so a transient failure does not log the user out. Covered by the new session test. PR description: Users were getting logged out mid-session under load. The session refresh call had no retry, so any transient failure on that request expired the session immediately. What changed - Added a single retry with backoff to the session refresh call - Logged retry attempts for easier debugging in production - Added a test covering the retry path Testing - Ran the new session test locally, confirmed it fails without the retry and passes with it - Manually throttled the network in dev tools to trigger a transient failure and confirmed the session survived

Common mistakes

← All guides