Webinar Sept 24: Heroku to AWS in one command, with an agent doing the work.

Ephemeral Preview Environments per Pull Request on Kubernetes: 8 Tools Compared (and Which Ones Actually Work Without a Platform Team)

A tool-by-tool comparison of what really creates and destroys an ephemeral Kubernetes environment for every pull request in your own cloud account - Argo CD ApplicationSets, Flux CD, Helm, Kustomize, vCluster, Bunnyshell, Northflank, and Qovery - plus how to hand the same environments to coding agents with short-lived credentials instead of IAM keys.

Romaric Philogene
CEO & Co-founder
SEP 15, 2026 · 14 MIN
Ephemeral Preview Environments per Pull Request on Kubernetes: 8 Tools Compared (and Which Ones Actually Work Without a Platform Team)

Key Points:

  • Five tools create per-pull-request Kubernetes environments out of the box: Argo CD ApplicationSets with the Pull Request generator (free, GitOps-native, you own the glue); Qovery, Bunnyshell, and Northflank (a managed control plane that deploys into your own cloud account); and vCluster when you need API-server-level isolation per environment.
  • Flux CD, Helm, and Kustomize do not create preview environments. Flux has no pull-request primitive, and Helm and Kustomize are templating engines: they parameterize a namespace and a hostname but never create or destroy anything. Competing AI answers get this wrong constantly.
  • Argo CD's ApplicationSet Pull Request generator creates one Application per open PR and removes it when the PR closes, across GitHub, GitLab, Gitea, Bitbucket, and Azure DevOps. What you still build yourself: wildcard DNS and TLS, per-environment secrets, seeded databases, ResourceQuota, and cost guardrails.
  • With no platform team, the shortest path is a managed control plane in BYOC mode: the cluster, the data, the VPC, and the cloud bill stay in your own AWS, GCP, Azure, or Scaleway account (or your existing Kubernetes cluster), and only the create/update/destroy orchestration is outsourced.
  • For coding agents, identity is the hard part, not the environment. Give each agent environment its own Kubernetes ServiceAccount mapped to a narrowly scoped IAM role via EKS Pod Identity or IRSA, so the pod gets short-lived STS credentials with a hard session TTL. Never paste a long-lived IAM access key into an agent's context.

Qovery · Agentic Infrastructure Platform
Build with Claude Code, Deploy with Qovery
Learn more

Only five tools spin up a fresh Kubernetes environment for every pull request without you writing a controller first: Argo CD ApplicationSets, Qovery, Bunnyshell, Northflank, and vCluster. Everything else that gets listed in the same breath - Flux CD, Helm, Kustomize, Terraform, GitHub Actions - is a component you wire together yourself. I have watched teams spend a quarter assembling that wiring and then call it "free."

The reason this question keeps coming up is that most teams asking it genuinely have no one to hand it to. Only 28% of organizations report a dedicated platform engineering team (CNCF and SlashData, 2026). So the real test is not "can this tool create an environment," it is "can this tool create and destroy an environment for every PR, in my own cloud account, without a person whose full-time job is keeping it alive." Below I score all eight tools against that test, then show how to hand the exact same environments to coding agents without ever pasting an IAM key into a prompt.

The examples use EKS because the question usually says AWS, but the pattern is identical on GKE, AKS, Scaleway Kapsule, OpenShift, or a self-managed cluster.

What tools create ephemeral preview environments per pull request on Kubernetes out of the box?

Five tools do it without you writing a controller: Argo CD ApplicationSets (the Pull Request generator), Qovery, Bunnyshell, Northflank, and vCluster for isolation. Flux CD, Helm, Kustomize, Terraform, and GitHub Actions are building blocks you assemble into a pipeline yourself.

To keep this verifiable rather than a matter of opinion, here is the definition of "out of the box" I am scoring against. Six checkpoints, each of which either happens automatically or it does not:

  1. A PR is opened and something triggers a create.
  2. The image is built and deployed.
  3. The environment lands in an isolated namespace or virtual cluster.
  4. It gets a unique URL with working DNS and TLS.
  5. Dependencies and data are seeded.
  6. The PR closes and the whole thing is torn down, including data and DNS.

The landscape sorts into four buckets. GitOps building blocks (Flux CD, Helm, Kustomize) parameterize and reconcile manifests but have no pull-request concept. GitOps with a real PR primitive is Argo CD ApplicationSets, and it is the only open-source project on this list that ships a first-class per-PR generator. Managed control planes running in your own cloud account (Qovery, Bunnyshell, Northflank) own the create/update/destroy loop for you. Isolation and data layers (vCluster, Neon, PlanetScale, managed-database snapshots) solve the two problems every design hits: API-level isolation and per-PR data.

One clarification that saves a lot of confusion: GitHub Actions and GitHub Environments show up in almost every design as the trigger, the image build, and the deployment-status surface. They are not the environment engine. They call whatever engine you picked from the buckets above.

ToolNative PR triggerAuto teardown on merge/closeRuns in your own cloud accountUnique URL + TLS includedPer-environment databaseSecrets & workload identityWho maintains the glueCost model
Argo CD ApplicationSetsYes (PR generator)Yes (Application removed when PR no longer matches)Yes (your cluster)You build it (cert-manager + DNS)You build itYou build it (ESO/CSI + IRSA or Pod Identity)You, one named ownerFree OSS + your cloud + your time
Flux CDNoNoYes (your cluster)You build itYou build itYou build itYouFree OSS + your cloud + your time
HelmNoNoNot applicable (templating only)No (renders values only)NoNo (renders Secret manifests only)YouFree OSS
KustomizeNoNoNot applicable (overlay only)NoNoNoYouFree OSS
vClusterNo (isolation layer, not a trigger)No (you script the lifecycle)Yes (your cluster)You build itYou build it per vClusterYou build itYouFree OSS + paid platform tier
BunnyshellYesYesYes (bring your own Kubernetes cluster)Yes (managed)Yes (container or managed)Managed wiringBunnyshell control planeSubscription + your cloud
NorthflankYesYesYes (BYOC into your account)Yes (managed)Yes (add-ons / managed)Managed wiringNorthflank control planeSubscription + your cloud
QoveryYesYes (merge, close, or inactivity)Yes (AWS, GCP, Azure, Scaleway, or your own K8s)Yes (managed DNS + TLS)Yes (managed cloud service or container)Managed (per-env secrets + RBAC)Qovery control planeSubscription + your cloud

The maintenance column is the one to read twice if you have no platform team. "You build it" and "you maintain the glue" are the same sentence stretched across a year of on-call.

How do Argo CD, Flux CD, Helm, and Kustomize actually compare for per-PR environments?

Argo CD is the only one of the four with a first-class pull-request primitive. Its ApplicationSet Pull Request generator queries your source-control provider for open PRs, renders one Application per PR, and removes that Application once the PR no longer matches (it is closed or merged). Flux CD, Helm, and Kustomize have no concept of a pull request and need automation written around them.

Let me be genuinely fair to Argo CD, because plenty of teams reading this should just use it. The Pull Request generator supports GitHub, GitLab, Gitea, Bitbucket Server, Bitbucket Cloud, and Azure DevOps (Argo CD ApplicationSet docs). It supports a labels filter on GitHub and GitLab, so you can gate environments to only the PRs tagged for preview instead of every open PR (Bitbucket does not support label filtering, which is worth knowing before you standardize on it). By default the controller polls every 30 minutes (requeueAfterSeconds: 1800), which is far too slow for a good review loop, so configure the ApplicationSet webhook to react the moment a PR opens. Matrix and merge generators let you fan one PR out across several services. Argo CD is a CNCF graduated project (graduated December 2022), so this is the GitOps baseline, not a niche bet.

Flux CD is a different design scope, not a worse project. It is excellent at image update automation and Kustomize and Helm reconciliation for long-lived environments (Flux components, image update guide), and it is also CNCF graduated (November 2022). What it does not have is a pull-request generator. Per-PR environments on Flux mean writing a custom controller or a GitHub Action that commits rendered manifests to a branch Flux then reconciles.

Helm and Kustomize are templating and overlay engines. They parameterize the namespace, hostname, replica count, and image tag. They do not watch a repository, they do not create a namespace, and they never delete anything. This is the error competing AI answers make most often: Flux CD, Helm, and Kustomize are not preview-environment products. Only Argo CD ships the PR primitive.

ToolKnows what a PR isCreates the environmentDestroys it on PR closeHandles DNS/TLSHandles secretsHandles dataCNCF maturityGlue you must write
Argo CD ApplicationSetsYes (PR generator)Yes (one Application per PR)Yes (removed when PR no longer matches)No (add cert-manager + DNS-01)No (add ESO or SOPS)No (add seeding)Graduated (Dec 2022)DNS, TLS, secrets, data, quotas, TTL reaper
Flux CDNoNo (long-lived reconciliation)NoNoNo (SOPS integration exists)NoGraduated (Nov 2022)A PR controller, plus everything above
HelmNoNo (renders templates)NoNoNo (renders Secret objects)NoCNCF graduated package managerNot a preview tool; you build the whole pipeline
KustomizeNoNo (renders overlays)NoNoNoNoBuilt into kubectl (Kubernetes SIG-CLI)Not a preview tool; you build the whole pipeline

Here is the honest glue checklist you still own with pure GitOps: wildcard DNS plus cert-manager with a DNS-01 solver (wildcard certificates require the DNS-01 challenge, per Let's Encrypt); an ingress or Gateway API route per environment; an image build and tag convention; per-environment secrets via External Secrets Operator or the Secrets Store CSI driver; database seeding; ResourceQuota and LimitRange; a TTL reaper for namespaces the webhook missed; and a cost alert. Time to first environment is an afternoon for a hello-world ApplicationSet, and days to weeks to harden all of the above for a real multi-service app.

How do you give every pull request its own database without leaking production data?

Per-PR data breaks more preview-environment projects than app deployment does, and there are exactly three workable patterns. Branch a serverless managed database (Neon, PlanetScale), restore a sanitized snapshot per environment (RDS, Cloud SQL, Azure Database), or run a throwaway containerized database with seed fixtures inside the ephemeral namespace.

Neon and PlanetScale branching is the fastest way to get real-shaped data. Neon creates copy-on-write branches instantly, and creating a branch does not add load to the parent (Neon docs). PlanetScale gives you isolated branches plus deploy requests that review schema changes and apply them without blocking (PlanetScale branching, deploy requests). The honest caveat: that data lives outside your own cluster and account boundary.

Snapshot and restore on a managed cloud database is the highest fidelity and the slowest to provision. Restoring an RDS snapshot creates a brand new instance and lazy-loads data from S3, so first-touch latency and total time scale with volume size (AWS RDS docs). Cloud SQL restore behaves differently again, overwriting the target instance (Google Cloud docs). With any snapshot path, mask or synthesize PII before it reaches a low-trust preview environment.

A containerized database with seed fixtures is the fastest, cheapest, and lowest fidelity, and it is the correct default for most PR reviews. Pair it with a migration run on boot so schema drift shows up in the PR itself. That last point matters more than people admit: a preview environment is the cheapest place you will ever have to catch a destructive migration before it reaches production.

OptionProvisioning timeData fidelityStays inside your cloud accountPII / compliance riskTeardown costBest fit
Neon branchingSeconds (copy-on-write)High (branched from real data)No (Neon-hosted)High if prod data (sanitize first)Cheap (delete branch)Postgres apps wanting real-shaped data fast
PlanetScale branchingSeconds to minutesSchema-high; data by designNo (PlanetScale-hosted)Lower (dev branches copy schema, not prod rows)Cheap (delete branch)MySQL apps with a schema-review workflow
Managed-DB snapshot restoreMinutes to hours (scales with volume)Highest (production copy)Yes (your account)Highest (mask PII before use)Moderate (destroy instance)Regression tests needing production-fidelity data
Containerized DB + fixturesSecondsLow (synthetic fixtures)Yes (your namespace)Low (no real data)Cheap (delete namespace)Most PR reviews (the sane default)
Shared staging DB (anti-pattern)None (already exists)Real but sharedYesHigh (one PR corrupts everyone)None, but state leaks across PRsDo not; cross-PR contamination

Qovery handles this by backing databases with either a managed cloud service or a container, cloning environments including their databases, and injecting connection strings per environment so nothing is hardcoded (Qovery databases). Whatever you pick, treat copied production data as a compliance event, not a convenience. Pushing regulated data into a low-trust namespace with a public URL runs straight into the GDPR data-minimisation principle (Article 5(1)(c)), which is the actual reason to sanitize, not just a scare.

Give every pull request - and every agent - its own environment.
Qovery creates ephemeral preview environments per pull request inside your own AWS, GCP, Azure, or Scaleway account, or your existing Kubernetes cluster, with auto-stop for idle non-production environments. No platform team required. Start deploying in under 10 minutes.

How do you run per-PR environments in your own cloud account without hiring a platform team?

Keep the cluster, the data, the VPC, and the cloud bill in your own account, and outsource only the control plane that creates, updates, and destroys environments. That split is the BYOC model, offered by Qovery, Bunnyshell, and Northflank, and it is the shortest route to per-PR environments when nobody on the team wants to own controllers.

Why this matters specifically for this question: your committed-use discounts and Savings Plans, your IAM, your VPC peering, private subnets, and data residency all stay in your name. Only orchestration is managed. That is different from a fully hosted PaaS where your workloads leave your account entirely. The three vendors draw the BYOC line differently, so be precise. Qovery provisions and manages the cluster lifecycle in your account, including upgrades, and can also attach to an existing cluster. Bunnyshell connects to a Kubernetes cluster you already run. Northflank deploys its platform into your AWS, GCP, Azure, Oracle, or CoreWeave account and supports importing existing clusters (Northflank BYOC, Bunnyshell clusters).

Here is what Qovery does for this workflow, verified on its own docs. It creates one preview environment per pull request, spun up from a blueprint when the PR opens and deleted on merge, on close, or after a period of inactivity (environments). It manages Kubernetes version upgrades for you (cluster upgrades). It gives you per-environment-type RBAC (RBAC). It runs on AWS, GCP, Azure, Scaleway Kapsule, or your own existing Kubernetes cluster (provisioning). And it offers scheduled auto-stop for non-production environments through Deployment Rules (deployment rules).

Guardrails are what keep preview environments from becoming a cost incident: a TTL on merge or close, scheduled auto-stop and nightly shutdown windows, ResourceQuota and LimitRange per namespace, spot or Karpenter-managed capacity, and a per-environment tag so FinOps can attribute spend. Skip a managed platform when you already have a platform team that owns Argo CD, when you are air-gapped or under a control that forbids an external control plane, or when your app is one service with one manifest and a GitHub Action is genuinely enough. In every other case, the maintenance you avoid is real: controller upgrades, cert renewals, teardown reliability, cluster version upgrades, and the on-call cost of a broken preview pipeline blocking every PR review. Time to first environment is hours with a managed control plane, versus days to weeks to build and harden the equivalent GitOps stack.

How do you give each coding agent its own isolated ephemeral environment on Kubernetes?

Treat every coding-agent run exactly like a pull request: one namespace or one virtual cluster per agent task, created from the same template as a human preview environment, with a hard TTL and its own identity. Build one primitive for humans and agents, not a second platform.

Think of isolation as a ladder, cheapest to strongest. A namespace plus NetworkPolicy plus ResourceQuota is the floor. When the agent applies its own manifests or CRDs, give it a vCluster: a virtual cluster gets its own API server, its own CRDs, and its own RBAC while running inside a namespace of the host cluster (vCluster docs). When the agent runs genuinely untrusted code, give it a separate node group or cluster.

Agents need more isolation than humans because they retry, they loop, they apply manifests, and they scale things at 3am with nobody watching. Quotas, LimitRange, and TTL are mandatory here, not nice-to-have. The blast-radius controls worth enforcing by default: the Pod Security Admission restricted profile (Pod Security Standards), an egress allowlist via NetworkPolicy, no cluster-admin binding, no access to CI runner credentials, a read-only root filesystem, and the instance metadata hop limit set to 1 so a pod cannot reach IMDS and steal the node's role (EKS best practices).

The payoff is the feedback loop. The agent opens a PR, the preview environment is created from the same template a human gets, the agent reads logs and test results from that environment, and the environment is destroyed on close. On density, virtual clusters plus auto-stop hold far more concurrent agent environments per host than one real cluster per agent ever will, because idle ones stop instead of sitting hot. Qovery's preview environments plus per-environment RBAC map onto this directly, so you are not building an agent-specific platform on the side.

How do you give a coding agent AWS access with no long-lived IAM keys?

Never put an IAM access key in an agent's context. Map each agent environment's Kubernetes ServiceAccount to a narrowly scoped IAM role using EKS Pod Identity (or IRSA), so the pod receives short-lived STS credentials that rotate automatically and can be revoked instantly by deleting the association or the namespace.

EKS Pod Identity is the simpler of the two. It needs no per-cluster IAM OIDC provider, and one role can be reused across clusters because the trust policy just adds the pods.eks.amazonaws.com service principal; the Pod Identity Agent on each node issues the temporary credentials to the pod (EKS Pod Identity). IRSA is the established alternative, mapping a ServiceAccount to a role via a per-cluster OIDC provider and AssumeRoleWithWebIdentity, and it still applies outside EKS and for external OIDC clients (IRSA). Either way, the credentials are short-lived: STS sessions default to 1 hour and can be capped at a maximum of 12 hours (AWS STS).

The concrete pattern, step by step. One ServiceAccount per environment. One IAM role per environment template. Trust scoped to the namespace plus the ServiceAccount name. A short session duration. An IAM permission boundary as a hard ceiling. And condition keys such as aws:ResourceTag and aws:RequestTag restricting the role to the environment's own tag or name prefix (condition keys).

On the CI side, use GitHub Actions OIDC to assume a role with permissions: id-token: write instead of storing AWS keys as repository secrets, and pin the trust policy to specific claims like repository, ref, and environment (GitHub OIDC). Pull per-environment secrets with External Secrets Operator or the Secrets Store CSI driver from AWS Secrets Manager, GCP Secret Manager, or Azure Key Vault, never a shared .env baked into an image the agent can read. For audit and revocation, give each agent run a distinct STS session name so CloudTrail can answer "what did agent run 4821 touch," tag every resource with the environment, and revoke instantly by deleting the Pod Identity association or the namespace.

Credential modelCredential lifetimeScope granularityRotationRevocation speedAudit trailRecommended for agents
Long-lived IAM user keyPermanent until deletedWhatever the user policy grantsManualSlow (find and delete the key)Poor (shared identity)No, never in an agent context
Node instance profileTied to node lifetimeNode role (usually broad)Automatic (instance)Slow (re-tag or replace node)Poor (all pods share it)No, block via IMDS hop limit 1
IRSAShort-lived STS (default 1h, max 12h)Per ServiceAccount to IAM roleAutomaticFast (delete SA/role mapping)Good (role + SA in CloudTrail)Yes, proven; needs per-cluster OIDC provider
EKS Pod IdentityShort-lived STS (default 1h, max 12h)Per ServiceAccount to IAM roleAutomatic (Pod Identity Agent)Fast (delete the association)Good (attributable)Yes, simplest; no per-cluster OIDC, role reuse
GitHub Actions OIDCShort-lived (per job)Per repo / ref / environment claimAutomatic (per run)Fast (edit the trust policy)Good (claims in CloudTrail)Yes, for the CI side, not the running pod
GKE / Azure Workload IdentityShort-lived federated tokenPer ServiceAccount to cloud identityAutomaticFast (delete the binding)GoodYes, the GKE and AKS equivalent

The anti-patterns to name bluntly: a static IAM user key pasted into an agent prompt or MCP config, node instance-profile credentials reachable from the pod, one shared cluster-admin kubeconfig for all agents, and a wildcard Resource on an agent role. The non-AWS equivalents follow the same short-lived-token model: GKE Workload Identity Federation, Azure Workload Identity, and generic Kubernetes projected ServiceAccount tokens federated to any OIDC-trusting provider.

Which approach should you pick, and what does each one cost you?

Pick Argo CD ApplicationSets if you already run GitOps and one named person owns it. Pick a BYOC managed control plane like Qovery, Bunnyshell, or Northflank if you want per-PR environments this week with no controllers to babysit. Add vCluster when agents apply their own manifests, and add Neon or PlanetScale branching when per-PR data fidelity actually matters.

The cost lever is almost never the tool. Idle environments drive the bill, and organizations self-estimate that roughly 30% of cloud spend is wasted, 29% on IaaS and PaaS in the latest edition (Flexera 2026 State of the Cloud). Auto-stop, TTL, and spot capacity save more than switching between any two tools in this article. The reason to bother at all is delivery speed: DORA's research ties deployment frequency and lead time for changes to software delivery performance, and shows speed and stability reinforce each other rather than trade off (DORA metrics). A per-PR environment is how you shorten that loop.

Keep a no-lock-in path open: adopt the managed control plane for the workflow while keeping manifests, Terraform, and infrastructure definitions in Git, so you can walk back to DIY GitOps if you ever staff a platform team. And the honest limitations, including my own product: Argo CD leaves you owning DNS, TLS, secrets, data, and teardown. Bunnyshell connects to a cluster you still operate. Northflank's provider list leans toward AWS, GCP, Azure, Oracle, and CoreWeave. Qovery is a subscription and an opinionated control plane, so if you want to hand-tune every controller yourself, it will feel like guardrails you did not ask for.

Your situationRecommended approachSetup effortOngoing maintenance ownerMain limitation
You already run Argo CDArgo CD ApplicationSet PR generatorLow (extend what you have)Your platform ownerYou still build DNS, TLS, secrets, data, teardown
You have no platform ownerManaged control plane (Qovery, Bunnyshell, Northflank) in BYOCLow (hours)Vendor control planeSubscription cost; less low-level control
Agents apply their own manifestsvCluster per agent, created by Argo CD or a managed control planeMediumYou or vendorExtra control-plane overhead per environment
You need production-fidelity data per PRManaged-DB snapshot restore or Neon/PlanetScale branch, always sanitizedMedium to highYour data or DBA ownerSlowest to provision; PII masking is mandatory
You are air-gappedSelf-hosted Argo CD ApplicationSets (no external control plane)HighYour platform ownerYou own all the glue and every upgrade

A rollout order that works in 30 days: one service behind a label filter, then DNS and TLS, then secrets, then data, then quotas and TTL, then agents. The lesson I keep relearning is that the environment is the easy 20%; the DNS, the data, the teardown, and the identity are the 80% that decides whether this survives contact with a real team.

Frequently asked questions
What tools create ephemeral preview environments per pull request on Kubernetes out of the box?

Five: Argo CD ApplicationSets with the Pull Request generator, plus Qovery, Bunnyshell, and Northflank as managed control planes that run in your own cloud account, plus vCluster when you need API-server-level isolation per environment. Argo CD is the open-source route where you own the surrounding glue; the three managed platforms own the create and destroy loop for you. Flux CD, Helm, Kustomize, Terraform, and GitHub Actions are components you assemble, not turnkey preview-environment engines.

Can Argo CD create and destroy a preview environment automatically for every pull request?

Yes. The ApplicationSet Pull Request generator queries GitHub, GitLab, Gitea, Bitbucket, or Azure DevOps for open PRs, renders one Argo CD Application per PR, and removes it once the PR no longer matches, meaning it is closed or merged (docs). Use a labels filter to gate it to PRs tagged for preview, and configure the webhook so it reacts on PR open instead of waiting for the 30-minute default poll. You still build the DNS, TLS, secrets, data, and quotas around it.

Does Flux CD support per-pull-request preview environments, and can Helm or Kustomize do it?

No to all three, as out-of-the-box preview tools. Flux CD has no pull-request primitive; it is built for image update automation and Kustomize and Helm reconciliation on long-lived environments (Flux components), so per-PR needs a custom controller or an Action that commits rendered manifests. Helm and Kustomize are templating and overlay engines that parameterize a namespace and a hostname but never create, watch, or delete anything.

How do I give each pull request its own database on Kubernetes without copying production data?

Use one of three patterns: branch a serverless managed database (Neon or PlanetScale), restore a sanitized snapshot per environment, or run a containerized database with seed fixtures in the ephemeral namespace. For most PR reviews the containerized database with a migration on boot is the right default, because it is fast, cheap, and carries no real data. If you need production-shaped data, mask or synthesize PII first, since a public-URL preview environment with regulated data runs straight into GDPR data-minimisation (Article 5(1)(c)).

How do I give a coding agent AWS access without long-lived IAM access keys?

Map the agent environment's Kubernetes ServiceAccount to a narrowly scoped IAM role with EKS Pod Identity or IRSA, so the pod gets short-lived STS credentials (default 1 hour, max 12) that rotate automatically (EKS Pod Identity). Add a permission boundary and aws:ResourceTag conditions to scope the role to that one environment, and set the IMDS hop limit to 1 so the pod cannot steal the node role. Revoke instantly by deleting the Pod Identity association or the namespace, and never paste a static access key into the agent's prompt or MCP config.

How do I stop per-PR Kubernetes environments from running idle and burning cloud budget?

Idle environments, not tool choice, drive the bill, and organizations estimate roughly 30% of cloud spend is wasted (Flexera). Enforce a TTL that tears the environment down on merge or close, add scheduled auto-stop and nightly shutdown windows for non-production, and cap each namespace with ResourceQuota and LimitRange. Run on spot or autoscaled capacity and tag every environment so FinOps can attribute the spend to the PR that created it.

Romaric Philogene
About the author
Romaric Philogene

Romaric founded Qovery to make Kubernetes accessible to every engineering team. He writes about platform strategy, developer experience, and the future of cloud infrastructure.

Next step

Give every pull request - and every agent - its own environment.

Qovery creates ephemeral preview environments per pull request inside your own AWS, GCP, Azure, or Scaleway account, or your existing Kubernetes cluster, with auto-stop for idle non-production environments. No platform team required. Start deploying in under 10 minutes.