How-To8 min read

Shift-right testing: how to test safely in production

By qtrl Team · Engineering

Every team already tests in production. The difference is whether anyone planned it. The unplanned version is called a customer support ticket, and it has a worse feedback loop than almost any alternative.

Shift-right testing means doing it deliberately: running checks against the live system, on purpose, with controls. It doesn't replace pre-release testing. It covers the things pre-release testing structurally can't, which is a bigger set than most teams assume.

What only production can tell you

Start with the data. Fifteen years of records, every migration artifact, every user who found a way to enter something nobody anticipated. Synthetic data approximates the shape. It doesn't reproduce the specific record from 2019 that breaks your new report.

The infrastructure is the next one: the actual load balancer, the actual CDN, the actual network between your services. Even a well-maintained staging environment differs, and the differences accumulate. Third parties are worse, because the substitutes are deliberately unrealistic. Sandbox payment processors always approve. Sandbox email services swallow everything. The failure modes of the real ones are exactly what you need to handle and exactly what you can't rehearse before release.

And then there's how people actually use the feature, which is reliably different from how you expected, and which should be shaping your test priorities more than it does.

Two halves, and neither covers the other's groundreleaseBefore: what you can predictcheaper to fix, hereUnit and contract testsEnd-to-end on known journeysRegressions you have already seenSpecified behaviorAccessibility and performance gatesA predictable bug reaching productionis a gap on this sideAfter: what you can'tthe only place it existsSynthetic monitoring on key journeysFeature flags, failure criteria set firstCanary compared against the old versionChaos experiments, once you can observeReal data, real third parties, real loadEmergent failures: two features nobodyconnected, a shape nobody imaginedEvery team already tests in production. The difference is whether anyone planned it.Observability is the precondition. An alert nobody can action gets muted.

Synthetic monitoring, the obvious starting point

Run your critical user journeys against production continuously. Sign up, log in, search, add to cart, check out. Every few minutes, from a few regions, alerting when a step breaks.

This is the highest-value shift-right practice and the one most teams skip, usually because it feels like duplicating the E2E suite. It isn't. Your E2E suite tells you the code worked when it merged. Synthetic monitoring tells you the system is working right now, including when nothing was deployed and a certificate expired or a dependency started returning 503s.

Use dedicated test accounts, flag their traffic so it doesn't pollute analytics, and keep write actions to journeys you can clean up. For destructive steps, stop short and assert the confirmation screen rather than completing the action.

Feature flags as a testing mechanism

Flags are usually framed as a release tool. They're also the cleanest way to test in production with a bounded blast radius.

Ship the code dark, enable it for your own team, then a small percentage of real users, watching error rates and the business metric the feature is meant to move. If something breaks, the fix is a config change rather than a rollback, which is the difference between a five-minute incident and an hour one.

The discipline that makes this work: decide the failure criteria before you turn the flag on. Error rate above X, latency above Y, conversion below Z, and any of them means off. Deciding in the moment, while looking at a graph and hoping, is how a bad rollout gets extended into a bad afternoon.

Canary releases and what to watch

Route a small share of traffic to the new version and compare it against the old one on the same metrics at the same time. The comparison is what makes it work, since absolute numbers move for reasons unrelated to your release.

Watch error rate, latency percentiles rather than averages, and at least one business metric. That last one catches the category nothing else does: the deploy where every technical indicator is healthy and orders dropped 8% because a button moved somewhere nobody looks.

Chaos experiments, when you're ready

Deliberately break things to check that your resilience claims are true. Kill an instance, add latency to a dependency, drop a percentage of requests.

Prerequisites matter here. Do this only if you have solid monitoring, a practiced rollback, and an on-call process that works. Chaos engineering on a system you can't observe is just an outage with extra steps. Start in staging to validate the tooling, then move to production during business hours with the team watching.

Observability is the precondition

All of this depends on being able to see what happened. If a synthetic check fails and you can't trace the request, you've learned that something is broken and nothing about what.

Distributed tracing, structured logs with a correlation ID, and metrics on the business outcomes rather than only the technical ones. Teams that add shift-right practices without that groundwork get alerts they can't action, and alerts nobody can action get muted.

Where the line is

Shift-right is not permission to skip pre-release testing, and the teams that read it that way end up with users as their regression suite.

The sensible division: pre-release testing catches what you can predict. Production testing catches what you can't. Anything you knew to look for should have been caught before release, and finding a predictable bug in production means your pre-release coverage has a gap, not that shift-right is working.

The failures worth catching in production are the emergent ones. The interaction between two features nobody connected. The data shape nobody imagined. The third-party timeout that only happens on Black Friday. Those were never going to show up in a pre-release strategy, however well constructed, and having a deliberate way to catch them is the whole point.


qtrl runs test cases in real browsers against whichever environment you target, with boundaries on what each run is allowed to do. That's what makes the read-only subset of your coverage safe to run continuously against production rather than only against staging.

Results are recorded per environment, so a case that passes in staging and fails in production shows up as a specific, traceable difference with the evidence attached. See how it works.

Have more questions about AI testing and QA? Check out our FAQ