Automate client feedback with our MCP serverLearn more!
By Harry Robinson•9th November 2026

A UAT environment is a private copy of your website or application, set up as closely as possible to production, where the business tests the finished product before it goes live. It runs the same code, configuration and integrations as live, with safe data, test-mode payments and restricted access.
Its job is to make a pass meaningful. If the environment behaves differently from production, the people signing off are approving something that will not exist on launch day.
Environment | Used by | Purpose | Data | How often it changes |
Development | Developers | Building features | Fake or minimal | Constantly |
Test or QA | Developers, QA | Technical testing | Built to hit edge cases | Several times a day |
UAT | Client staff, end users | Business acceptance | Realistic and safe | Frozen during a round |
Staging | Developers, operations | Final deployment rehearsal | Close to production | Each release |
Production | The public | The live service | Real | Controlled releases |
On most website projects, one server plays the staging and UAT roles. That works as long as the rules below still apply during testing. Larger projects often separate them, so a deployment rehearsal does not disturb testers partway through a round.
The closer the match, the fewer surprises at launch. These are the things to keep identical:
Keep the same | Why it matters |
Runtime versions (PHP, Node and so on) | Code that works on one version can break on another |
Web server and its configuration | Rewrites, limits and headers change behaviour |
Caching and CDN setup | Caching bugs only appear with caching switched on |
Database engine and version | Queries and character sets can behave differently |
CMS, plugin and module versions | Mismatches are a common cause of "it worked on staging" |
Security headers and consent settings | Headers and cookie banners can block scripts and forms |
Redirects and HTTPS | Mixed content and redirect loops show up here |
Some things should deliberately differ, because the environment must not affect real customers or systems:
Change on purpose | How |
Domain | A separate subdomain such as uat.example.com |
Payment gateway | Test mode with test API keys |
Outgoing email and SMS | Diverted to a shared inbox |
Search engine access | Blocked by a password on the whole site |
Analytics and advertising tags | Removed, or sent to a separate test property |
Scheduled jobs | Disabled if they contact customers or live systems |
Third-party connections | Pointed at supplier sandboxes |
You do not usually need production-sized hardware. Load testing is a separate exercise, and a smaller server is fine as long as it is not so underpowered that testers mistake slowness for a bug.
Testers need data that looks real without the risks of actual customer records. There are three broad options:
Option | What it is | Best for | Watch out for |
Synthetic | Invented products, customers and orders | Most websites | Must be realistic enough to spot errors |
Anonymised copy | Production data with personal details replaced | Complex data, large catalogues | Anonymisation has to be done properly, including free-text fields |
Full production copy | An exact copy of live data | Rarely justified | Personal data risk, and real customers can receive test emails |
Start with synthetic data and only move up if you have a specific reason. Under UK GDPR's data minimisation principle, you should hold only the personal data you need for a purpose. A full copy of your customer database on a test server is hard to square with that, so take advice before you do it.
Practical rules that help:
Create a test account for every user role, with clearly fake details
Make sure test records are obvious, so nobody mistakes one for a real order
Give testers the payment details they need. Stripe's test cards, for example, let you complete a payment without using a real card, and real card details should never be used for testing
Keep a way to reset the data between rounds
Delete the data when the project closes
A UAT environment often contains unreleased work, so treat access as seriously as you would on live.
Put the whole site behind a password or an IP allow list. A noindex tag on its own is not protection. Google's guidance says private content needs password protection, and that a noindex page can still be reached through links. A robots.txt rule is no better, because it is a public file that only asks crawlers to stay away.
Give people their own accounts. Shared logins make it impossible to see who did what. If your CMS has roles, test with the same role each person will have on the live site, rather than handing everyone admin rights.
Never reuse production credentials. If UAT is compromised, the damage should stop there.
Close access afterwards. Remove test accounts and shut the environment down, or lock it again, when the round ends. Forgotten UAT sites have a habit of staying online for years.
Allow your tools. Security rules can block the tools your testers rely on. QualityHive, which is our product, is one example. Its guest link loads the site in a frame from app.qualityhive.com, so a UAT site with strict X-Frame-Options or Content Security Policy headers has to allow app.qualityhive.com and connector.qualityhive.com. If you cannot change those headers, use the widget script or the browser extension instead. Our website UAT software page has more on how this works.
A site that changes while people are testing it produces results nobody can make sense of.
Agree a deployment window, such as once a day at 5pm, and stick to it
Show the release number in the footer so reports can be matched to a version
Run a smoke test after each deployment and before testers start the next day
Tell testers when a new version has gone up and what changed
If testers come across something strange, the version number should tell you whether it was fixed since they saw it.
Problem | Likely cause | Fix |
Real customers receive test emails | Mail not diverted, or a real data copy used | Divert at the mail layer and test it before kick-off |
A fix does not appear for testers | Page cache or CDN not purged | Add cache purging to the deployment |
Works in UAT, breaks on live | Version or configuration differences | Compare environments before launch, and script configuration where possible |
Testers report issues nobody can reproduce | Code deployed mid-test | Use a deployment window and a visible version number |
Test orders appear in the stock system | An integration still points at live | Use sandboxes and review all endpoints |
The UAT site appears in Google | No password, only a robots rule | Password protect the whole site |
Test traffic in live analytics | Tracking tags left on | Remove them, or use a separate property |
Testers locked out on day one | Password expired or office IP not allowed | Have each tester log in before kick-off |
This is also why the environment should be on your UAT checklist from the start. On WordPress, the launch checklist covers the settings that need flipping when you move from UAT to live. If a connection is misbehaving, check whether it was covered in SIT before testers get involved. For how the environment fits the wider process, see our guide to user acceptance testing.
They are often the same server on website projects, and that can work well. Strictly, staging is a rehearsal for deployment and UAT is for business acceptance, so larger teams keep them apart.
Usually no. Synthetic data suits most websites. If you need production-like data for a good reason, anonymise it, restrict who can see it and delete it afterwards.
The named testers, the UAT lead, the approver and the developers supporting the round. Each person should have their own login where possible.
Software and configuration should match as closely as you can make them. Hardware can be smaller, and payments, email and other outbound connections should deliberately differ so testing cannot affect real customers.