From Monolith to Microservices: How We Fixed Branching in a Banking Project

When I worked on a banking project, we hit a serious pain point. The application was a monolith, and the business decided to move toward microservices architecture. That meant multiple services, multiple developers, and a lot of Git chaos.
At one point, we had 20 developers all creating branches however they liked. The result? More than 50 stale branches older than 90 days sitting around. No one was cleaning them up, and people weren’t sure which branch was safe to use. Releases were painful, QA was frustrated, and production fixes took too long.
It became clear: we didn’t just need microservices in the code — we needed micro-discipline in branching.
The branching mess we inherited
Developers created branches without a naming convention.
Some feature branches lived for months (and were never merged).
QA didn’t have a clean snapshot to test from.
Production bugs meant developers scrambling to figure out where to fix and merge.
This was risky in a banking environment, where every release needed to be stable, auditable, and fast to fix if issues arose.
What we evaluated
GitFlow
Pros: Clear structure (
main
,develop
,release
,hotfix
). Predictable.Cons: Too heavy. Having both
main
anddevelop
confused developers. Double merging slowed us down. In microservices, it added unnecessary ceremony.
GitHub Flow
Pros: Super simple — one
main
, feature branches, and PRs.Cons: Assumes you can push to production many times a day. In banking, we needed QA cycles and compliance checks. GitHub Flow didn’t fit our reality.
Trunk-Based Development (TBD)
Pros: Simple, short-lived branches, fast integration, fewer merge conflicts.
Cons: Needs strong CI/CD and discipline, otherwise
main
breaks.
What we chose (and why)
We went with Trunk-Based Development (TBD), customized for banking needs.
main
branchOur single source of truth.
Always deployable, always stable.
Protected by rules: no direct pushes, PRs only, 2 reviews, CI checks must pass.
Feature branches (
feature/*
)Created per task/service, e.g.,
feature/payment-service
.Short-lived (1–7 days). No more 90-day zombie branches.
Deleted after merge to keep the repo clean.
Release tags
Instead of long-lived
release
branches, we used tags.Example:
git tag -a v1.0.0 -m "Release v1.0.0 to QA"
git push origin v1.0.0
- QA tested against the tagged commit. Once approved, the same commit (or a new tag) went to Prod.
Hotfix branches (
hotfix/*
)Created directly from
main
when urgent production issues arose.Example:
hotfix/payment-timeout
.Merged back to
main
, tagged, deployed fast.
How it looked (simplified)
flowchart LR
A[main] -->|branch| B[feature/*]
B -->|PR + merge| A
A -->|tag| C[(QA Release Tag)]
C --> D[(Prod Release Tag)]
A -->|branch| E[hotfix/*]
E -->|merge + tag| A
Comparison: GitFlow vs GitHub Flow vs Trunk-Based
Strategy | Pros | Cons | When to use |
GitFlow | Clear separation of work, predictable release process | Heavy, confusing, slows delivery | Enterprises with fixed release cycles |
GitHub Flow | Simple, fast, great for CI/CD | No QA branch, assumes frequent prod deploys | Startups, SaaS, continuous deployment teams |
Trunk-Based | Fast feedback, fewer stale branches, clean history | Needs discipline, strong CI/CD | Large teams, microservices, regulated domains (like banking) |
Why it worked in banking
✅ No more stale branches — every feature branch had a short life.
✅ QA was happy — they got clean, tagged builds to test.
✅ Auditors were satisfied — tags created a clear release trail.
✅ Developers moved faster — smaller conflicts, faster merges.
✅ Production was safer — hotfixes were isolated and quickly tagged.
My takeaways
Don’t blindly adopt GitFlow, GitHub Flow, or TBD — check what works for your domain.
In regulated industries like banking, you need both speed and auditability.
For us, a Trunk-Based strategy with tags and hotfix branches was the sweet spot.
The result: we went from branch chaos to clean, auditable, and faster delivery — exactly what the bank needed.
👉 If your repo feels like a jungle of stale branches, consider tightening with trunk-based + tagging. It saved our team, and it might save yours too.
Subscribe to my newsletter
Read articles from Chandra Sekhar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Chandra Sekhar
Chandra Sekhar
I’m a DevOps and Cloud Engineer with 3+ years of hands-on experience designing and managing infrastructure on AWS. Over my career, I’ve worked on automating deployments, building CI/CD pipelines, and optimizing cloud resources for scalability and cost-efficiency. My daily toolkit includes AWS (EC2, S3, RDS, VPC, IAM, Lambda), Terraform, Docker, Kubernetes, and Jenkins/GitHub Actions. I enjoy breaking down complex infra problems into simple workflows and sharing those solutions with the community. On Hashnode, I write about Git best practices, AWS architecture patterns, Infrastructure as Code, CI/CD pipelines, and real-world DevOps case studies. My goal is to simplify cloud and DevOps concepts for developers and engineers who are just starting out or scaling their systems.