Zero-Wait PR Previews: The Pre-Configured Slots Pattern

Ever waited for PR preview environments to spin up? Yeah, me too. Here’s a pattern that changed the game for our team: pre-configured deployment slots with deterministic routing.

The Problem

Traditional PR preview workflows go something lik…


This content originally appeared on DEV Community and was authored by Konstantin Tarkus

Ever waited for PR preview environments to spin up? Yeah, me too. Here's a pattern that changed the game for our team: pre-configured deployment slots with deterministic routing.

The Problem

Traditional PR preview workflows go something like this:

  1. Open PR
  2. CI/CD provisions a new environment
  3. Wait... ⏳
  4. Deploy code
  5. Wait some more... ⏳
  6. Finally get your preview URL

The provisioning step is the killer. Whether you're using Kubernetes namespaces, cloud functions, or edge workers, creating resources takes time.

The Solution: Pre-Configured Slots

What if we flipped the script? Instead of creating environments on-demand, we pre-configure a fixed set of deployment slots:

tokyo    🔗 https://tokyo.example.com
paris    🔗 https://paris.example.com
london   🔗 https://london.example.com
berlin   🔗 https://berlin.example.com
sydney   🔗 https://sydney.example.com
madrid   🔗 https://madrid.example.com
moscow   🔗 https://moscow.example.com
cairo    🔗 https://cairo.example.com
dubai    🔗 https://dubai.example.com
rome     🔗 https://rome.example.com

Then use a deterministic hash to map PR numbers to slots:

- uses: koistya/pr-codename@v1
  id: pr

- run: wrangler deploy --env ${{ steps.pr.outputs.codename }}

PR #1234 always maps to tokyo. PR #1235 always maps to paris. No provisioning, no waiting.

How It Works

The magic happens in three parts:

1. Pre-Configure Your Slots

First, set up your deployment slots. Here's a Cloudflare Workers example:

# wrangler.toml
[env.tokyo]
name = "preview-tokyo"
route = "tokyo.example.com/*"

[env.paris]
name = "preview-paris"
route = "paris.example.com/*"

[env.london]
name = "preview-london"
route = "london.example.com/*"

# ... repeat for all slots

2. Deterministic Mapping

The PR Codename Action uses a simple hash function to consistently map PR numbers to slot names:

const words = ['tokyo', 'paris', 'london', 'berlin', /* ... */];
const index = prNumber % words.length;
return words[index];

The above is just an example, in reality it uses FNV-1a hashing algorithm.

3. Deploy to the Slot

Your GitHub Action workflow becomes dead simple:

name: Deploy PR Preview

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: koistya/pr-codename@v1
        id: pr

      - name: Deploy to slot
        run: |
          npm ci
          npm run build
          wrangler deploy --env ${{ steps.pr.outputs.codename }}

      - name: Comment PR
        uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: '🚀 Preview deployed to https://${{ steps.pr.outputs.codename }}.example.com'
            })

The Benefits

This pattern isn't just a neat trick; it fundamentally changes the rhythm of your development cycle.

🚀 Zero-Wait Deploys
The biggest win. By eliminating the on-demand provisioning step, deployments start immediately. What used to be a 2-3 minute coffee break is now a 30-second task. Your developers stay in the flow, and your pipeline gets a whole lot faster.

🔗 URLs You Can Actually Share
Forget long, ugly, auto-generated URLs. With this pattern, PR #1234 always maps to https://tokyo.example.com. This URL is:

  • Memorable: You can actually remember it.
  • Shareable: Perfect for dropping in a Slack channel, a Jira ticket, or even saying out loud during a Zoom call. No more "Hey, can you find that preview link for me?"
  • Bookmarkable: QA testers and product managers can bookmark slots for features they're tracking.

💰 No More Cloud Bill Surprises
Dynamic environments are notorious for leaving behind orphaned resources that quietly drain your budget. With a fixed number of slots, your infrastructure costs become predictable. You know exactly what's running, and you never have to hunt down forgotten preview apps again.

🧹 Cleanup? What Cleanup?
When a PR is merged or closed, there's no complex teardown script to run. The slot simply becomes available for the next PR. You can even have a workflow that automatically deploys the main branch to the slot to keep it fresh. It's a self-cleaning system.

Real-World Considerations

How Many Slots?

We've found 10-15 slots work well for most teams. The math:

  • 10 slots + 50 open PRs = each slot serves ~5 PRs
  • Only the latest deployment to each slot is accessible
  • Most teams only actively review a handful of PRs at once

Collision Handling

Yes, PRs can map to the same slot. PR #1 and PR #11 both map to the same environment with 10 slots. In practice, this rarely matters because:

  1. Developers typically work on recent PRs
  2. Old PR previews naturally expire
  3. You can always trigger a redeploy to refresh

Security Notes

  • Use environment-specific secrets for each slot
  • Consider adding basic auth to preview domains
  • Implement automatic cleanup for stale deployments

Beyond Basic Previews

This pattern unlocks some cool possibilities:

Persistent Test Environments: QA can bookmark specific slots for testing.

A/B Testing: Map feature flags to slots for instant switching.

Geographic Testing: Actually deploy slots to different regions.

Try It Yourself

Getting started is pretty straightforward:

  1. Install the action:
   - uses: koistya/pr-codename@v1
     id: pr
  1. Use the codename in your deploy:
   deploy --env ${{ steps.pr.outputs.codename }}
  1. Enjoy instant PR previews 🚀

The full source is on GitHub if you want to customize the word list or hashing algorithm.

Wrapping Up

Sometimes the best optimization is avoiding work altogether. By pre-configuring deployment slots and using deterministic routing, we eliminated the biggest bottleneck in our PR workflow.

Give it a shot and let me know how it works for your team. Happy deploying!

What patterns have you used for PR previews? Drop a comment below 👇 always curious to hear different approaches!


This content originally appeared on DEV Community and was authored by Konstantin Tarkus


Print Share Comment Cite Upload Translate Updates
APA

Konstantin Tarkus | Sciencx (2025-07-25T11:46:25+00:00) Zero-Wait PR Previews: The Pre-Configured Slots Pattern. Retrieved from https://www.scien.cx/2025/07/25/zero-wait-pr-previews-the-pre-configured-slots-pattern/

MLA
" » Zero-Wait PR Previews: The Pre-Configured Slots Pattern." Konstantin Tarkus | Sciencx - Friday July 25, 2025, https://www.scien.cx/2025/07/25/zero-wait-pr-previews-the-pre-configured-slots-pattern/
HARVARD
Konstantin Tarkus | Sciencx Friday July 25, 2025 » Zero-Wait PR Previews: The Pre-Configured Slots Pattern., viewed ,<https://www.scien.cx/2025/07/25/zero-wait-pr-previews-the-pre-configured-slots-pattern/>
VANCOUVER
Konstantin Tarkus | Sciencx - » Zero-Wait PR Previews: The Pre-Configured Slots Pattern. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/07/25/zero-wait-pr-previews-the-pre-configured-slots-pattern/
CHICAGO
" » Zero-Wait PR Previews: The Pre-Configured Slots Pattern." Konstantin Tarkus | Sciencx - Accessed . https://www.scien.cx/2025/07/25/zero-wait-pr-previews-the-pre-configured-slots-pattern/
IEEE
" » Zero-Wait PR Previews: The Pre-Configured Slots Pattern." Konstantin Tarkus | Sciencx [Online]. Available: https://www.scien.cx/2025/07/25/zero-wait-pr-previews-the-pre-configured-slots-pattern/. [Accessed: ]
rf:citation
» Zero-Wait PR Previews: The Pre-Configured Slots Pattern | Konstantin Tarkus | Sciencx | https://www.scien.cx/2025/07/25/zero-wait-pr-previews-the-pre-configured-slots-pattern/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.