Skip to content
ThemesIonic — home
WordPress Tutorials

wp-config.php Explained: Location, Constants and Hardening

One file holds the database credentials, the salts and every constant that changes how WordPress behaves. Know where it lives, what belongs in it, and how to keep it unreadable.

1 min read intermediate

What it is: the configuration file WordPress reads before anything else. It holds database credentials, security keys, and constants that switch features on and off. It is not in the WordPress repository, it is not overwritten by updates, and it is the first file to back up before editing.

Where to find it

The default location is the WordPress root, alongside wp-admin and wp-includes. Depending on the host that is public_html, www, httpdocs or htdocs.

WordPress also checks one level above the root, and some setups use that deliberately so the file sits outside the web-server document root. If it is not where you expect, look there before assuming it is missing.

If the file does not exist at all, WordPress shows the installation screen. wp-config-sample.php is the template: copy it, fill in the database details, and save it as wp-config.php.

What each block does

<?php
// Database connection.
define('DB_NAME',     'database_name');
define('DB_USER',     'database_user');
define('DB_PASSWORD', 'database_password');
define('DB_HOST',     'localhost');
define('DB_CHARSET',  'utf8mb4');

// Authentication keys and salts — unique per site.
define('AUTH_KEY',    '...');
define('SECURE_AUTH_KEY', '...');
// ... six more

// Table prefix.
$table_prefix = 'wp_';

// Debugging.
define('WP_DEBUG', false);

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

Everything you add belongs above the "stop editing" line. Below it, WordPress has already bootstrapped and the constant arrives too late.

Generate salts from the official secret-key service rather than inventing them. They must be long and random; their only job is to make stolen cookies useless.

Constants worth knowing

Constant Purpose
WP_DEBUG Turns on error reporting — see debug mode
WP_DEBUG_LOG Writes errors to wp-content/debug.log
WP_DEBUG_DISPLAY Whether errors are printed on screen
WP_MEMORY_LIMIT PHP memory for the front end — see memory limit
WP_MAX_MEMORY_LIMIT Memory for admin-side tasks such as image processing
WP_HOME / WP_SITEURL Overrides the URLs stored in the database
DISALLOW_FILE_EDIT Removes the built-in theme and plugin editors
DISABLE_WP_CRON Stops cron firing on page loads — see admin speed
WP_POST_REVISIONS Caps stored revisions per post
EMPTY_TRASH_DAYS How long trashed content is kept
WP_ENVIRONMENT_TYPE Marks the install as production, staging or local
WP_ALLOW_REPAIR Exposes the database repair page — remove after use

A practical production block:

<?php
define('WP_ENVIRONMENT_TYPE', 'production');
define('WP_DEBUG', false);
define('DISALLOW_FILE_EDIT', true);
define('WP_POST_REVISIONS', 5);
define('EMPTY_TRASH_DAYS', 14);
define('WP_MEMORY_LIMIT', '256M');

And a staging block:

<?php
define('WP_ENVIRONMENT_TYPE', 'staging');
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
@ini_set('display_errors', 0);

Never leave WP_DEBUG_DISPLAY on in production. Error output leaks paths and, occasionally, credentials.

Fixing URLs when you cannot log in

If a domain change locked you out of the admin, set the URLs here. These override the database values and take effect immediately:

<?php
define('WP_HOME',    'https://example.com');
define('WP_SITEURL', 'https://example.com');

Useful during a migration, but treat it as temporary — the database should hold the correct values eventually, per how to migrate a WordPress site.

Keep the file unreadable

wp-config.php contains your database password. Protect it accordingly.

File permissions. 640 or 600 is appropriate, owned by the account the web server runs as. Never 777.

Block direct access on Apache or LiteSpeed, in the root .htaccess:

<Files wp-config.php>
    Require all denied
</Files>

On Nginx, in the server configuration:

location = /wp-config.php {
    deny all;
}

Never leave backups next to it. Files named wp-config.php.bak, wp-config.old or wp-config.php.txt are served as plain text by most servers, and automated scanners look for exactly those names. If you need a copy before editing, download it and delete the server-side copy.

Keep it out of version control. If the site is in Git, wp-config.php belongs in .gitignore, with credentials supplied by environment variables or an untracked include.

Editing it safely

  1. Download a copy first — this file breaks the entire site when it is wrong.
  2. Edit in a plain-text editor, not a word processor.
  3. Save as UTF-8 without a byte-order mark. A BOM produces "headers already sent" errors and a blank page.
  4. Leave no blank lines or spaces after the closing ?>, or omit the closing tag entirely, which is safer.
  5. Upload and load the site immediately, so a mistake is caught while you still remember what you changed.

A syntax error here produces a white screen with no admin access. Recovery is to restore the copy you downloaded — the reason step one exists. If it happens and you have no copy, the symptoms and rescue routes are in the white screen guide.

Frequently asked

In the WordPress root, next to wp-admin and wp-includes — usually public_html, www or httpdocs. WordPress also looks one directory above the root, which some setups use to keep it outside the web root.
Every existing login cookie becomes invalid and all users are logged out. Nothing else breaks, which is why rotating salts is a standard step after a security incident.
Everything below it sets up WordPress itself. Custom constants must go above that line, or they are defined too late to affect anything.
Tagged Security

Related guides