For some, a simple staging setup is enough. For others, adding more infrastructure can feel like overkill, introducing extra costs, complexity and operational overhead.
But pre-production is an environment worth serious consideration if your releases are high-stakes and your app handles complex, business-critical data.
This time, we’ll share how introducing a pre-production environment helped our team reduce bugs, boost confidence and bring business stakeholders into the quality loop, without slowing down our CI/CD process.
Imagine you're building an application for large enterprise clients. The app’s job is to analyze and optimize costs by performing thousands of calculations across real-time datasets. Detecting fractional savings at scale, sometimes down to $0.001, translates into better operating margins.
Every interaction in the app triggers complex logic: live recalculations, performance-sensitive updates and visual feedback in the form of charts and statistics.
Now, imagine a bug slipping through to production.
A calculation error could result in corrupted business data, incorrect recommendations, or even halted operations. Fixes must be swift and precise. But with continuous delivery in play, every deployment feels like a calculated risk.
One particularly frustrating issue is the data-dependent bug. Some calculations would fail, but only under specific, hard-to-replicate data conditions. These were nearly impossible to catch in generic test environments and data sets.
So, how do you release with near-100% confidence?
The answer, for us, was a dedicated pre-production environment.
The idea of how to deal with all problems was simple: let's introduce another test environment, but make it as similar as possible to the production environment. We copy anonymized production data and use the same or similar hardware. In general, it's a second production environment but is used internally.
User acceptance testing (UAT) is a crucial step in delivering software that meets real-world needs, but too often, it happens in environments that aren’t up to the task. Traditional test environments are usually unstable, underpowered, and filled with artificial data that doesn’t reflect objective business complexity.
That might be fine when developers and quality assurance work closely, catching and fixing bugs early. But it’s a bigger challenge when business stakeholders, who are further from the day-to-day development loop, test and validate functionality.
That’s where our pre-production environment made a difference. By introducing another stable, production-like environment, we could invite business users and stakeholders to test features in conditions that closely mirrored production. These were features already finalized and ready to merge.
Of course, our UAT setup isn’t by the book. It’s a variation of classic user acceptance testing, tailored to our process. Software development is full of compromises, and aiming for the best possible outcome is more important than perfection.
Still, when working with uncommon, complex, industry-specific business logic, every chance to involve business users in testing is a valuable opportunity.
One of the biggest advantages of a pre-production environment is the ability to work with anonymized copies of real production data.
This gives QA and business users the closest possible simulation of live conditions, making it easier to spot edge case issues that wouldn’t surface with generic test data.
Using realistic data allows us to:
Pre-production creates a safe space to surface issues that would otherwise remain hidden until it’s too late.
Pre-production creates a tight, cross-functional feedback loop. It acts as a final checkpoint where with faster feedback:
It improves quality, builds team trust, and shortens the time between code completion and stakeholder approval, without slowing down the CI/CD pipeline.
Before anything gets deployed to production, it must earn the "green light" in pre-production. This environment serves as a final gate, where features are tested under near-real conditions, UAT happens with full business context, and both QA and Product Owners approve releases.
Pre-production turns stakeholders into active contributors. Instead of observing from a distance, they share responsibility for quality and become more integrated with the development team. Their input becomes part of the release process, and their role in the software development life cycle becomes more meaningful and greatly appreciated.
Getting the green light means both the development team and the people who know the business best have truly tested the release.
Setting up a pre-production environment is about creating a space close enough to catch real issues without introducing unnecessary overhead or slowing down the team.
Here’s how we built one for our client.
Our release flow revolves around three main Git branches — staging, pre-production and main — each connected to a corresponding environment. As code moves through these stages, it’s automatically built, deployed and tested under increasingly production-like conditions.
This ensures that what gets merged into the main branch has already passed through realistic simulations and stakeholder review.
Our backend is fully containerized using Docker, providing consistency across all environments. We use a deployment platform that integrates with our Git repository, so:
This approach reduces drift between environments, automates deployment gates, and catches production-level issues before they go live.
The front end follows a similar model, with Git branches directly tied to multi-environment previews. Every commit or merge builds a deployment linked to a unique URL, allowing quick access for internal reviews or stakeholder testing.
We map branches like this:
Environment variables are managed independently, keeping each stage isolated and aligned with its intended purpose.
To ensure safe and realistic testing, each environment uses its identity tenant. That means having separate users, roles and login flows for each environment, without test users leaking into production or real credentials being used accidentally.
This setup also allows us to safely test features like multi-factor authentication, permission models, and custom auth flows without risk.
Each environment runs on its own isolated database instance. In the case of pre-production, that database is populated with anonymized snapshots of production data. This gives us a realistic data model that closely mirrors live usage, without risking sensitive customer information.
It’s a setup that lets us catch edge-case bugs more effectively, especially those that emerge only in specific, real-world data scenarios. Think of it as a high-fidelity simulation lab identical to production in behavior, but with no real-world consequences.
Our release pipeline is tightly connected to the environment architecture. Every code push triggers an automatic deployment, with each stage: staging, pre-production, and production, configured with its own secrets and environment-specific settings.
Pre-production acts as a mandatory approval gate. Before anything reaches production, QA and stakeholders use this environment to validate changes in a controlled, realistic setup. The process is largely automated, but we’ve built in smart manual checkpoints where human feedback is essential.
Introducing a pre-production environment isn’t about favoring one team over another. It adds complexity for everyone involved, so it’s only natural that software engineers, QA teams and stakeholders see the pros and cons from different angles.
For QA engineers, pre-production was a clear win. It gave us a stable, isolated test environment to retest production issues, validate releases, and catch edge-case bugs before anything went live.
In fast-moving agile development, things can break at awkward moments. A critical production issue might pop up while you’re deep into testing another feature. You risk losing data or halting progress with only one shared test environment. Pre-production solved that, protecting our test data and giving us breathing room.
It also helped us test the release process itself. Were environment variables, feature flags, or deployment configs missing? Pre-production exposed them before users ever noticed.
Most importantly, it gave business stakeholders a role in the quality process. They could explore the app in a production-like environment, validate business logic, and even help decide whether a release was ready. It turned final-stage UAT into a collaborative process, not just a checkbox.
But not every project needs pre-production. A simpler approach might also work if your app is small, has little data complexity, or operates with limited users.
From a developer’s perspective, the pre-production process wasn’t without cost. Supporting another primary environment meant more maintenance, CI/CD logic, config files, and chances for something to go wrong.
It raised fair concerns about overengineering. For lean teams or less critical apps, a single staging environment plus strong monitoring might be enough. That setup provides agility.
But even the skeptics had to admit that the drop in production bugs, the confidence in releases, and the quality of stakeholder feedback were hard to ignore. The ROI became visible very quickly.
Looking back, introducing a pre-production environment was the right move for our team. It reduced risk, improved collaboration and brought business users closer to the development process, without compromising speed.
The pre-production process also allowed us to safely debug production data issues without risking the live environment. This consistent and automated process gave everyone, from developers to stakeholders more confidence in every release.
But that doesn’t mean it’s for everyone. In fact, here are some good reasons NOT to use a pre-production environment:
On the other hand, pre-production shines when:
So instead of asking “Do we need pre-production?,” the better question might be:
“Are there any real reasons not to build one?”
Partner with world-class experts who understand your challenges, deliver seamless solutions, and support you every step of the way.