wp-config.php
is the most important file in your WordPress installation. It tells WordPress how to connect to the database, where to find its content, which security keys to use for authentication, and how to behave in different environments. Every single page load reads this file before anything else happens.
Unlike most WordPress files,
wp-config.php
is not part of WordPress core. It is generated during installation with your specific settings and stays untouched by WordPress updates. This means it is your file to configure, and changes you make here persist across every update, migration, and plugin installation.
Most WordPress guides tell you to add lines to
wp-config.php
without explaining what they do or where they go. This guide explains every important setting in the file, what happens if you get it wrong, and the settings that are worth adding beyond the defaults.
Where wp-config.php fits in the WordPress lifecycle#
When a visitor loads any page on your WordPress site, the request follows a specific path through PHP files. The WordPress index.php and wp-admin files guide covers this chain in full. The relevant part:
index.php
loads
wp-blog-header.php
, which loads
wp-load.php
, which loads
wp-config.php
. This happens before WordPress loads plugins, themes, or content. Everything in
wp-config.php
is set before WordPress starts.
This is why changes to
wp-config.php
take effect immediately – there is no cache to clear, no service to restart, no settings page to save. Edit the file, and the next page load uses the new values.
The file lives in the root of your WordPress installation, alongside
wp-admin/
, wp-content/, and
wp-includes/
. WordPress also checks one directory above the root, so you can move
wp-config.php
up one level for additional security (keeping it outside the web-accessible directory).
Database settings#
These four constants tell WordPress how to connect to MySQL. If any of them are wrong, you get the error establishing a database connection message.
define('DB_NAME', 'wordpress_db');
define('DB_USER', 'wp_user');
define('DB_PASSWORD', 'your_password_here');
define('DB_HOST', 'localhost');
DB_NAME is the name of the MySQL database that holds your WordPress tables. Not the server name, not the username – the database name specifically. You can check which databases exist with SHOW DATABASES via SSH or phpMyAdmin.
DB_USER is the MySQL user account that has access to this database. This user needs SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, and DROP privileges on the database. See how to manage MySQL user permissions for the full breakdown of required privileges.
DB_PASSWORD is the password for that MySQL user. This is stored in plain text. There is no way around this – PHP needs the actual password to authenticate with MySQL. This is one of the reasons
wp-config.php
should never be publicly accessible.
DB_HOST is the MySQL server address. On most hosting setups, this is
localhost
(MySQL runs on the same server as PHP). Some hosting providers use a separate database server, in which case this might be an IP address or hostname like
db.example.com
.
Table prefix
$table_prefix = 'wp_';
This prefixes every WordPress table name. The default
wp_
creates tables named
wp_posts
,
wp_users
,
wp_options
, and so on. Changing the prefix (for example, to
blog_
) creates
blog_posts
,
blog_users
, etc.
On a fresh installation, a non-default prefix adds a thin layer of security by making automated SQL injection attacks slightly harder (they often assume the default prefix). On an existing site, do not change this value – WordPress will look for tables with the new prefix and find nothing.
If you run multiple WordPress installations on the same database (uncommon but possible), each needs a unique prefix to avoid table name collisions.
Authentication keys and salts#
define('AUTH_KEY', 'unique-random-string-here');
define('SECURE_AUTH_KEY', 'unique-random-string-here');
define('LOGGED_IN_KEY', 'unique-random-string-here');
define('NONCE_KEY', 'unique-random-string-here');
define('AUTH_SALT', 'unique-random-string-here');
define('SECURE_AUTH_SALT', 'unique-random-string-here');
define('LOGGED_IN_SALT', 'unique-random-string-here');
define('NONCE_SALT', 'unique-random-string-here');
These eight constants are used to generate the cryptographic hashes in WordPress authentication cookies. When you log in, WordPress creates a cookie with an HMAC signature generated using these keys and salts. On every subsequent request, WordPress validates the cookie using the same keys. If the keys change, every existing cookie becomes invalid and every user gets logged out.
If your site was hacked, changing these keys is one of the first things to do. It immediately invalidates all logged-in sessions, including the attacker’s. See the WordPress hacked recovery guide for the full checklist.
Generate new keys at the WordPress secret key API:
https://api.wordpress.org/secret-key/1.1/salt/
. Copy the output and paste it into
wp-config.php
, replacing the existing keys.
Never leave these as the default placeholder values (
put your unique phrase here
). A WordPress installation with default keys is significantly easier to attack because the cookie signatures are predictable.
Debug settings#
define('WP_DEBUG', false);
This is the master switch for WordPress debug mode. When
false
(the default), PHP errors, warnings, and notices are hidden. When
true
, they are exposed.
On a production site,
WP_DEBUG
should be
false
. On a staging or development site, enable it along with these companions:
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
WP_DEBUG_LOG writes all errors to
wp-content/debug.log
. This is the safest way to see errors on a live site – they go to a file instead of the screen. Check this file when diagnosing PHP warnings, plugin errors, or the white screen of death.
WP_DEBUG_DISPLAY controls whether errors appear in the browser. Set this to
false
on any publicly accessible site. Displaying PHP errors to visitors is a security risk because error messages reveal file paths, database details, and server configuration. For the full guide on PHP error visibility, see how to display PHP errors and enable error reporting.
Script debugging
define('SCRIPT_DEBUG', true);
Forces WordPress to load the unminified versions of core CSS and JavaScript files. This is useful when developing themes or plugins and you need to read the source, but it slows down the site. Leave this off in production.
Site URL settings#
define('WP_SITEURL', 'https://example.com');
define('WP_HOME', 'https://example.com');
These override the WordPress Address and Site Address values in the database (Settings > General). When defined in
wp-config.php
, the corresponding fields in Settings are greyed out.
WP_SITEURL is where the WordPress core files live. WP_HOME is the address visitors type to reach your site. In most setups, they are identical. They differ when WordPress is installed in a subdirectory but you want the site accessible from the root domain.
Defining these in
wp-config.php
is useful when:
- You are fixing a redirect loop caused by incorrect URL settings in the database
- You are migrating between domains and need to set the URLs before accessing the dashboard
- You want to prevent accidental changes through the admin interface
- You are running WordPress behind a reverse proxy or load balancer that handles SSL termination
If these values do not match the actual URL (for example,
http
instead of
https
), you get redirect loops, mixed content errors, or broken stylesheets. Always include the protocol and never include a trailing slash.
Memory and performance settings#
PHP memory limit
define('WP_MEMORY_LIMIT', '256M');
define('WP_MAX_MEMORY_LIMIT', '512M');
WP_MEMORY_LIMIT sets the PHP memory limit for front-end operations (page loads, API requests). WP_MAX_MEMORY_LIMIT sets it for admin operations (uploading media, running imports, updating plugins), which typically need more memory.
These values can only increase the limit, not exceed the server-level
memory_limit
set in php.ini. If php.ini sets
memory_limit = 128M
, setting
WP_MEMORY_LIMIT
to
256M
has no effect. For the full guide on memory limits and what to do when they are exhausted, see WordPress PHP memory exhausted error.
Post revisions
define('WP_POST_REVISIONS', 10);
WordPress saves a revision every time you update a post. On a site with thousands of posts updated frequently, the
wp_posts
table can grow to millions of rows, slowing down queries and bloating backups.
Setting this to a number limits how many revisions WordPress keeps per post.
10
is reasonable for most sites. Setting it to
false
disables revisions entirely. Setting it to
true
(the default) keeps unlimited revisions. For database cleanup, see WordPress database optimization.
Autosave interval
define('AUTOSAVE_INTERVAL', 120);
The default autosave runs every 60 seconds. On busy sites with many simultaneous editors, this creates frequent AJAX requests to the server. Increasing it to 120 or 180 seconds reduces server load with minimal risk.
Trash retention
define('EMPTY_TRASH_DAYS', 14);
WordPress empties the trash automatically after 30 days by default. Lowering this keeps the database smaller. Setting it to
0
disables the trash entirely – deleted posts are permanently removed immediately. This is risky on multi-author sites where accidental deletions happen.
Security settings#
Disable file editing
define('DISALLOW_FILE_EDIT', true);
Removes the Theme Editor and Plugin Editor from the WordPress admin. These editors let anyone with admin access modify PHP files directly from the browser. If an attacker gains admin access, the editors give them the ability to inject malicious code into any theme or plugin file. Disabling them is a basic security measure.
Disable plugin and theme updates via the admin
define('DISALLOW_FILE_MODS', true);
This is the stronger version. It prevents all file modifications through WordPress: no plugin installs, no theme installs, no updates through the dashboard. All changes must happen through SFTP, SSH, or WP-CLI. This is appropriate for managed environments where deployments are handled through a controlled process rather than the WordPress admin.
Force SSL for admin
define('FORCE_SSL_ADMIN', true);
Forces all admin and login pages to use HTTPS. On modern sites that already run entirely on HTTPS (as they should), this is redundant but harmless. It matters on sites where HTTP is still partially in use, ensuring that credentials never travel unencrypted.
Automatic updates
define('WP_AUTO_UPDATE_CORE', true);
Controls WordPress core automatic updates. The default (
minor
) applies security releases automatically. Setting it to
true
enables major version auto-updates as well. Setting it to
false
disables all automatic updates.
Keeping at least minor updates automatic is strongly recommended. Core security releases patch known vulnerabilities, and the window between disclosure and exploitation is often measured in hours.
Multisite
define('WP_ALLOW_MULTISITE', true);
Enables the WordPress Multisite feature, which lets you run multiple sites from a single WordPress installation. After enabling this constant and following the network setup wizard in the admin, WordPress adds additional constants for the multisite configuration. See the WordPress multisite hosting guide for the infrastructure requirements and additional wp-config.php settings multisite requires.
Common wp-config.php problems#
Site down after editing
A syntax error in
wp-config.php
takes down the entire site immediately. There is no graceful error message – the browser shows a blank page or a generic server error. The fix is always the same: restore the backup you made before editing, or fix the syntax error via SSH.
The most common syntax errors:
- Missing semicolon at the end of a
define()line - Unmatched quotes (single quote inside a single-quoted string)
- Pasting code from a website that uses curly/smart quotes instead of straight quotes
- Adding code after the
require_once ABSPATH . 'wp-settings.php'line
Database connection error after migration
After migrating WordPress to a new server, the database connection error is almost always caused by
wp-config.php
still containing the old server’s database credentials. Update
DB_NAME
,
DB_USER
,
DB_PASSWORD
, and
DB_HOST
to match the new server.
Redirect loop after changing URLs
Setting
WP_SITEURL
or
WP_HOME
incorrectly (wrong protocol, trailing slash, or mismatched domain) causes infinite redirects. The browser shows ERR_TOO_MANY_REDIRECTS. Fix the values in
wp-config.php
or remove them entirely and correct the URLs through the database.
Where to put custom settings#
The most common mistake with
wp-config.php
is adding settings in the wrong place. The file has a specific structure:
// 1. Database settings (DB_NAME, DB_USER, etc.)
// 2. Authentication keys and salts
// 3. Table prefix
// 4. Custom settings go HERE
// 5. "That's all, stop editing!" comment
// 6. ABSPATH and require wp-settings.php
All custom constants must go between the table prefix and the “That’s all, stop editing!” comment. Anything after the
require_once ABSPATH . 'wp-settings.php'
line runs after WordPress has already initialized, and many constants will have no effect.
The line to look for:
/* That's all, stop editing! Happy publishing. */
Add your custom
define()
statements above this line.
Editing wp-config.php safely#
wp-config.php
is a PHP file. A single syntax error – a missing semicolon, an unclosed quote, a stray character – will crash your entire site with a fatal error. No front-end, no admin, no login page. Nothing.
Always keep a backup before editing. Copy the file via SFTP or SSH before making changes:
cp wp-config.php wp-config.php.bak
If something goes wrong, restore the backup:
cp wp-config.php.bak wp-config.php
Edit with a proper text editor (nano or vim over SSH, or a local editor via SFTP). Never use a word processor or rich text editor – they can insert invisible characters that break PHP parsing.
wp-config.php on Hostney#
On Hostney,
wp-config.php
is generated automatically when WordPress is installed on your account. The database credentials are pre-configured, authentication keys are generated with unique random values, and debug mode is off by default.
You can edit
wp-config.php
via SSH through the Terminal Access section in the control panel, or through the file manager. PHP settings like memory limits are managed through Hosting > PHP Manager and take effect at the server level, so you typically do not need to set
WP_MEMORY_LIMIT
in
wp-config.php
unless you want a WordPress-specific override.
If you break
wp-config.php
and the site goes down, connect via SSH and restore your backup. If you do not have a backup, the database credentials for your account are available in the control panel under your site’s hosting settings.