The Developer’s Advanced Guide to the wp-config File

How well do you really know wp-config? There’s a surprising amount of power in those few lines of PHP! This article is a tour of some bits of wp-config that you maybe didn’t know about, but really should.

Do you know all there is to know about the wp-config.php file? Have you read the whole of the WordPress documentation page about it? Right to the end?

If you’re already familiar with the basics of wp-config, then reading official WordPress documentation will probably be a proper snooze fest.

If you want the real developer treats, grouped nicely by subject, and delivered with what could only be called “totally unnecessary enthusiasm over a few PHP constants,” then stick around: I’m about to make wp-config.php cool again.

Milhouse from the Simpsons, with "wp-config" across his face, and the caption "My mom says I'm cool."

Table of Contents

  1. Who Should Read This?
  2. Why Should You Read This?
  3. The Basics
  4. Viewing wp-config Constants
  5. Breaking Down the wp-config.php Loading Process
    1. wp-config Can Be Moved Up
    2. The Setup Screen Loads if There Isn’t a wp-config.php File
    3. wp-config.php Loads Very Early
    4. Don’t Mess With wp-config.php!
  6. Checking/Linting Your wp-config.php File
  7. Securing WordPress With wp-config.php
    1. Protecting wp-config.php From Website Visitors
    2. Rotating Keys/Salts
    3. Moving and Hiding Things
    4. Disabling the File Editors
    5. Disabling Automatic Updates
    6. Preventing External HTTP Requests
  8. Moving Stuff Around
    1. Moving the User and Usermeta Tables
    2. Move Content, Uploads, and Plugins Directories
  9. Content-Related Settings
    1. Change Site and Dashboard URLs
    2. Post Settings
    3. Post Revisions
    4. Changing the Autosave Interval
  10. Wrapping Up

Who Should Read This?

This article is aimed at developers and advanced users who already know how to edit the wp-config.php file and are aware of some of the configuration settings you can put in it.

I’m not going to tell you how to edit the file using FTP or cPanel, or why you shouldn’t use MS Word to edit it.

I’m not going to tell you how to configure your database or go over legacy settings that you were using in 2013 but really shouldn’t need any more. And most hosts will take care of the basics for you anyway.

If you’re new to wp-config.php, there’s no shortage of guides that will give you the basics, or you can always dig into the official documentation.

Why Should You Read This?

Yeah, yeah, I hear you. If the basic details of what you can put in this article are all covered elsewhere, and if your host takes care of most of the basics anyway, why should you read this? And, indeed, why am I spending my time writing it?

Well, if you’re happy with editing wp-config.php, and you know the basics of what it does, then you are probably at least an intermediate-level WordPress developer.

You are probably at least partly responsible for hosting large sites, probably for clients. So you need to know how you can use this file in an emergency. And to have enough of an understanding of this file that, if you do edit it, you won’t do something wrong.

In addition, you will almost certainly want to lock down certain features of WordPress beyond what your host will allow you to configure automatically.

It’s likely that there are things you don’t even know you can do with wp-config.php! Some “Aha!” moments to be had.

This article is a useful reference point for configuring some of WordPress’s internals. So read on, bookmark, and share with your friends and colleagues.

The Basics

I said this wasn’t a beginner’s article, but we should establish the basic facts to make sure we’re at the same starting point.

The wp-config.php file lives in the root of your WordPress install (it can live in other places, but we’ll come to that), loads as part of WordPress’s initialization, and allows you to configure WordPress core.

It is essential to the running of WordPress. It stores a set of constants that let you specify:

  • The database connection and table prefix that WordPress uses.
  • Security information like salts and auth keys.
  • Settings for other features of WordPress core such as WP_CACHE and WP_DEBUG.
  • Settings for plugins that may add their own options to the file.
  • Your own configuration options.

Crucially, wp-config.php is an environment-specific file. Its contents can (and should!) be different for different sites. Even local, staging, and live copies of the same site will have different values in the file.

WordPress comes with a wp-config-sample.php file that contains the bare minimum of details WordPress needs to work. You could copy this to your own wp-config.php as part of the installation, but these days that is usually done for you.

Finally, just note that it’s possible that when you open a wp-config.php file from an existing site you may see some old PHP constants for legacy features like default file permissions and FTP credentials for running upgrades. We won’t cover those here as it’s unlikely that you’ll need to use them.

Viewing wp-config Constants

There are a few ways to quickly check the values of WordPress constants without SSHing to a remote server and opening the file.

The Site Health feature of WordPress core lets you view some basic values by navigating to Tools -> Site health -> Info -> WordPress constants. Database constants can also be seen in the “Database” section of the same page.

Database constants, shown here in the Database section of the WordPress Site Health page.

The Query Monitor plugin has an “Environment” panel where you can see some commonly used wp-config constants.

The Query Monitor plugin’s "Environment" panel, showing some commonly used wp-config constants.

WP-CLI, the WordPress command-line interface, has a wp config command that can be used to get and set constants in wp-config.php. This would normally require you to SSH first, but if you set up aliases in your WP-CLI configuration then you can create a quick shortcut to view and modify constants in remote wp-config files.

Breaking Down the wp-config.php Loading Process

It’s useful to know when the wp-config.php file loads, as this determines some of the things that you can and cannot do with it. It’s a good exercise to trace the loading process:

  • WordPress starts loading with the index.php file. This requires the wp-blog-header.php file.

  • Pretty much the first thing that wp-blog-header.php does is load wp-load.php.

  • Next, wp-load.php sets the ABSPATH constant (the base WordPress core directory) and initializes error_reporting() before loading wp-config.php.

This loading process, and the code in wp-load.php in particular, can teach us a few interesting things. Here is that code:

/*
 * If wp-config.php exists in the WordPress root, or if it exists in the root and wp-settings.php
 * doesn't, load wp-config.php. The secondary check for wp-settings.php has the added benefit
 * of avoiding cases where the current directory is a nested installation, e.g. / is WordPress(a)
 * and /blog/ is WordPress(b).
 *
 * If neither set of conditions is true, initiate loading the setup process.
 */
if ( file_exists( ABSPATH . 'wp-config.php' ) ) {

        /** The config file resides in ABSPATH */
        require_once ABSPATH . 'wp-config.php';

} elseif ( @file_exists( dirname( ABSPATH ) . '/wp-config.php' ) && ! @file_exists( dirname( ABSPATH ) . '/wp-settings.php' ) ) {

        /** The config file resides one level above ABSPATH but is not part of another installation */
        require_once dirname( ABSPATH ) . '/wp-config.php';

} else {

        // A config file doesn't exist.

        // [Code here to load the setup screen for in-browser configuration]

}

What do we see here?

wp-config.php Can Be Moved Up

First, the comment tells us that we can put wp-config.php in the “WordPress root”. What it fails to mention is that the “root” can actually be a directory above the ABSPATH where wp-load.php lives.

We can see this additional check in the elseif where it looks for dirname( ABSPATH ) . '/wp-config.php'. The additional condition in the elseif is explained in the comment.

The Setup Screen Loads if There Isn’t a wp-config.php File

Second, we can see that if a config file doesn’t exist, it will load the setup screen.

It’s entirely possible that you’ve never seen this screen before. It lets you enter the initial configuration information, such as the database credentials, in a web-based user interface:

The rarely seen WordPress setup screen. WordPress loads this if it doesn’t find a config file, allowing you to set configuration options manually.

This is a feature of WordPress worth knowing about. If you ever put the WordPress core files on a publicly-available web server, but don’t create a wp-config.php file, then someone else (or, more likely, a bot) can come along and set up WordPress their way and possibly compromise your hosting.

wp-config.php Loads Very Early

The third thing to note is that wp-config.php is loaded very early in WordPress’s startup sequence. This means that:

  1. There is a lot we can’t do in wp-config.php. For example, we can’t add hooks (actions or filters) here because the functions and data structures for doing that aren’t loaded yet. And we don’t have access to any of WordPress’s internal functions, objects, and APIs.

  2. We have a lot of control over what happens next. Because the file is loaded so early, it has a lot of influence over WordPress. This is both good and bad. We can easily make WordPress die completely. But we can also access anything that is defined in wp-config.php from pretty much anywhere else in WordPress.

Don’t Mess With wp-config.php!

The final thing we learn from this process is that with this great power comes great responsibility.

At the bottom of the wp-config.php file are these lines:

/* Add any custom values between this line and the "stop editing" line. */



/* That's all, stop editing! Happy publishing. */

/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
        define( 'ABSPATH', __DIR__ . '/' );
}

/** Sets up WordPress vars and included files. */
require_once ABSPATH . 'wp-settings.php';

There are some instructions here, but the “stop editing” line is important. After this line is the continuation of WordPress’s initialization sequence. Adding new code in the wrong place will probably only result in the new code having no effect whatsoever. But to be safe, I recommend following these instructions. They’re there for a good reason.

Checking/Linting Your wp-config.php File

If you’re working in production, you really don’t want to put any errors in the wp-config.php file. Errors here can break your website, and you may not get a useful error message displayed when it does.

You can run php on the command line with the -l (“lint”) option to check your wp-config.php file for fatal PHP syntax errors.

$ php -l wp-config.php

Parse error: syntax error, unexpected token "require_once" in wp-config.php on line 9

Errors parsing wp-config.php

You could even write a shell script to…

  1. Copy wp-config.php to a temporary file,
  2. Edit the temporary file,
  3. Lint the temporary file, and
  4. Copy it back only if it has no syntax errors.

If you’re happy with the command line, then it’s safer to use the WP-CLI commands such as wp config set <name> <value> to safely set values rather than doing it by hand.

You can list your config values with WP-CLI too (this is a sample with some entries removed – you get the idea!):

$ wp config list
+---------------------+-----------------------------------------------+----------+
| name                | value                                         | type     |
+---------------------+-----------------------------------------------+----------+
| root_dir            | /Users/smithers/sites/snpp                    | variable |
| webroot_dir         | /Users/smithers/sites/snpp/public             | variable |
| table_prefix         | wp_                                           | variable |
| WP_HOME             | https://snpp.test                             | constant |
| WP_SITEURL          | https://snpp.test/                            | constant |
| DB_NAME             | snpp                                          | constant |
| DB_USER             | root                                          | constant |
| DB_PASSWORD         | Montgomery                                    | constant |
| DB_HOST             | 127.0.0.1                                     | constant |
| DB_CHARSET          | utf8mb4                                       | constant |
| DB_COLLATE          |                                               | constant |
| DB_PREFIX           | wp_                                           | constant |
| WP_DEBUG            | 1                                             | constant |
| WP_DEBUG_LOG        | 1                                             | constant |
| WP_DEBUG_DISPLAY    |                                               | constant |
| WP_ENVIRONMENT_TYPE | development                                   | constant |
| DISABLE_WP_CRON     |                                               | constant |
| DISALLOW_FILE_EDIT  | 1                                             | constant |
+---------------------+-----------------------------------------------+----------+

These two techniques could really save you some hassle and stop you freaking out about accidentally putting a semi-colon in the wrong place in such a critical file.

Securing WordPress With wp-config.php

Security is a perpetually hot topic in WordPress. Some settings we can change in the wp-config file put more tools into our security toolbox.

These parts of the wp-config file are definitely not the only things you should use to achieve good WordPress security. Make sure you understand website security thoroughly in addition to the information in the following section.

Protecting wp-config.php From Website Visitors

Your wp-config file lives in your website’s root directory by default, and it just happens to contain critical information like your database login details and password salts. You do not want this information to be publicly available, so you should ensure that your wp-config file is protected from website visitors.

Your hosting company will often do this for you. You can check by trying to access the file from your browser by adding /wp-config.php right after your domain. This URL may be different if you have moved the file.

If you have placed the wp-config file in the directory above your website’s root directory, then you should not be able to see it. In most other cases you will just get a PHP error message when trying to visit the file anyway, so there’s usually nothing to do here. But if you want to secure it properly then you can do so by modifying your web server (Apache or nginx) configuration to block access to it.

Finally, if you’re storing your website’s file in Git it is important to not store the wp-config file in your Git repository. Doing so could leak critical information about your site, but in addition you probably want a different version of this file in each environment anyway. So it’s better to add it to your .gitignore and manually manage the files in each environment.

Rotating Keys/Salts

What are keys/salts?

The keys and salts section is one of the more mysterious parts of wp-config. This set of weird-looking constants helps with the encryption of things like cookies and nonces. Without going into the details—as WP Engine has—they add an extra layer of randomness that makes things harder to decrypt if you don’t know the salts and keys.

Why “rotate” keys/salts?

First off, “rotate” is just a fancy word for “change.” I don’t know why we use “rotate.” It’s not like we ever come back to the same set of keys!

You should probably change your keys and salts if the site has been hacked, as you can’t guarantee that the keys and salts are still secret. But you may want to rotate them on a regular basis anyway, like with passwords, just to be sure no one knows what they are.

The problem with rotating keys/salts

Changing keys and salts is not without pain. Anyone who has a cookie set will lose it. So anyone logged in will be booted out, and anyone with a WooCommerce cart will have it emptied.

How to rotate keys/salts

I mean, you could edit the wp-config file and just type some new random characters over the old ones. But this would be tedious and humans aren’t very good at randomness.

So let me tell you about a few ways to set new keys/salts in your wp-config.

  1. Manually add keys from a generator: You can use the wordpress.org generator to get the code you need. Just copy-and-paste it into the wp-config file in place of the old values.
  2. Use a plugin: Many security plugins like Sucuri Security, iThemes Security, and Malcare all have this feature. And Salt Shaker is a dedicated plugin that will automate this process on a schedule for you.
  3. Use WP-CLI. Have we said how awesome WP-CLI is yet? We did? OK. Well, we’re saying it again! And you can use the wp config shuffle-salts command to do this job in seconds.

Moving and Hiding Things

Security people will tell you that “security by obscurity” is not security at all, but some people still like to hide their WordPress stuff to put up some additional barriers to the hackers.

The wp-config file gives you a number of options for doing this, and we will cover these in later sections on moving things and turning off file editing.

Disabling the File Editors

WordPress has a handy feature that allows you to edit files in themes and plugins from inside the admin dashboard. Editing wp-config.php lets you turn these file editors off! Some people like to disable them for peace of mind.

Now I know that there’s a security argument that if someone has administrator access to your site—which is needed to use these editors—then they can upload a plugin and do whatever they like anyway. Having these editors enabled isn’t providing hackers with any more power than they already have.

However, though security might not actually be improved by turning these off, the real reason to do it is to stop people who are actually authorized as admins from using them. If you’re an agency, you probably don’t want your clients discovering they can edit all their theme files, right?

Many hosts will just disable this feature by default. But if you want to make them disappear it’s as simple as adding:

define( 'DISALLOW_FILE_EDIT', true );

Or if you really want to lock down your filesystem, there’s DISALLOW_FILE_MODS, which we will cover in the next section.

Disabling Automatic Updates

Whether you love or hate them, WordPress’s automatic updates have had a net-positive impact on the WordPress ecosystem and are hard to ignore. But not everyone wants their software taking care of itself!

So wp-config gives you control over the automatic updates process with a simple set of self-explanatory constants that you can set:

# Disable all core updates:
define( 'WP_AUTO_UPDATE_CORE', false );

# Enable all core updates, including minor and major:
define( 'WP_AUTO_UPDATE_CORE', true );

# Enable core updates for minor releases (default):
define( 'WP_AUTO_UPDATE_CORE', 'minor' );

If you want something more extreme, you can DISALLOW_FILE_MODS:

define( 'DISALLOW_FILE_MODS', true );

But this stops WordPress writing anything to disk related to core, themes, plugins or translations, and it disables email notifications about minor updates. It has been described by a core contributor as “crazy stupid to use unless you know exactly what you are doing.”

Slightly less extreme is AUTOMATIC_UPDATER_DISABLED. This lets you install plugins and themes, but won’t update them or the core software. It also disables translation updates though.

define( 'AUTOMATIC_UPDATER_DISABLED', true );

There is a detailed guide on all this on wordpress.org, including some other options like using filters for more fine-grained control.

Finally, I note that if your site is version controlled, then it is likely that WordPress has disabled updates for you anyway. For example, the presence of a .git directory in the site’s root (or various other files in various different places) will disable automatic updates without you needing to add anything to wp-config.

Configuring HTTPS

Configuring HTTPS often used to be challenging. With the advent of free, trusted security certificates from places like LetsEncrypt and Cloudflare, many hosts will set this up for you with a couple of clicks. This setting should probably be considered legacy, but perhaps you still need it for something.

The FORCE_SSL_ADMIN constant tells WordPress to always use SSL for the login pages and WordPress Dashboard. This ensures that secure credentials and cookies cannot be sent unencrypted.

But, like I said, a good hosting company is going to make setting up HTTPS on your site simple anyway, so just do it.

Preventing External HTTP Requests

Finally in security, you can block external HTTP requests. This means that WordPress can’t contact other places on the internet to do things like make API calls or download updates.

Allowing WordPress to contact external services over HTTP is generally a good idea because it lets you get updates, install plugins and themes, and many plugins will break if you turn HTTP requests off.

But WordPress core and many plugins and themes send “telemetry” or “usage data” back to central servers. This can be good – it helps plugin and theme developers know who is using their software and how. But if you have a site that has particularly sensitive data on it, you may want to disable this. And you can do that with:

define( 'WP_HTTP_BLOCK_EXTERNAL', true );

If you want to have an allow-list of hosts that can be contacted then you can do that too:

define( 'WP_ACCESSIBLE_HOSTS', 'api.wordpress.org,*.github.com' );

Note that the accessible hosts list is a comma-separated list and wildcard subdomains are allowed. And you can monitor what hosts are being contacted using the Log HTTP Requests plugin.

Moving Stuff Around

Not every WordPress install is the same. Some hosts or frameworks like to move directories around for security reasons or to keep site-specific code and assets separate from WordPress core. My article on using Git and Composer to manage WordPress covers some benefits of this approach.

So what options does WordPress give you for – for want of a better term – “moving stuff”?

Changing the Database Prefix

WordPress uses the database table name prefix wp_ by default. This prefix is added to all database table names and is used in some other places too, for example the <prefix>user_roles option in the options table, and the <prefix>capabilities user meta entries.

Hackers or attackers may use the default prefix in an attack, trying to discover or modify your database tables. So some people recommend changing it from the default.

The wp_config option $table_prefix lets you do this and you should probably set it to some short but random string, suffixed with an underscore:

$table_prefix = 'b4F8az_';

This will tell WordPress to use table names such as b4F8az_posts instead of wp_posts.

You shouldn’t have to update any code to cater for this change (unless that code is very badly written), but if you are changing this on an existing site, you will have to make some updates to your database – and not just renaming the tables!

Some security plugins will do this for you and there is a plugin that can do this too. We highly recommend making a backup of your database before doing this, and note that selecting a non-default table prefix is best done when installing WordPress, not when changing it while your site is in-flight.

A curious note on this is that $table_prefix is a variable, not a constant. It is the only variable defined in the sample config file that WordPress gives you! And if you’re still curious: yes, WP-CLI’s wp config commands take care of this for you without you even having to know!

Moving the User and Usermeta Tables

I’ve never seen this done, and I only learned that it could be done when writing this article, but you can also completely change the names of the user and usermeta tables.

I guess this helps prevent a SQL-injection attack that tries to “SELECT * FROM wp_usermeta;”, but I’m happy to hear other reasons to do it.

In any case, the CUSTOM_USER_TABLE and CUSTOM_USER_META_TABLE constants are what you need:

define( 'CUSTOM_USER_TABLE', $table_prefix.'my_users' );
define( 'CUSTOM_USER_META_TABLE', $table_prefix.'my_usermeta' );

There are some caveats that are worth knowing before you use these constants. Check the official docs before using this feature. And like using a custom table prefix, this is definitely best done when installing a new site, rather than modifying it later on.

Move Content, Uploads, and Plugins Directories

It is also possible to move the whole wp-content directory, the uploads directory and the themes and plugins directories. Things to note:

  • In some of these cases you need to set the URL as well as the directory.
  • You need to be careful to use full paths, or relative paths as appropriate.
  • None of these settings should have a trailing slash.

Consult the official documentation for details – I won’t repeat all of that here.

Finally, note that a badly coded plugin or theme can mess up if you change these. This should never happen, but it’s worth knowing about.

If you’re a plugin or theme developer, it’s important to remember that these paths can change. So be sure not to hard code paths to directories or URLs. Useful functions for you here are:

wp_upload_dir plugins_url plugin_dir_url plugin_dir_path get_stylesheet_directory get_stylesheet_directory_uri get_template_directory – note that for a child theme this returns the parent theme’s location get_template_directory_uri

There is a more exhaustive list of functions like these in the WordPress developer’s handbook.

Finally, as well as moving files around inside your WordPress install, you may also want to move your wp-admin location, or change the location of your site. And wp-config.php can help with that too.

WordPress is, after all, a content management system. So you’d expect some of the constants you can use in wp-config.php to control content options. Let’s have a look and see what we can do.

Change Site and Dashboard URLs

These have always confused me.

To set the URL of your site you need to use the WP_HOME constant, not the WP_SITEURL constant.

The WP_SITEURL constant does not change your site’s URL.

Confused?

The official description of what WP_SITEURL does is “the address where your WordPress core files reside.” This is also confusing because it’s a URL, not a directory.

Don’t blame me for this, I’m just your tour guide for the day!

Setting WP_HOME and WP_SITEURL overrides the home and siteurl entries in the wp_options database table. So that, at least, makes sense.

// NOTE: These must not have trailing slashes
define( 'WP_HOME', 'https://helfish.media' );
define( 'WP_SITEURL', 'https://hellfish.media/wordpress` );

You can use these constants after moving a site to a new URL, to get the site up and running while you fix the database up properly. You may even choose to leave them in place afterwards.

The WP_SITEURL setting can also be used when you have moved your core WordPress files to a different directory.

Using these also prevents a database query or two from being run to get the values from the options table, so it may have a marginal performance gain. Though if you’re doing object caching that gain is probably negligible.

There is some more detail in the official docs, and even a full support article on changing the site URL. Additionally, that article includes the obscure RELOCATE constant for wp-config.php that I’d never heard of before researching this article.

Finally, when moving sites, note that this isn’t the only thing you have to change. A full database search-and-replace for the URL strings is recommended.

Post Settings

There are a few different settings you can modify when it comes to posts. Most of these are concerned with either post revisions or the autosave feature.

Post Revisions

The default behavior of WordPress is to save all revisions made to posts and pages. The advantage of this is that it’s easy to revert to previous versions. The disadvantages are that all those revisions take up space in the database and can impact site performance by slowing down database queries.

It’s possible to completely disable post revisions by modifying the WP_POST_REVISIONS value in your wp-config.php file. It defaults to true. To turn off revisions you can set it to false instead:

define( 'WP_POST_REVISIONS', false );:

Some hosts, including WP Engine, disable post revisions by default. I recommend checking with your hosting provider before making any changes. This varies from host to host, but if you’re with WP Engine, you cannot enable revisions through wp-config, as it will be overwritten at the server level.

If your host controls this and you try to change it, you won’t necessarily break something, but you might be wasting your time.

If you are concerned about post revisions slowing down database queries, a better option might be to limit the number of revisions that WordPress stores. This is controlled by the WP_POST_REVISIONS constant, which you can set to the maximum number of revisions you want to keep:

define( 'WP_POST_REVISIONS', 5 );

Changing the Autosave Interval

You can also decrease how often the autosave fires off. This defaults to every 60 seconds, but you can change it to whatever you like. If you’re paranoid, you might want to set this to 20 or 30 seconds instead.

It’s important to bear in mind how long an autosave takes. You don’t want them to overlap by making them happen too frequently, so don’t set this value to, for example, one second. It’s not very likely that autosaves will take more than the default of 60 seconds, but you can increase the interval if you wish to save requests:

define( 'AUTOSAVE_INTERVAL', 120 ); // Seconds

Wrapping Up

There’s a lot of potential in wp-config that’s just waiting to be unlocked. I hope this tour has helped to highlight just some of what’s possible. In a future article, I’ll look into more of the advanced capabilities inherent in wp-config, including multisite installations, and debugging. I’ll also look into performance, including how to adjust memory limits, CRON issues, and environment types.

There are no doubt other treasures lurking in the official documentation, waiting to be discovered. What tips have you found for using wp-config? Let me know in the comments.

About the Author

Ross Wintle Software Developer

Ross is a software developer based in Swindon in the UK who specialises in WordPress and Laravel. He enjoys solving all kinds of complex, real world problems with code and loves helping other developers out. In a previous life he worked on aerospace systems; websites have always felt more down to earth!