When developing a piece of software, it is important to think of what kind of environments you may need.

Here are a list of questions targeted at helping you identify the needs:

  1. Where do you develop?
    • Locally
    • On the we
  2. Where do you run you tests?
    • Specific machine
    • Load tests
    • Test-suite
    • Regressions
  3. Where do you test a feature that has not been merged?
  4. Where do other people test your code?
    • Other developers
    • Non-developers - Quality assurance / engineers
    • Internal services integrations
    • External customers
  5. How do you cherry-pick / hotfix to an environment?
  6. How / where do you debug a issue that happened?
  7. Do you need external services to integrate in a sandboxed environment?
  8. How does each environment interact with 3rd parties?
    • E-mail
    • External request
    • Services
    • Databases (Read - Read & Write - Append)
  9. Where do you test recovery
    • Revert of code to a previous state
    • Revert of data to a previous state
    • Revert of schema to a previous state
    • Recovering multiple of the above (imagine an earthquake taking your system down…)

Hereafter is a flow I came up with that addresses many of these questions. While specific questions might be addressed with specific environments.



This is the most important environment. It should have latest version of your stable code, should be up with 100% availability and perform all actions your application is meant to do. It contacts other parties production environment.

Its database should be back-up on regular intervals for data-recovery purposes. Backup could be both automatic (scheduled) or manual (eg: before something big is about to change, we may want an up-to-date copy).

Some common backup strategies are exponential. Example: backup every 1’, 2’, 5’, 10’, 60’, 3h, 6h, 1d.


This is an exact copy of your production environment.

It can be used internally to mimic a bug encountered in a production environment. Periodically and/or on demand the database is reset with that of production.

This is the primary environment used to debug production issues as it has similar data at a moment T defined by the user and any changes made on this environment can be undone with the push of a button. It also shields from debugging directly in production thereby not affecting live customers.

Use case example: A customer has a problem with his account. Maybe deleting the user and re-creating it solves the issue. How can this be tried without affecting the actual customer? (what happens if it works? what happens if it does not?)


This environment is for integrations with other services. Every end of sprint, this gets deployed and if no regressions are nd, this release makes it to production.

This is a common ground for di erent services to integrate with each other. (Automated scripts, etc.)

A version of staging goes to production on a regular basis.

The database is filled with seed data and easily reproducible. It gets destroyed and re-seeded on a regular basis.

This also has the backup of database so we can try our rollback strategies. We could also have the same backup strategy as in production. This is so that we have a place where we can test our emergency procedure (we would not want to have to use our recovery system and have it fail!)

Use case: I want to simulate something going bad in production and having to restore the database at a t - 1 day.


This is where QA runs their tests as the sprint evolves.

This is where the CI goes. Every green build, a new version of QA gets deployed. A copy of QA goes to staging-future on a periodic basis (when a sprint ends). The database is filled with seed data and easily reproducible. It gets destroyed and re-seeded on a regular basis.

Test [0..*]

These are environments available to the developer to deploy code to test a feature out without having to merge their code (ie: deploy and share a branch).

The database is filled with seed data and easily reproducible. It gets destroyed and re-seeded on demand.


This is a server-branch that makes it straight to staging, then to production. It allows for hotfix deploys while something is in the pipeline.

Dev box

This is the developer’s local machine. Here, the developer is free to try anything he wants: different technologies, different background tiers, foreground tiers, branches, code, etc.

                            [ DEV BOX ]
            /------------------- | ------------------- \
          /                      |                       \
        /                        |                         \
    Deploy to testing      Merge to master             Cherry-Pick/Hotfix
      |                          |                                |
      |                          |                                |
      |                          |                                |
      |                          |                                |
  [ Testing.* ]               [ QA ]                          [ Release ]
                                 |                            /
                                 |                         /
                                 |                      /
                              Staging cut
                                 |                   /
                                 |                /
                                 |             /
                                 |          /
                                 |       /
                              [ Staging ]
                            [ Production ] --- Mirror ---> [ Production Copy ]