Operations · 6 min read

QA Environment Scheduling for Multiple Teams

Lockit Team · 2026-10-15

One QA environment and one team is a coordination problem you can solve by talking. Three QA environments and six teams is a scheduling problem, and it rarely gets solved on purpose. It gets solved by whoever is loudest in the channel that morning.

The symptoms are familiar. A team's regression run fails because another team deployed mid-run. A release slips because the "integration" environment has been held by a feature team for four days. QA leads spend part of every standup negotiating who gets what.

This guide covers how to structure QA environment sharing across multiple teams: the allocation models, how to separate planned windows from ad-hoc use, how to make CI obey the same rules, and the short policy you should write down.

Step 1: Inventory what you actually have

Before you pick a model, list every environment and what it's for. Be specific.

EnvironmentPurposeShared withContention
qa-1Feature testingTeams A, BHigh
qa-2Feature testingTeams C, DMedium
qa-intCross-team integration, release candidatesEveryoneHigh near releases
perfLoad testsPlatform, on requestLow but long sessions
uatCustomer/partner acceptanceProduct, CSScheduled

Two things usually fall out of this exercise. First, environments that people call by the same name are actually different things with different rules. Second, some "environments" are really a shared dependency inside one, like a single partner sandbox or one test database. Those need to be listed separately, because they're often the true bottleneck. See shared test database access for that case.

Step 2: Choose an allocation model

There are four common models. Most organisations mix them.

Dedicated per team

Each team gets its own environment. No coordination needed within the team beyond normal chat.

  • Works when: you can afford one per team and teams rarely need each other's services in a specific state.
  • Breaks when: cross-team integration testing needs one place where everything is on the right version.

Shared pool, first come

A pool of identical environments (qa-1 to qa-3). Anyone can take any free one, for a limited time.

  • Works when: environments are interchangeable and most sessions are short.
  • Breaks when: there's no visible record of who holds what, or claims never expire.

Planned windows

An environment is reserved for a team for a fixed window: "Team C has qa-int Tuesday 9:00 to 13:00 for the payments regression."

  • Works when: sessions are long and predictable, like regression suites, UAT with external participants or release-candidate testing.
  • Breaks when: used for everything. Planned windows waste capacity when the session ends early and nobody releases the slot.

Release-train ownership

The integration environment belongs to the release manager during a defined freeze period. Nobody deploys without them.

  • Works when: you ship on a fixed cadence.
  • Breaks when: the freeze is informal and people deploy "just a small fix."

A practical mix for six teams and three environments: two shared-pool environments for ad-hoc feature testing, one integration environment with planned windows near releases and first-come use the rest of the time.

Step 3: Separate planned windows from ad-hoc use

This is where most teams go wrong. They try to run everything through one mechanism.

Planned windows are calendar events. They're decided in advance, often in a planning meeting, and they need to be visible a week ahead. A shared calendar or the release calendar is the right home for them.

Ad-hoc use is "I need qa-1 for the next hour to check my fix." Putting that on a calendar is overhead nobody keeps up with. It needs a fast, visible claim with an automatic end.

The handoff between them is the important part. When a planned window starts, the team that owns it takes the environment the same way as any ad-hoc user: they lock it. That way there's one place to check who has the environment right now, regardless of how the slot was decided.

Step 4: Make CI follow the same rules

If pipelines deploy to QA environments, they need to claim them too. Otherwise a human locks qa-int, starts a regression run, and a merge to main triggers an automated deploy over the top.

Two levels:

Pipeline-to-pipeline. Most CI systems can serialise jobs that target the same environment. In GitLab CI, resource_group limits jobs sharing a group to running one at a time, and it's available on all tiers including Free:

deploy_qa_int:
  stage: deploy
  environment: qa-int
  resource_group: qa-int
  script:
    - ./deploy.sh qa-int

GitHub Actions has concurrency groups for the same purpose. We compared the two approaches in GitHub Actions concurrency vs environment locks.

Pipeline-to-human. CI concurrency controls only know about other pipelines. They don't know that a QA engineer is halfway through a manual test. For that, the pipeline needs to check and take the same lock humans use. The pattern is covered in detail in locking staging from CI/CD.

Step 5: Write the policy down

Keep it short enough to pin in a channel. A template:

QA environments

  • qa-1, qa-2: first come. Lock before you deploy. Default lock is 2 hours.
  • qa-int: planned windows on the release calendar during release week. First come otherwise, 2 hour default.
  • perf: ask in #platform first. Lock for the duration of the test.
  • Release when you're done, even if your lock has time left.
  • Need an environment someone else holds? Use "Alert when released." If you're blocked on a release, "Ask for takeover."
  • Pipelines lock before deploying. Don't deploy to an environment you haven't locked.

Running the ad-hoc part with Lockit

Lockit handles the first-come locking side in Slack, Discord or Microsoft Teams. Each environment becomes a resource:

@Lockit new

The form asks for a name, a description and an optional channel for lock and release updates, such as #qa-envs. Then:

@Lockit lock qa-1
@Lockit release qa-1
@Lockit list

@Lockit list shows every environment with its status and Lock, Edit and Delete buttons. When an environment is taken, people see who holds it and until when, plus Alert when released and Ask for takeover. The holder gets Release and Approve and Reject Request buttons for takeover requests.

Lock length comes from the duration given when locking, else the resource's default, else the workspace default, else 48 hours. On a paid plan, set per-environment defaults through the API:

curl -X POST \
  -H "X-API-KEY: $LOCKIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"defaultLockHours": 2}' \
  https://api.lockitbot.com/api/locky/resources/qa-1/default-duration

Pipelines can lock with POST /resources/{name}/lock and release with POST /resources/{name}/release using the same key. The API currently works with Slack workspaces only. Full reference in the API docs.

What Lockit doesn't cover: planned windows. Lockit has no calendar and can't reserve qa-int for next Tuesday. Keep planned windows on your release calendar and lock the environment when the window starts. Lockit also doesn't deploy, reset or provision environments.

The free plan covers two resources with unlimited locks and members, enough to trial it on your two most contested environments. Starter is $17/month for up to 100 resources and adds the API and MCP server. See pricing.

Signs your scheduling is working

You don't need a dashboard to tell. Watch for these:

  • Nobody asks "is anyone on qa-1?" in the channel. They check the list.
  • Regression runs stop failing because of surprise deploys.
  • Takeover requests are rare and get answered quickly.
  • Locks end close to when people actually finish, not at the default.

If people are regularly waiting more than an hour for an environment, the problem is capacity, not scheduling. That's the point to add an environment or move some testing to ephemeral preview environments that are created per pull request.

FAQ

Should each team get its own QA environment?

If budget allows and teams rarely integrate, yes. You'll still need at least one shared integration environment where everything runs at release-candidate versions, and that one needs scheduling.

How long should a default QA lock be?

Long enough for a typical session, short enough that a forgotten lock doesn't block a full day. Two hours is a sensible starting point for feature testing. Long-running suites should state their duration when locking.

Can Lockit reserve an environment for a future date?

No. Lockit locks start when they're taken. Use a calendar for planned windows and lock the environment when the window begins.

How do we stop pipelines deploying over manual testing?

Have the pipeline take the same lock people use before it deploys, and fail or wait if the environment is held. CI-only concurrency controls don't know about humans.

Stop asking who's on staging.

Add Lockit to Slack in a minute. Free for your first 2 resources.