There are three different things people mean by resetting a WordPress site, and they clean up different amounts. A reset plugin empties the database. wp site empty truncates three tables. Destroying the install and building a new one is the only one that removes files.
Pick the wrong one and the reset appears to work, then the original problem comes straight back. This post covers what each method actually removes, and the four things that survive a database reset.
The three methods, and what each one touches
Reset plugins are the common answer. WP Reset's own description is the honest one: it resets the database "to the default installation values without modifying any files" (InstaWP's roundup, read 2026-09-16). It drops and recreates the core tables plus any table sharing your database prefix.
Files on disk are untouched. Plugin and theme directories stay where they are, deactivated but present.
wp site empty is much narrower than people assume. The WP-CLI docs say it "truncates posts, comments, and terms tables" and "doesn't affect site configuration (options) or users".
So every option row survives, including the ones a broken plugin wrote. Pass --uploads and it also deletes "all files in the site's uploads directory", but nothing else on disk.
Destroying and rebuilding the install removes the database and the filesystem together. This is the only method where the word "clean" is accurate.
Four things that survive a database reset
1. Must-use plugins
wp-content/mu-plugins is loaded by wp-settings.php with no conditional at all:
foreach ( wp_get_mu_plugins() as $mu_plugin ) {
$_wp_plugin_file = $mu_plugin;
include_once $mu_plugin;
There is no active-plugin option consulted, so there is nothing in the database for a reset to clear. A managed host's mu-plugin, or one a previous developer dropped in, runs on the "clean" site exactly as it did before.
2. Drop-in files
Four files in wp-content are loaded by core by filename, again without asking the database. object-cache.php is loaded in wp_start_object_cache():
if ( file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) {
require_once WP_CONTENT_DIR . '/object-cache.php';
db.php is loaded the same way inside require_wp_db(). Both quotes are from wp-includes/load.php on the trunk branch of WordPress/wordpress-develop, read 2026-09-16.
This is the failure mode that wastes the most time. A caching plugin gets deleted, its object-cache.php stays, and the orphaned drop-in keeps trying to reach a Redis server that is no longer there.
3. wp-config.php constants
advanced-cache.php only loads if a constant set in wp-config.php says so:
if ( WP_CACHE && apply_filters( 'enable_loading_advanced_cache_dropin', true ) && file_exists( WP_CONTENT_DIR . '/advanced-cache.php' ) ) {
include WP_CONTENT_DIR . '/advanced-cache.php';
A database reset cannot change WP_CACHE, WP_DEBUG, WP_MEMORY_LIMIT, DISALLOW_FILE_MODS or anything else in that file. If your reset is meant to rule out a configuration problem, the configuration is the one part you did not reset.
4. Tables outside your prefix
A reset plugin works on tables sharing the defined prefix. A plugin that created myplugin_events with no prefix, or that wrote to a second database, keeps its data through the reset and repopulates the "clean" site on first load.
So which one do you actually want?
Match the method to the reason.
Clearing out demo content before a handover. wp site empty --uploads is the right size. You want the options and the users to survive, because the configuration is the work you were paid for.
Starting a redesign on the same install. A reset plugin is fine. You are keeping the hosting, the domain and the SSL certificate, and you accept that anything in mu-plugins is deliberate.
Ruling out a cause while debugging. None of the above. A database reset that leaves drop-ins, mu-plugins and wp-config.php in place cannot rule out drop-ins, mu-plugins or wp-config.php, which are three of the more likely causes. You need an install that never had them.
Recovering from a compromise. Never reset. A reset leaves every file on disk, and a backdoor is a file. Rebuild from source and restore only content you have checked.
Resetting a sandbox instead
The reason we care about this distinction is that we build the rebuild path, so we know what it costs to do properly.
A SandyWP sandbox has a "Reset to clean slate" action that re-provisions the sandbox in place. It is not a database truncation. The worker removes the container, deletes the storage volume, drops the database, and builds the install again from the base template.
The parts that come back identical are the ones derived from the sandbox record rather than its contents: the same URL, the same admin login, the same sandbox in your dashboard. The lease is untouched too, so a reset does not extend or shorten how long the sandbox lives.
Two behaviours are worth knowing before you press it. Any per-site PHP configuration you set is re-applied automatically when the container is recreated, because it is stored on the sandbox record rather than in the install. The WordPress debug constants are the opposite: they go back to the preset the rebuild seeds into wp-config.php, so if you had turned on debug mode you turn it on again afterwards.
There are two guards. A sandbox can only be reset once it is ready, since there is no clean live install to wipe while one is still being created. Multisite sandboxes are refused outright, because they are built through a cold conversion path the in-place rebuild does not reproduce, and returning a broken single site would be worse than saying no.
Honest limit: this only helps if the thing you want to reset is disposable in the first place. It is the right tool for a test install you are about to reuse, and the wrong tool for your live site, where you want a backup and a restore rather than a wipe.
The version most people actually need
If you are resetting because something is broken, the fastest route is usually not a reset at all. Build a clean install, put your theme and plugins on it one at a time, and see which addition reproduces the fault.
That is a different job from emptying a site, and it is the one a disposable install is for. Our guides on testing a plugin conflict and cloning a site safely cover the two halves of it, and the CLI will create the install in one command if you would rather not use the dashboard.
Kinsta's guide (roughly 4,000 words, read 2026-09-16) covers six reset scenarios well and is worth reading for the domain-move case. Like InstaWP's, it does not mention drop-ins, mu-plugins or wp-config.php surviving the reset, which is the part that sends people round the loop a second time.
