Arezgitfield notes / engineering
Git workflowsUPDATED JUL 13, 2026

Trunk-Based Development vs GitFlow: Choose by Delivery Constraints

A practical comparison of trunk-based development and GitFlow based on release cadence, review capacity, deployment safety, support windows, and team structure.

AREZGIT / FIELD NOTEGIT WORKFLOWS
Trunk based development and GitFlow optimize for different constraints. The wrong question is "which branching model is modern?" The useful question is "which model makes integration, releas
READ / VERIFY / APPLYTECHNICALLY REVIEWED

Trunk-based development and GitFlow optimize for different constraints. The wrong question is "which branching model is modern?" The useful question is "which model makes integration, release, and recovery safest for this product and team?"

Branching strategy cannot compensate for weak tests, slow review, manual deployment, or unclear ownership. Choose a model only after naming those delivery constraints.

What trunk-based development requires

Trunk-based development keeps integration close to the primary branch. Developers merge small changes frequently, often within a day. Long-lived release divergence is minimized, and incomplete behavior is controlled through design, compatibility, or feature flags.

It works well when:

  • Automated checks are fast and trustworthy.
  • Review turnaround is short.
  • Changes can be decomposed into safe increments.
  • Deployment is frequent or decoupled from feature exposure.
  • The primary branch remains releasable.
  • Rollback or forward recovery is routine.

Trunk-based development is not "everyone pushes unreviewed work to main." Teams can use short-lived branches and pull requests while preserving frequent integration.

Its main benefit is reducing merge distance. Conflicts and incompatible assumptions surface while context is fresh.

What GitFlow provides

GitFlow uses persistent branches with distinct roles, commonly a development branch, release branches, and production-oriented main. Feature branches enter development, release branches stabilize a version, and hotfixes target production history.

It can fit when:

  • Releases are scheduled and packaged rather than continuously deployed.
  • Multiple supported production versions need patches.
  • Formal stabilization periods are required.
  • Artifact certification or external approval freezes a release line.
  • Deployment and release are materially different events.

Its strength is explicit release state. Its cost is repeated integration. A fix may need to move between hotfix, main, development, and one or more release branches. The graph communicates process, but it also creates places for changes to drift or disappear.

Compare the integration cost

Branch lifetime and divergence predict integration difficulty better than branch names.

In trunk-based development, small changes integrate often. Feature flags or compatible scaffolding may add code complexity, but merge conflicts remain smaller.

In GitFlow, feature work may converge on development while release work continues elsewhere. Hotfixes must return to every relevant line. Conflict resolution needs strong ownership because a mechanical merge can preserve syntax while losing intent.

Measure:

  • Median branch age
  • Time from ready-for-review to merge
  • Number of open release lines
  • Merge-conflict frequency
  • Rework after integration
  • Hotfix propagation failures

If branches remain open for weeks under either label, the team has a feedback-cycle problem.

Compare release and deployment semantics

For a web service with reliable automated deployment, a releasable trunk plus feature flags often provides the shortest recovery path. The code can deploy before exposure, and the feature can be enabled gradually.

For a signed desktop application, app-store package, embedded product, or regulated artifact, a release branch may be justified after the source freezes for certification. The team can continue integrating future work while applying narrow fixes to the release candidate.

That does not require full GitFlow. A hybrid can use trunk for normal integration and create short-lived release branches only when an artifact enters stabilization.

Name the reason for every persistent branch. "That is our process" is not an operational requirement.

Account for database compatibility

Branch strategy interacts with schema evolution. If trunk deploys frequently, migrations must support overlapping application versions and incremental rollout. Expand-and-contract changes fit this model.

Long-lived release branches make schema divergence dangerous. A hotfix built from an older release may encounter a database already changed by a newer deployment. Desktop clients can remain old for months and must tolerate server evolution explicitly.

Whichever model you choose:

  • Make migrations forward compatible where versions overlap.
  • Keep API contracts compatible with supported clients.
  • Test old application versions against the new schema or server.
  • Do not assume rolling back code rolls back data.

Account for security fixes

Security response needs a clear path from fix to every affected supported version.

Trunk-based teams need confidence that the current trunk can produce a safe release quickly or that a patch can be cut from the affected version. GitFlow teams need an explicit propagation map so a hotfix does not remain only on main.

Maintain a support matrix containing version, branch or tag, deployment population, and end-of-support date. Test the patch on each line and publish artifact provenance.

Complex branch graphs are especially risky during incidents because time pressure encourages skipped merges.

Use feature flags carefully

Feature flags help trunk-based development separate integration from exposure, but they are not free.

Every flag creates multiple behavior states. Define owner, default, rollout metrics, failure mode, and removal date. Protect server-side authorization independently; a hidden frontend control is not a security boundary.

Avoid flags around irreversible data transitions unless both states remain compatible. Test combinations that can exist in production and remove stale flags to prevent configuration archaeology.

A decision framework

Choose trunk-based development when most statements are true:

  • The primary branch can remain releasable.
  • Review and checks complete within hours.
  • Work can merge in small compatible slices.
  • Deployment is automated and observable.
  • Incomplete behavior can remain safely unavailable.
  • The team prefers forward recovery over long stabilization.

Use release branches when one or more statements are materially true:

  • A signed artifact enters a formal stabilization window.
  • External certification fixes a source baseline.
  • Multiple production versions receive patches.
  • Deployment happens through delayed customer-controlled distribution.
  • A release candidate needs narrow changes while future development continues.

Even then, keep release branches few, named by version, and closed after support ends.

Make the strategy enforceable

Document:

  • Branch purposes and lifetime expectations
  • Merge direction
  • Required checks
  • Release tagging and signing
  • Hotfix propagation
  • Who can override protections
  • How abandoned branches are closed
  • How supported versions map to branches or tags

Configure protections to match the document. A written rule without repository enforcement becomes folklore.

The best branching strategy reduces the distance between a change and the evidence that it integrates safely. For many teams, that means short-lived branches into a releasable trunk, with release branches only for real distribution constraints. Choose from the product's delivery reality, measure the cost, and simplify when the graph becomes harder to reason about than the software.