Skip to main content

Branching

The way that "infrastructure" (like databases, event queues, object storage, and servers) is configured and deployed is fundamentally at-odds with the way that "features" are built and shipped. Features are implemented as part of a codebase, and the code changes for a feature are grouped into branches and introduced through pull requests.

Platter resources are built with this feature-first model in mind, including built-in support for integration with git branches. Let's take a look at how Postgres branches powered by git can help avoid the complexity of environment-based configuration.

What is Branching?#

When working with git in a codebase, creating a new "branch" means creating a point-in-time copy of the entire state of the project that can be changed independently from any other branch. The same is true for a Platter service: creating a new "branch" of a resource means copying any state or configuration that applies to that service at a point in time and making it easy to throw that copy away later.

Much like git has commands to create new branches based on the existing HEAD/checked-out branch (i.e. git branch and git checkout --branch), Platter resources also have a branch command. This creates a new copy of that resource at a point in time, and a collection of these branches is called an "instance".

Branching Postgres#

When you run platter postgres create, a new instance is created with a single "trunk" branch (typically called main). An "instance" is analgous to a git "repository", in the sense that it is a collection of different branches. Each branch of a Postgres instance is its own independent database, cloned from another branch (typically the trunk branch configured during instance creation). These branches can be accessed independently through connection strings generated by the url command, or through generated clients.

You might develop against an instance's trunk branch directly to start, just like you would with the rest of your git-powered codebase. Much like your application code, end users will probably interact with this trunk branch, too. Eventually, though, you'll want to develop new features on separate feature branches. And when those features require schema changes to your database, you'll want to iterate on those schema changes against a copy (or branch) of production data.

platter watch#

In projects that use explicitly-configured Platter resources and generated clients, branching and client generation during feature work can be automated with the watch command:

watch coordinates the creation of new branches based on previously-checked-out git branches and generates any pre-configured clients.

Why Branching Matters#

There are some immediate benefits to the branching workflow for developers and users alike:

  1. There are no more local development instances of Postgres to run, as all development work is done against the exact same production infrastructure your users will interact with. This is important, since it means that bugs arising from differences between what is hosted in the cloud and what's possible to run locally will disappear!

  2. There's no more manual state transfer: all branches copy the data of their parent at the time of their creation, so all of the logic required to pg_dump and spin up new instances can be removed from the workflow entirely.

  3. Shareability: sharing data is as easy as sharing the name of a branch. And once resource branches are tied to git branches, switching between ongoing feature work is as easy as git checkout.