Skip to main contentTailor AI LogoTailor AI
    Engineering Blog
    Agentic Coding3 min read

    Five Standing Dev Environments

    Greg Bayer
    Greg Bayer

    CEO & Co-founder

    Five Standing Dev Environments

    Once you work on more than one branch a day, the bottleneck stops being the code and becomes the environment. Two branches want the same port. Two dev servers want the same test org. An e2e run on one branch stomps the JWT the other was using.

    Our answer is five standing worktree folders that never move.

    Each slot sits beside the main checkout with its own ports, subdomain, seeded test org, and JWT. Five branches run at once. Five e2e suites run at once. Nothing collides.

    Isolation is the easy part. The work went into making it something you set up once and then stop thinking about.

    You switch branches inside a slot, not slots inside a branch

    The folders are permanent. Starting a project means picking a free slot and putting a branch on it. Env files and slot attachment survive the switch, so there's no re-setup. The main checkout becomes a pure git hub for pulls and browsing.

    Setup is one command, and it's re-runnable

    One script creates all five, copies your secrets over, attaches each to its slot, and installs. Run it again and it skips what exists, including finishing an attach that got interrupted halfway. Idempotent setup is worth the extra hour, because the alternative is people abandoning the tool after one bad run.

    It refuses rather than guesses

    Earlier versions silently attached your current checkout when nothing claimed a slot. Convenient, until two checkouts claim the same slot and the subdomain serves whichever started first. That's a genuinely confusing afternoon. It now refuses and prints the exact command to fix it.

    Running them

    A later addition starts every slot from one terminal: interactive bits (sudo, first-time seeding) run one at a time up front, then all servers in parallel with color-coded per-slot log prefixes. Ctrl-C stops them all cleanly.

    Not everyone uses it, and the objection from our own team is a good one. Dev servers get wedged sometimes, and when they do you want finer control over one slot and its live logs in its own window. So the single-slot command still works exactly as it did. The one-terminal version is an option, not a migration.

    Worth saying, because internal tooling has a failure mode where the new thing quietly obsoletes the old workflow and everyone who liked the old workflow is now annoyed. Adding an option is cheaper than winning an argument.

    One preflight check

    Every run now confirms Postgres and Memcached are actually accepting connections before it tries to seed, and starts a stopped service if it finds one. It's silent when they're already up.

    Without it, a machine whose Postgres didn't come back after a reboot fails at the seeding step with a bare connection-refused, several minutes into setup, pointing at entirely the wrong thing.