DiggingIntoWordPress

by Chris Coyier & Jeff Starr

Pimp your wp-config.php

Posted by on

Easily, the most important file in your WordPress installation is the wp-config.php file. It serves as your site’s base configuration file, controlling key aspects of WordPress’ functionality and enabling WordPress to do mission-critical stuff like connect to the database. Without wp-config.php, WordPress simply won’t work. So whenever you install WordPress, one of the first things to do is pimp your wp-config.php with some custom WP configuration tricks.

And it’s pretty easy too – just get your database credentials in place and you’re done. The other settings available in the wp-config.php file will work just fine using the default values, but there are some cool things you can do to customize functionality, tighten security, and improve performance. Once you get the basics of wp-config.php, you can really pimp it out to do some awesome stuff. We’ll break this down into four basic parts:

There is no wp-config.php..

When you first download WordPress, the wp-config.php file isn’t included. Instead, you get a file named “wp-config-sample.php” (located in the root install-directory) that contains everything you need. Just rename the file to “wp-config.php” and delete the wp-config-sample.php file from the server if it’s already there. Here is a visual:

[ Rename the file ]

With the wp-config.php file now ready to go, it’s time to protect it..

Protect wp-config.php

The first thing you want to do with wp-config.php is protect it. Here is a great way to secure the file using .htaccess:

<Files wp-config.php>
	Order Allow,Deny
	Deny from all
</Files>

This code should be placed in an .htaccess file located in the directory that contains your wp-config.php file.

[ Use the same directory ]

Once the .htaccess file is in place, ensure that permissions are chmod 640 for both files. This setting returns a “403 Forbidden” error to all external requests. Combining proper file permissions with .htaccess protection is an excellent way to secure your wp-config.php.

Main Configuration Settings

Now that wp-config.php is secure, it’s time to add the required database information and then customize for optimum performance. This section covers the first four configuration settings that you’ll find already included in your wp-config.php. Then in the next section, we’ll explore some awesome techniques and really pimp things out.

1) Database credentials

The first and only required step is to add your database credentials. This should appear after the PHP comments near the top of the file:

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'database_name_here');

/** MySQL database username */
define('DB_USER', 'username_here');

/** MySQL database password */
define('DB_PASSWORD', 'password_here');

/** MySQL hostname */
define('DB_HOST', 'localhost');

/** Database Charset to use in creating database tables. */
define('DB_CHARSET', 'utf8');

/** The Database Collate type. Don't change this if in doubt. */
define('DB_COLLATE', '');

For most servers, you’ll need only the first three bits of information: database name, username and password. If WordPress can’t connect after that, then you may need to change the hostname to whatever your host tells you. Only fiddle with the last two items – charset and collate – if you have need and know what you’re doing.

2) Authentication Unique Keys and Salts

Next up is a section for key/salt definitions. By default it looks like this:

/**#@+
 * Authentication Unique Keys and Salts.
 *
 * Change these to different unique phrases!
 * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
 * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
 *
 * @since 2.6.0
 */
define('AUTH_KEY',         'put your unique phrase here');
define('SECURE_AUTH_KEY',  'put your unique phrase here');
define('LOGGED_IN_KEY',    'put your unique phrase here');
define('NONCE_KEY',        'put your unique phrase here');
define('AUTH_SALT',        'put your unique phrase here');
define('SECURE_AUTH_SALT', 'put your unique phrase here');
define('LOGGED_IN_SALT',   'put your unique phrase here');
define('NONCE_SALT',       'put your unique phrase here');

/**#@-*/

The eight definitions should be replaced with values generated via the official WordPress.org secret-key service. Visit that link, refresh the page a few times, and paste the results into place, like so:

/**#@+
 * Authentication Unique Keys and Salts.
 *
 * Change these to different unique phrases!
 * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
 * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
 *
 * @since 2.6.0
 */
define('AUTH_KEY',         ')` 4yDGc w=*:l8@RD167k0+/+@+rgo(mI-x<_~.=WtCm[qD8<3S)TsR}K~bMLNT');
define('SECURE_AUTH_KEY',  'zO?htRkV.k[vBqn<+.,lorpObkc?@|Vi+8`w=A9,|FjPB&5`5|9<[&&WaUB.pwTS');
define('LOGGED_IN_KEY',    'jtr|J-/.-:6CVh*8h.~bNzc3^#A9@hB9G3E/fx/>k)pmTHbES5^Rq(+EINCW w>8');
define('NONCE_KEY',        'O2Vz+br+`6MqQVv1{-g}sy -CF8M/tldEyWV[W}dnebd7m$6.P,m+.G6Ec]{V@Kl');
define('AUTH_SALT',        '>x,, 8wMLIJCH}i94Ib+}~lR%r_))x@LU3~YJwCok++xaSVE@[My(zAg!Fpi4{NR');
define('SECURE_AUTH_SALT', '7[,gAJ#TQmsw:$!R-n-r%4<UvG7%|-7&jt4]XS-[KX&O)|H,err]<{EuFnmP3,M}');
define('LOGGED_IN_SALT',   '9dJP8uW2E2&.^a|@I|[?qbY%z:&jgnH<OUg+t6Tks,Hox=M@~yx+b;~zU)436q=+');
define('NONCE_SALT',       '=Xv~8+!>l:wy`~w0U-6wO2lmG8l5Xg21$J59T$T~)(h5m<5`|/|dVN{j[80QMV60');

/**#@-*/

Don’t use the example keys shown here though – the whole idea is to specify unique phrases to improve security. And it’s totally fine to replace these keys at any time – the worst that will happen is that currently logged-in users will need to log in again.

At this point, we have our database credentials and secret keys all ready to go. Next we want to further improve security by specifying a unique database prefix.

3) WordPress Database Table prefix

WordPress is a huge target for malicious scripts, hacks, and spam. One of the best ways to secure your WordPress database is to change the default table prefix. The default value, as seen below, is “wp_”:

/**
 * WordPress Database Table prefix.
 *
 * You can have multiple installations in one database if you give each a unique
 * prefix. Only numbers, letters, and underscores please!
 */
$table_prefix  = 'wp_';

This works, but as the default value, it is heavily targeted by malicious scripts and bad bots. Changing it to something unique essentially immunizes it against automated attacks on anything prefixed with wp_. The more random and unique the better, like a password: “h7G3vcDEo3jDf_” would be a good example. Note that ending the string with an underscore or some other easily recognizable character is a good way to keep things readable and easy to use.

4) WordPress Localized Language

By default WordPress uses the English language, but you can use any available language by following these steps. As a part of that process, you’ll specify your language in this part of the wp-config.php file:

/**
 * WordPress Localized Language, defaults to English.
 *
 * Change this to localize WordPress.  A corresponding MO file for the chosen
 * language must be installed to wp-content/languages. For example, install
 * de.mo to wp-content/languages and set WPLANG to 'de' to enable German
 * language support.
 */
define ('WPLANG', '');

It’s pretty straightforward: if nothing is specified (as is seen here), English is used; otherwise, you include the .mo language file you are using for the translation.

Additional Tips and Tricks

Now that you’ve got the database connection, security keys, table prefix, and language definition dialed in you’re ready to rock. Most WordPress sites are in great shape at this point, but there is much more that we can do with wp-config.php to maximize performance and make our lives easier.

Pimping Post Revisions

Recent versions of WordPress provides a post-revisioning system that enables users to save different versions of their blog posts and even revert to previously saved versions if necessary. Regardless of how much you do or do not despise this amazingly awesome feature, here are a couple of configurational definitions that may prove useful for you:

// Limit the number of saved revisions
define('WP_POST_REVISIONS', 3); // any integer, but don't go crazy

// Disable the post-revisioning feature
define('WP_POST_REVISIONS', false); // kill the bloat

Specify the Autosave Interval

In a similar vein as the post-revisioning feature is WordPress’ actually useful Autosave functionality. By default, WordPress saves your work every 60 seconds, but you can totally modify this setting to whatever you want. Don’t get too crazy though, unless you want to stress-out your server ;)

define('AUTOSAVE_INTERVAL', 160); // in seconds, don't go nuts

Automated Trash

Since WordPress 2.9, we’ve had the “Trash” feature to help prevent accidents. So now instead of deleting stuff like posts and comments, you send them to the Trash. By default WordPress deletes the Trash every 30 days, but you can set it to whatever you want by adding a line like this to wp-config.php:

define('EMPTY_TRASH_DAYS', 7); // empty weekly

To ride bareback without the safety net, you can disable the Trash feature by specifying a zero value:

define('EMPTY_TRASH_DAYS', 0); // disable trash

By disabling Trash, you’ll be deleting stuff permanently the first time, just like way back in the day.

Automatic Database Repair

WordPress 2.9 also gave us automatic database repair, which enables you to repair and optimize your database even when not logged in. This functionality should be used on an as-needed basis by first adding the following snippet to wp-config.php:

define('WP_ALLOW_REPAIR', true);

With that in place, visit the following URL to open the “Database Repair” page:

http://example.com/wp-admin/maint/repair.php

There you’ll be able to optimize and repair your database without needing to log in to WordPress. Important: While you have WP_ALLOW_REPAIR set in wp-config.php, the Database Repair page is openly accessible by anyone who finds it. So definitely remove the line to disable the auto-repair functionality after you are done using it.

Block External Requests

If you need to prevent WordPress from making external requests, add this snippet to wp-config.php:

define('WP_HTTP_BLOCK_EXTERNAL', true);

This will prevent things from happening that normally happen, like updates, dashboard feeds, and data reporting. Fortunately, it’s easy to whitelist (allow access) anything that is needed. Here is an example where we grant access to pingomatic.com:

define('WP_ACCESSIBLE_HOSTS', 'rpc.pingomatic.com');

Blog Address and Site Address

By default, these two configurational definitions are not included in the wp-config.php file, but they may be added to improve performance. These two settings were introduced in WordPress version 2.2 and override the database value without actually changing them. Example:

define('WP_HOME', 'http://digwp.com'); // no trailing slash
define('WP_SITEURL', 'http://digwp.com');  // no trailing slash

These settings should match those specified in your WordPress Admin. Once you set them in wp-config.php, they will be “grayed-out” when displayed in the Admin.

Debugging WordPress

Since WordPress version 2.3.1, users have been able to display certain errors and warnings to help with the debugging of their site. As of WordPress version 2.5, enabling error reporting raises the reporting level to E_ALL and activates warnings for deprecated functions. By default (i.e., if no definition is specified in the wp-config.php file), error reporting is disabled.

define('WP_DEBUG', true); // debugging mode: 'true' = enable; 'false' = disable

Adding that snippet to wp-config.php tells WordPress to display warnings and error messages with your web pages. This functionality is extremely useful but infrequently used by plugin and theme developers. If you’ve never enabled debugging, you’re in for a surprise – lots of errors even with some of the most popular plugins.

Error Log Configuration

Here is an easy way to enable basic error logging for your WordPress-powered site. Create a file called php_error.log, make it server-writable, and place it in the directory of your choice. Then edit the path in the third line of the following code and place into your wp-config.php:

@ini_set('log_errors','On');
@ini_set('display_errors','Off');
@ini_set('error_log','/home/path/domain/logs/php_error.log');

Error logs are powerful tools for keeping an eye on things and expediently resolving issues. It’s awesome that WordPress makes this so easy. We cover this in greater depth along with a couple of other methods in this post.

Increase PHP Memory

If you are receiving error messages telling you that your “Allowed memory size of xxx bytes exhausted,” this setting may help resolve the issue. As of WordPress version 2.5, the WP_MEMORY_LIMIT definition enables you to specify the maximum amount of memory that may be used by PHP. Here are some examples:

define('WP_MEMORY_LIMIT', '64M');
define('WP_MEMORY_LIMIT', '96M');
define('WP_MEMORY_LIMIT', '128M');

By default, WordPress will automatically attempt to increase PHP memory up to 32MB, so this setting is only needed for values higher than 32MB. Note that some web hosts disable your ability to increase PHP memory, so you may need to ask (or beg) for them to do it.

More info, tips and tricks for wp-config

For more information on the wp-config.php file, check out the WordPress Codex. We also have some awesome wp-config tricks and wp-config optimization tips for your WordPress enjoyment :)

46 Responses

  1. Some useful info, never really looked into the wp-config before.

  2. If I set permissions to 640 then I can’t access the site at all

    • Yikes – what setting works for you?

      • Unfortunately on some servers 640 will be too restrictive. Even 644 may be too restrictive. It also depends on ownership. If Apache owns the file, and you have it set to 640, your FTP account might be the 4 or the 0, which is no fun. Our rule of thumb is to chmod the file as low as you can, but ultimately it is at the complete mercy of server setups, some of them not optimal.

        • My installation doesn’t work with 640 or 644…what do you recommend I change it to? I don’t know much about this :(

        • Definitely ask your host about this. They would know best. Then double-check their response online to make the best decision.

      • 644 works fine

      • wp-config is fine with 640 on my server, but htaccess would only allow with 644.

        Great tips and advice, thanks.

        D.

    • Richard August 25, 2010

      Same result here. I had to go with 644. Seems the Public Read permission needs to be available?

    • Exactly the same result for me.
      I had to revert back to 644

      • Same here. 640, is a no go. And 644 works. But I get a blank page, rather than Forbidden error. Which really doesn’t matter much, the file isn’t accessible, still. I don’t think. All my installations, over two hosts, are the same. Anyone else experiencing this?

      • Jeff I get similar here as well…

        Except I can use 640 on the wp-config but have to use 644 on the .htaccess

        Thanks for a great post though, and of course with V3 ‘Digging’ – You guys have produced the best WP book out there – But hey I bet you know that already…lol

  3. useful tips,i like it
    and my .htaccess also have to be set to 644, 640 won’t work

  4. Hi Jeff,

    WP_HOME and WP_SITEURL sound really useful for when you’re restoring the database from the live site to a localhost installation. That’ll save you from having to edit the DB and change these settings (which annoys me everytime).

    Thanks!

  5. Incontournable post de sécurité et personnalisation WordPress.
    Bravo !

  6. lorenzo August 26, 2010

    Great Tut, thanks to share it with us

  7. Thanks a lot for this, i’ll test the htaccess/chmod on differents wp sites asap.

  8. quick question on the auth keys/salts. Is https://api.wordpress.org/secret-key/1.1/salt/ a new set of keys for use with WordPress 3.x?

    I only remember getting 4 unique keys from https://api.wordpress.org/secret-key/1.1/ in the past, now there are 8.

    Just curious.

  9. Are there any benchmarks available to prove that setting WP_HOME and WP_SITEURL increases performance? WP is going to query everything in that table anyway; I don’t see how it would help.

  10. What happens to an existing blog if you change the table prefix?

    Also, I noticed that with 1-click upgrades you don’t get the new versions of wp-config. Can you just add the 4 new SALT keys to the existing keys or do you have to generate the 8 keys together?

    Thanks!

    • I found the article on changing the table prefix on an existing blog here

      http://wpcanada.ca/2009/11/21/how-to-change-wordpress-table-prefix/

      Very good, step by step process.
      No answer yet on the keys.

    • Pretty certain that simply changing the table prefix in wp-config will break any existing installation.

      $table_prefix should be set prior to installing your site (i.e. prior to running the install.php script).

      You still can change the table prefix for an existing WP installation; however, it will take more steps because any existing table name will need to be manually changed (via: Export->Find and Replace->Drop Tables->Import OR the method cited in Wes Hopper’s reply). Any records within the tables containing the old table names will also need to be changed.

      One note of caution; some records will be serialized (i.e. unreadable to humans without decoding), so even if you search for the old table names within certain records, they may not come up and your website will break anyway.

      Possible work-around; if someone can confirm that WordPress does not store any records with table names in serialized format by default, it may be possible to avoid breakage by first enabling the default theme and disabling any plugins. Although, I’m not sure how many themes and plugins are properly coded for this scenario. I know that upon deactivation, the register_deactivation_hook should be used, but there are probably instances where reactivating certain plugins/themes will also break things.

      Recently had a problem moving an installation because the blog_info option record is serialized. Fortunately, modifying this on the settings page prior to the database export solved this.

      Source:
      Installing_Multiple_Blogs
      Moving_WordPress

      • Good points, and I would add emphasis on existing installations. Changing table prefixes is possible after install, but is infinitely easier doing it during the installation process. For the serialized data, I have never had a problem and have changed many prefixes post-install.

    • @Wes Hopper: I would just generate a complete new set of keys. The worst that will happen is users will have to log in again, which they would have to do anyway even if you just added the 4 new keys.

  11. Perfect timing for this post! I just attended a webinar about all this, but it went a little over my head. This is just what I needed to bring it into clearer focus :-) Thanks!

  12. Awesome tips. Thank you!

  13. 640 will not work… thats very restrictive.

  14. Hi

    Very useful tips.
    I have used your htaccess tips in one of my project.

    Thanks for this.

  15. Honestly, I cannot forsee anyone doing this for anything other than malicious reasons, but for knowledge’s sake, look up Windows RAS. Very easy to setup.

  16. Excellent Tips… Will use this in future projects..

    Thank you guys.. Keep us Informed, Keep us Inspired.

  17. Cristian Giordano August 28, 2010

    This is a fantastic resource. Am bookmarking, and tweeting this.

    Thanks for this.

    :)

  18. Sam Stevens August 28, 2010

    Since Version 2.6, wp-config.php can be moved to the directory directly above the WordPress application directory, ie. outside your web root.

    • Yes, very true – thanks for the reminder :)

    • Good point. Since before that I’ve left wp-config.php as a most empty file that just requires another file outside the web root directory, but it’s easier to just move the whole file.

  19. Hello, these are very helpful but a bit intimidating. I am doing a WordPress site about police brutality and expecting a lot of attacks on it. Do you ever do consulting to make sure set up/security settings are set up well? Better yet, consulting on checking everything?! Of course I would work through the book first, but some of this is scary! Of course I am happy to pay your full rate and minimum hours. Thank you very much for these tutorials and CSS Tricks, they are so great.

  20. Thanks for the tips. We could also use a company to handle site maintenance & such for emergencies & for that which I am not able to handle. I will be in touch.

    In regards to securing the wp-config.php via .htaccess & file permissions…

    The Codex says to set the permissions to 750. What do you think of that? At the Boston WP Camp, it was suggested to set all files to 644 & all folders to 755. What’s your view on that? Sorry, I don’t mean to challenge, I am just trying to figure all of this out :-)

    About the .htaccess at the root level…I cannot have more than one .htaccess file in the same directory, correct?

    So, for those who cannot set their permissions to 640 but rather 644, that means that the all can read a particular file. I read somewhere today that because of this, passwords can also be seen in the wp-config.php file. Is this true & if so, what to do? Doesn’t sound right to me…

    Thanks!

  21. oops..forgot to mention that the Codex says set to 750 when on a shared server…

  22. Many thanks for this very handy article.
    I’ll try to change table names … This really sound a very good idea !

  23. Hello,

    My (ex)co-partner of a blog stole the email address registered for the blog and obviously the blog itself.
    I was wondering if it is possible to extract somehow the wp-config.php file in order to see the password?
    (I just want to delete some personal data because I am aware that I cannot retrieve the email address)

    Thanks!

  24. I really enjoy the layout of your blog. Did you use an existing theme or custom designed it yourself?

  25. I have a long ways to go with learning these codes I did change some things when I set up my blog I still have wp there but my password and username are not wp-admin like a bunch of other wp sites I have seen. What I am wanting to know is in the near future i am going to want to start another wp blog for wp is very easy for me to use since I am not a computer guru I had to have something easy. Anyhow I have found out there is a wp multi site option where you can have a bunch of sites on one wordpress blog is that right? If so how hard is that to set up and make safe?

  26. A lot of useful stuff in this post, especially Post Revisions, Autosave Interval, which drives me crazy some days. Blog Address and Site Address will make using a development site MUCH MUCH easier. So i thank you in advance for that puppy.

  27. Be very cautious when editting, wp-config.php minor things can cause, severe issues. I’ve recently run into an issue with a trailing slash caused by WP_HOME variable e.g.:

    define('WP_HOME', 'http://digwp.com'); // no trailing slash.

    It took me a while to solve the problem.

Comments are closed. Contact us with any critical information. Thank you!

Code is poetry