WordPress has three top-level directories, and the split is simple: wp-admin and wp-includes are the application, replaced wholesale on every update, and wp-content is everything you added. Anything you care about is in wp-content, and anything you edit outside it will be gone at the next update.
That division explains most of what you need to know about backing up, migrating, securing and troubleshooting a WordPress site. It also explains a category of bug that confuses people repeatedly — a customisation that mysteriously reverts — because the file it was in gets overwritten by design. Here is what is actually in there.
Table of contents
- The three directories, and the rule they imply
- What is inside wp-content
- Must-use plugins and drop-ins
- Backing up and migrating
- Security and the constants worth knowing
- How this fits the rest of the stack
- FAQ
The three directories, and the rule they imply
wp-admin— the administration interface. Core code. Do not touch.wp-includes— the core libraries and functions. Core code. Do not touch.wp-content— plugins, themes, uploads, and anything else added to the installation. Yours.
Plus loose files in the root, of which two matter: wp-config.php holding database credentials and configuration constants, and .htaccess on Apache holding rewrite rules. Both are yours; both survive updates.
The operational rule that follows: an update replaces wp-admin and wp-includes entirely. Any edit to a core file is silently reverted, and worse, the edit works right up until the update, so the connection between the change and the breakage is separated by weeks.
This is why hacking core is the cardinal WordPress sin, and why every legitimate customisation route — hooks, filters, child themes, plugins, must-use plugins — exists inside wp-content. If a tutorial tells you to edit a file in wp-includes, the tutorial is wrong and there is a hook for whatever it is trying to achieve.
What is inside wp-content
A fresh install contains a handful of directories; a running site accumulates more.
/plugins— one directory per plugin. Deleting a directory deactivates the plugin, which is the standard way to recover from a plugin that has taken the site down and locked you out of the admin./themes— one directory per theme, including the child theme where your customisations belong./uploads— every media file, organised into year and month subdirectories by default. This is almost always the largest directory and the one that is genuinely irreplaceable, since it is not reconstructible from anywhere else./languages— translation files./upgrade— temporary working space during updates. Safe to empty; occasionally full of leftovers from failed updates./mu-plugins— must-use plugins, if it exists. Covered below because it behaves differently from everything else.
Plugins also create their own directories here — caches, backups, generated files, logs. A wp-content that has grown unexpectedly large is usually a caching or backup plugin storing more than anyone realised, and it is worth looking at before paying for more disk.
One useful troubleshooting fact: renaming wp-content/plugins to something else deactivates every plugin at once, which is the fastest way to determine whether a white screen is plugin-related. Rename it back and reactivate one at a time.
Must-use plugins and drop-ins
Two special mechanisms live in wp-content and both are worth knowing because they are invisible in the normal admin flow.
Must-use plugins in wp-content/mu-plugins load automatically and cannot be deactivated from the dashboard. They run before regular plugins and do not appear in the standard plugin list. This is genuinely useful for infrastructure code that must always run, and it is also a favourite hiding place for malware precisely because it is not visible where people look. If you are investigating a compromised site, check this directory early.
Note that must-use plugins are only loaded from files directly in mu-plugins, not from subdirectories, which surprises people whose mu-plugin quietly does nothing.
Drop-ins are specifically named files placed directly in wp-content that replace core behaviour entirely:
advanced-cache.php— page caching, installed by most caching plugins.object-cache.php— persistent object caching, installed when you add Redis or Memcached.db.php— replaces the database layer.maintenance.php— a custom maintenance page instead of the default.db-error.php— a custom page for database connection failures.fatal-error-handler.php— replaces the fatal error handler.
Drop-ins are listed under a Drop-ins tab on the plugins screen, which most people have never clicked. A leftover object-cache.php from an uninstalled caching plugin, pointing at a cache server that no longer exists, is a classic cause of a site that is inexplicably slow or throwing errors after a plugin was removed.
Backing up and migrating
The three-directory split makes the backup question straightforward.
What you must have:
- The database — every post, page, comment, user, setting and plugin configuration.
wp-content/uploads— irreplaceable media.wp-content/themes— at minimum your child theme with its customisations.wp-config.php— configuration and credentials, though it must be edited if the destination database differs..htaccessor equivalent — rewrite rules and any custom directives.
What you do not need to back up: wp-admin, wp-includes, and the root PHP files. These are a fresh download of the matching WordPress version. Plugin directories are also re-downloadable, though keeping them is easier than reinstalling and configuring twenty plugins by hand — and essential for any premium plugin you cannot simply re-download.
A full-files backup is simpler and larger; a wp-content plus database backup is smaller and requires knowing the WordPress version to restore against. Either works. What does not work is a backup nobody has restored — test the restore into a staging site at least once, because a backup that fails to restore is discovered at the worst possible moment.
The other migration gotcha: URLs are stored absolutely throughout the database, including inside serialised PHP arrays where a naive find-and-replace corrupts the data by breaking string length prefixes. Use a migration tool or WP-CLI’s search-replace, which handle serialisation correctly.
Security and the constants worth knowing
Because wp-content is the writable, user-modifiable part of the installation, it is where most WordPress security problems are found.
- Block PHP execution in uploads. An uploaded file that gets executed as PHP is the classic path from a file-upload vulnerability to full compromise.
/uploadsshould serve files, never run them, enforced by server configuration. - Directory listing off. Browsing
/uploadsshould not enumerate every file on the site. - Check
mu-pluginsand drop-ins during any compromise investigation. They load automatically and are not visible in the usual plugin list. - Sensible permissions. Directories 755, files 644,
wp-config.phpmore restrictive. Never 777 — it is not a fix for a permissions problem, it is a way of not having permissions. - Remove what you do not use. Inactive plugins and themes still contain code that can be reachable. Delete rather than deactivate.
Two configuration constants worth knowing about, set in wp-config.php. DISALLOW_FILE_EDIT disables the built-in plugin and theme file editor in the dashboard — worth setting on any production site, since that editor turns an admin account compromise into arbitrary code execution.
And WP_CONTENT_DIR with WP_CONTENT_URL can relocate or rename wp-content entirely. This is occasionally suggested as a security-through-obscurity measure; it mostly breaks plugins that hardcode the path, and the security benefit is negligible against anything that reads your HTML. Use it if you have a real structural reason, not as a hardening step.
How this fits the rest of the stack
Most WordPress file work — checking a drop-in, clearing a stuck upgrade directory, spotting an unexpected mu-plugin — needs file access while the site may be misbehaving, which usually means an FTP client and a credential hunt. The RunxBuild hosting calculator covers what running the site costs alongside the rest of the stack. RunxBuild managed WordPress includes a file manager and a database browser in the dashboard: browse, edit, upload, unzip and download files, and inspect tables, run SQL and export or import, without SFTP or phpMyAdmin.
Useful related references:
- WordPress vs Drupal: Ease of Use Against Structured Content
- Gatsby CMS Options: Choosing the Content Layer
- CDN Content Delivery: What It Actually Does for Your Bill and Your Latency
- Services on RunxBuild
FAQ
What is the wp-content folder in WordPress?
The directory holding everything added to the installation — plugins, themes, uploaded media, languages, and plugin-generated files. It is the only top-level directory that is yours; wp-admin and wp-includes are core code replaced wholesale on every update.
Can I edit files in wp-includes or wp-admin?
No. Both are replaced entirely on every WordPress update, so any edit is silently reverted — and because the change works until the next update, the breakage appears weeks later with no obvious cause. Use hooks, filters, a child theme, or a plugin instead.
What are WordPress drop-ins?
Specifically named files placed directly in wp-content that replace core behaviour, such as advanced-cache.php for page caching and object-cache.php for persistent object caching. They appear under a Drop-ins tab on the plugins screen. A leftover object-cache.php from a removed caching plugin is a common cause of unexplained slowness or errors.
What do I need to back up in WordPress?
The database, wp-content/uploads, your theme (especially a child theme), wp-config.php, and .htaccess or equivalent. You do not need wp-admin, wp-includes or the root PHP files — those are a fresh download of the matching version. Test a restore into staging at least once.
Is it safe to rename the wp-content folder?
It is possible using the WP_CONTENT_DIR and WP_CONTENT_URL constants, but it commonly breaks plugins that hardcode the path, and the security benefit is negligible against anything that reads your page source. Do it only for a real structural reason, not as a hardening measure.