Back to Blog

Ephemeral Testing Environments: Save Money on QA Infrastructure

August 3, 2024
9 min read

Stop paying for idle QA environments. With ephemeral environments, you create testing infrastructure on-demand that automatically disappears when done. Here's how to cut your testing costs by 70% or more.

The Hidden Cost of Static QA Environments

Traditional Setup:

  • • 5 QA environments running 24/7
  • • Used only 20% of the time
  • • $2,000/month in wasted resources
  • • Constant conflicts between teams

Ephemeral Setup:

  • • Environments created on-demand
  • • Auto-deleted after 2 hours
  • • $400/month total cost
  • • Unlimited parallel testing

Step 1: Automatic PR Environments

Create a new environment for every pull request automatically:

# GitHub Actions workflow
name: Deploy PR Environment

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    
    - name: Generate environment name
      run: echo "ENV_NAME=pr-${{ github.event.pull_request.number }}" >> $GITHUB_ENV
    
    - name: Create namespace
      run: |
        kubectl create namespace $ENV_NAME --dry-run=client -o yaml | kubectl apply -f -
        
    - name: Deploy application
      run: |
        helm upgrade --install $ENV_NAME ./charts/myapp \
          --namespace $ENV_NAME \
          --set image.tag=pr-${{ github.event.pull_request.number }} \
          --set ingress.host=$ENV_NAME.test.company.com \
          --wait
          
    - name: Comment PR with environment URL
      uses: actions/github-script@v6
      with:
        script: |
          github.rest.issues.createComment({
            issue_number: context.issue.number,
            owner: context.repo.owner,
            repo: context.repo.repo,
            body: '🚀 Environment deployed: https://${{ env.ENV_NAME }}.test.company.com'
          })

Step 2: Implement Resource Limits

Prevent runaway costs by setting strict resource limits:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: ephemeral-quota
  namespace: pr-123
spec:
  hard:
    requests.cpu: "2"
    requests.memory: "4Gi"
    limits.cpu: "4"
    limits.memory: "8Gi"
    persistentvolumeclaims: "2"
    
---
apiVersion: v1
kind: LimitRange
metadata:
  name: ephemeral-limits
  namespace: pr-123
spec:
  limits:
  - default:
      cpu: "500m"
      memory: "1Gi"
    defaultRequest:
      cpu: "100m"
      memory: "128Mi"
    type: Container

💡 Pro Tip: Use 1/4 of production resources for ephemeral environments. Most testing doesn't need full production capacity.

Step 3: Configure Auto-Deletion

Automatically clean up environments to prevent cost creep:

# CronJob to clean up old environments
apiVersion: batch/v1
kind: CronJob
metadata:
  name: cleanup-ephemeral-envs
  namespace: default
spec:
  schedule: "*/30 * * * *"  # Every 30 minutes
  jobTemplate:
    spec:
      template:
        spec:
          serviceAccountName: cleanup-sa
          containers:
          - name: cleanup
            image: bitnami/kubectl:latest
            command:
            - /bin/bash
            - -c
            - |
              # Delete namespaces older than 2 hours
              for ns in $(kubectl get ns -l environment=ephemeral -o name); do
                namespace=$(echo $ns | cut -d/ -f2)
                created=$(kubectl get $ns -o jsonpath='{.metadata.creationTimestamp}')
                age=$(($(date +%s) - $(date -d "$created" +%s)))
                
                if [ $age -gt 7200 ]; then
                  echo "Deleting $namespace (age: $age seconds)"
                  kubectl delete namespace $namespace
                fi
              done
          restartPolicy: OnFailure

Cleanup on PR Events

# Delete environment when PR is closed
on:
  pull_request:
    types: [closed]

jobs:
  cleanup:
    runs-on: ubuntu-latest
    steps:
    - name: Delete environment
      run: |
        kubectl delete namespace pr-${{ github.event.pull_request.number }} \
          --ignore-not-found=true

Real Cost Comparison

Static QA Environments (5 environments, m5.large instances)

$1,840/month

5 × $0.096/hour × 24 hours × 30 days

Ephemeral Environments (avg 10 concurrent, spot instances)

$288/month

10 × $0.030/hour × 4 hours/day × 24 days

84% Cost Reduction

Plus unlimited scaling during peak times

Expected Results

✓ 70-90% Cost Reduction

Pay only for what you use

✓ Unlimited Parallel Testing

No more waiting for environments

✓ Faster Development

Test every PR independently

✓ Zero Conflicts

Each PR gets its own environment

Ready to slash your QA costs?

KTL.AI makes ephemeral environments simple. Automatic PR deployments, spot instance management, and intelligent cleanup policies included. Cut your testing costs by 70% or more.