Hotfix Workflow
A hotfix is an urgent fix applied directly to production code, bypassing the normal development cycle. The word "hotfix" implies urgency: something is broken in production right now and users are affected. A payment processor is returning errors, a security vulnerability has been discovered, or a data-loss bug slipped through. Normal feature-branch process is too slow — you need a way to get a fix into production within minutes or hours, not days.
This guide covers hotfix procedures for both GitHub Flow and Gitflow, with full command walkthroughs, version bumping, tagging, team communication, and post-fix monitoring.
What Makes a Hotfix Different
Characteristic | Normal feature branch | Hotfix branch |
|---|---|---|
Source branch | main or develop | main (the tag in production) |
Target branch(es) | main | main AND develop (Gitflow) / main (GitHub Flow) |
Review process | Normal review cycle | Expedited — 1 approval, immediate merge |
CI requirements | All checks pass | All checks pass (never skip) |
Urgency | Low–medium | High — production is impacted |
Scope | Can be large | Minimal — one bug, no refactoring |
Version bump | Minor or patch on next release | Immediate patch version bump |
GitHub Flow Hotfix
GitHub Flow has no develop branch, so a hotfix is just a short-lived branch from main with an expedited review.
1. Ensure main reflects what is in production
git checkout main git pull origin main # From github.com:org/project # * branch main -> FETCH_HEAD
2. Create a hotfix branch from main
git checkout -b hotfix/payment-null-pointer # Switched to a new branch 'hotfix/payment-null-pointer'
3. Make the minimal fix
# Edit only the affected file(s) # src/services/payment.ts — add null check before processing git add src/services/payment.ts git commit -m "fix(payment): add null check before charge processing Fixes a NullPointerException when the customer object is missing the billing_address field. Added optional chaining and a fallback to the account address. Fixes #501"
4. Bump the patch version
# package.json: 2.4.1 -> 2.4.2 npm version patch --no-git-tag-version # v2.4.2 git add package.json package-lock.json git commit -m "chore(release): bump version to 2.4.2"
5. Push and open an expedited PR
git push origin hotfix/payment-null-pointer # remote: Create a pull request: # remote: https://github.com/org/project/pull/new/hotfix/payment-null-pointer
Ping reviewers directly in Slack/Teams. Do not wait for the normal review cycle. One approval is sufficient for a hotfix.
6. After merge — tag the release
git checkout main git pull origin main git tag -a v2.4.2 -m "Hotfix v2.4.2 - fix(payment): add null check before charge processing Fixes NullPointerException when billing_address is missing (#501)" git push origin v2.4.2
7. Deploy and clean up
# Trigger your deployment pipeline (CI/CD will pick up the tag) # OR deploy manually: git push origin main # if your CD watches main # Delete the hotfix branch git branch -d hotfix/payment-null-pointer git push origin --delete hotfix/payment-null-pointer
Gitflow Hotfix Process
Gitflow has both a main branch (production) and a develop branch (integration). A hotfix must be applied to both so that the fix is not lost in the next release cycle.
1. Branch from main (not develop)
git checkout main git pull origin main git checkout -b hotfix/2.4.2 # Switched to a new branch 'hotfix/2.4.2' # Note: branch from the production tag if main has moved since deployment # git checkout -b hotfix/2.4.2 v2.4.1
2. Bump version and make the fix
# Bump version in package.json to 2.4.2 npm version patch --no-git-tag-version git add package.json package-lock.json git commit -m "chore(release): bump version to 2.4.2" # Apply the fix git add src/services/payment.ts git commit -m "fix(payment): add null check before charge processing"
3. Merge into main and tag
git checkout main git merge --no-ff hotfix/2.4.2 -m "Merge hotfix/2.4.2 into main" git tag -a v2.4.2 -m "Hotfix v2.4.2: payment null pointer fix" git push origin main --follow-tags
4. Merge into develop so fix is not lost
git checkout develop git pull origin develop git merge --no-ff hotfix/2.4.2 -m "Merge hotfix/2.4.2 into develop" git push origin develop
5. Delete the hotfix branch
git branch -d hotfix/2.4.2 git push origin --delete hotfix/2.4.2
Semantic Version Bumping for Hotfixes
Hotfixes always increment the patch version — the third number in MAJOR.MINOR.PATCH:
Version before | Type of change | Version after |
|---|---|---|
2.4.1 | Hotfix (bug fix only) | 2.4.2 |
2.4.1 | New feature (not a hotfix) | 2.5.0 |
2.4.1 | Breaking API change (not a hotfix) | 3.0.0 |
Bump version in common project types
# Node.js / package.json npm version patch --no-git-tag-version # Output: v2.4.2 # Python / pyproject.toml (using bump2version) bump2version patch # Edits pyproject.toml: version = "2.4.2" # Go / manually edit version file # sed -i 's/Version = "2.4.1"/Version = "2.4.2"/' version.go # Manual (any project) # Edit the version field in your config file, then: git add . git commit -m "chore(release): bump version to 2.4.2"
Tagging the Hotfix Release
Create an annotated tag with release notes
git tag -a v2.4.2 -m "Hotfix v2.4.2 Changes: - fix(payment): add null check before charge processing (#501) Impact: - Fixes NullPointerException causing 5xx errors on checkout page - No database migrations required - Safe to deploy with zero downtime" # Push the tag git push origin v2.4.2 # Verify the tag was pushed git ls-remote --tags origin # refs/tags/v2.4.2 a3f9c2145b8d...
Create a GitHub Release from the tag (using gh CLI)
gh release create v2.4.2 \ --title "v2.4.2 — Payment hotfix" \ --notes "## Hotfix ### Bug Fixes - **payment**: Add null check before charge processing (#501) ### Deployment notes No migrations required. Rollback is safe."
Communicating the Hotfix to the Team
A hotfix affects everyone. Communication should happen at three points: when you start, when you deploy, and after you verify.
When you start the hotfix:
Slack message: hotfix started
🚨 HOTFIX IN PROGRESS 🚨 Issue: NullPointerException on /checkout causing 5xx errors (issue #501) Impact: ~12% of checkout attempts failing since 14:32 UTC Branch: hotfix/payment-null-pointer PR: https://github.com/org/project/pull/502 ETA: ~30 minutes to deploy @reviewer1 @reviewer2 — expedited review needed ASAP
When you deploy:
Slack message: hotfix deployed
✅ HOTFIX DEPLOYED v2.4.2 is now live on production. Commit: a3f9c21 Deployed at: 15:04 UTC Monitoring error rates now. Will confirm fix in 15 minutes.
Post-Hotfix: Verify and Monitor
Immediately after deploy: check error monitoring (Sentry, Datadog, Rollbar) — error rate for the affected endpoint should drop to baseline within minutes.
Check application logs for the specific exception that was reported — confirm it is no longer appearing.
Run a manual smoke test of the affected user flow end-to-end.
Monitor for 30 minutes before declaring the incident resolved.
Write a post-mortem (for major incidents): what happened, timeline, root cause, resolution, how to prevent recurrence.
Backfill any missing test coverage — the hotfix exposed a gap in your test suite.
Update your CHANGELOG.md or GitHub Release notes.
Close the incident in your incident management tool (PagerDuty, Opsgenie, etc.).