- WordPress Pages Live in the Database, Not as HTML Files
- The wp_posts Table: Where All Page Content Is Stored
- Beyond wp_posts: The Other Database Tables That Matter
- The WordPress File System: Where Themes, Plugins, and Media Live
- How to Find Your WordPress Pages in the Database
- The Hidden Problem Nobody Talks About: Revision Bloat in wp_posts
- Conclusion
- Frequently Asked Questions
Where Are WordPress Pages Stored? Database and Files Explained


- WordPress Pages Live in the Database, Not as HTML Files
- The wp_posts Table: Where All Page Content Is Stored
- Beyond wp_posts: The Other Database Tables That Matter
- The WordPress File System: Where Themes, Plugins, and Media Live
- How to Find Your WordPress Pages in the Database
- The Hidden Problem Nobody Talks About: Revision Bloat in wp_posts
- Conclusion
- Frequently Asked Questions
WordPress pages are stored in a MySQL database, specifically inside a table called wp_posts. That’s the direct answer. Most people expect to find their pages as HTML files sitting in a folder on the server, but that’s not how WordPress works, and understanding the difference matters a lot when you’re troubleshooting, migrating, or backing up a site.
Here’s the thing: we’ve built and maintained dozens of WordPress and WooCommerce projects, and database confusion is one of the most common reasons small problems turn into big ones.
In this guide, you’ll learn exactly where WordPress stores your pages and other content, what role the file system plays, how to find your pages in the database, and why post revision bloat is a silent performance issue most guides never mention.
WordPress Pages Live in the Database, Not as HTML Files
If you’ve ever opened your hosting file manager or connected via FTP looking for a file called about-us.html, you already know it doesn’t exist. That’s not a bug. It’s how WordPress was designed.
WordPress is a dynamic content management system. When a visitor loads a page on your site, WordPress doesn’t serve a pre-built HTML file. Instead, it runs a PHP script, connects to a MySQL database, pulls the relevant content, combines it with your theme’s layout files, and builds the HTML on the fly before sending it to the browser.
This process happens in milliseconds. From the visitor’s perspective, the page loads normally. Behind the scenes, though, every page request triggers a database query.
What This Means in Practice
This dynamic system gives WordPress enormous flexibility. You can change your theme without touching a single piece of content. You can update a page from any device, anywhere, and the change is live immediately.
But it also means your site has a single point of failure. If the database connection breaks, WordPress can’t retrieve any content. Your site won’t show a stale version. It will show an error. If you’ve ever seen “Error establishing a database connection” on a WordPress site, now you know why that error wipes out the entire site rather than just one page.
This is why database backups aren’t optional. They’re the only backup that actually matters.
The wp_posts Table: Where All Page Content Is Stored

The core of WordPress page storage is a database table called wp_posts. This is where the actual content lives: the title, the body text, the publication date, the author ID, the URL slug, and the publishing status.
Here’s what surprises many people: pages, blog posts, WooCommerce products, navigation menu items, and media attachments all live in this same table. WordPress doesn’t use a separate table for each content type. Instead, it uses a column called post_type to tell them apart.
When you create a WordPress page, it gets saved as a row in wp_posts with post_type = 'page'. A blog post gets post_type = 'post'. A WooCommerce product gets post_type = 'product'. Everything shares the same structure.
The most important columns in wp_posts are:
post_title: the page titlepost_content: the full body contentpost_status: publish, draft, trash, private, pendingpost_type: page, post, product, attachment, revision, and morepost_name: the URL slugpost_author: the user ID of whoever created itpost_date: the creation timestamp
How Gutenberg Stores Page Content
One thing no basic guide covers: the Gutenberg block editor doesn’t store content as plain HTML inside post_content. It wraps every block in HTML comment delimiters that look like this:
<!-- wp:paragraph --> <p>Your text here.</p> <!-- /wp:paragraph -->
This means the raw content stored in wp_posts includes those comment markers. WordPress uses them to reconstruct the block structure when you open the page editor.
If you’re reading post_content directly from the database in a custom query, you’ll see them. They don’t affect the front end — WordPress strips them before rendering — but they’re worth knowing about if you’re working with the database programmatically.
If you want to learn more about how to add pages in WordPress through the admin dashboard, that’s a good starting point before you get into database-level work.
Beyond wp_posts: The Other Database Tables That Matter

wp_posts stores the core content, but it doesn’t hold everything associated with a page. Several other tables fill in the gaps.
wp_postmeta
This is where per-page metadata lives. Every row in wp_postmeta is linked back to a specific page via its post_id. Common things stored here include:
- SEO plugin data: title tags, meta descriptions, and focus keywords set by plugins like Yoast or Rank Math
- Page template: which custom template the page uses, if not the default
- Featured image ID: a reference to the attachment record in
wp_posts - Custom fields: any extra data added via the editor or programmatically
- Page builder data: Elementor and other builders often store their own serialized layout data here
The wp_postmeta table is often larger than wp_posts on sites that use page builders or lots of custom fields, because the metadata rows multiply fast.
wp_options
This table stores site-wide settings rather than per-page data. Your site title, tagline, active theme, active plugins, permalink structure, and widget settings all live here. It’s also where many plugins dump their configuration data, which is why the wp_options table can balloon on plugin-heavy sites.
wp_users and wp_usermeta
These store registered user accounts and their related metadata. The author ID is stored on each page in wp_posts points to a row in wp_users.
wp_terms, wp_term_taxonomy, wp_term_relationships
These three tables handle categories, tags, and custom taxonomies. Pages don’t typically use categories, but custom post types and posts do.
wp_comments and wp_commentmeta
All comments and their metadata live here, linked back to posts and pages via a comment_post_ID column.
The WordPress File System: Where Themes, Plugins, and Media Live
The database handles content. The file system handles everything else: how content looks, what functionality is available, and where uploaded media files are physically stored.
wp-content/themes
This folder contains your installed WordPress themes. When WordPress receives a request for a page, it uses a logic called the template hierarchy to decide which PHP file to use for rendering that page. For a standard page, it will look for a file called page.php in your active theme. If that doesn’t exist, it falls back to singular.php, then to index.php.
This is why you can switch themes without losing a single word of your content. The content is in the database. The theme just provides the container that wraps around it.
wp-content/plugins
Installed plugins live here as folders. Their PHP files are what add functionality to your site. Most plugins also store their data in the database tables described above, not in these folders.
wp-content/uploads
Media files are stored here, organized into year and month subfolders. When you upload an image and add it to a page, the physical file lands in something like /wp-content/uploads/2025/03/your-image.jpg. But the reference to that image, including its attachment details and alt text, gets stored as a row in wp_posts with post_type = 'attachment'.
So even the media has a split existence: the file itself on the server, the record about it in the database.
wp-config.php
This file sits in your WordPress root directory. It’s the bridge between WordPress and the database. It contains the database name, username, password, and host. Without it, or with a wrong value in it, WordPress can’t connect to the database, and the entire site fails.
If you’re working on setting up permalinks in WordPress, this file structure becomes directly relevant because the permalink settings are stored in wp_options and depend on WordPress being able to reach the database.
How to Find Your WordPress Pages in the Database

You can view and inspect your page content directly using phpMyAdmin, a tool based on web most hosts include in their control panel.
- Step 1: Log in to your hosting control panel (cPanel or equivalent) and open phpMyAdmin.
- Step 2: In the left sidebar, select your WordPress database. The name is listed in your
wp-config.phpfile underDB_NAME. - Step 3: Find and click the
wp_poststable. Your database prefix might differ — if you didn’t use the default setup, it could be something likemysite_poststhat instead. - Step 4: Click “Browse” to see all the rows. You’ll see posts, pages, revisions, attachments, and menu items all mixed.
- Step 5: To filter by pages only, click the “Search” tab and set
post_typetopagewith the equals operator. This returns only your actual pages. - Step 6: Click any row to view its full content, including the raw
post_contentvalue.
A word of caution: editing content directly in phpMyAdmin is risky. There’s no undo, no autosave, and no revision history. For daily edits, always use the WordPress admin dashboard. Direct database edits are for edge cases only, such as recovering content from a corrupted install.
The Hidden Problem Nobody Talks About: Revision Bloat in wp_posts
Here’s something that almost every “where are WordPress pages stored” guide skips entirely: every time you save a draft or update a page, WordPress creates a new row in wp_posts with post_type = 'revision'.
That revision is a full copy of the page content, then. Save a long page ten times, and you’ve got ten near-identical rows sitting in your database.
On a new site with a few pages, this doesn’t matter. On an active WooCommerce store or a content-heavy blog that’s been running for a few years, it absolutely does. Having built and maintained 20+ WordPress and WooCommerce plugins, we’ve seen wp_posts tables balloon to hundreds of megabytes on active stores. The culprit is almost always uncontrolled revisions.
Why Revision Bloat Is a Real Problem
A larger database takes longer to query. Backups take longer. Migrations are slower. And if you’re on a shared hosting plan with database size limits, you can hit those limits faster than you’d expect.
How to Limit Revisions
You can cap the number of revisions WordPress keeps by adding one line to your wp-config.php file:
define( 'WP_POST_REVISIONS', 3 );
This tells WordPress to keep a maximum of three revisions per post or page. Older ones get deleted automatically. Setting it to false disable revisions entirely, though keeping a few is useful for recovery.
How to Clean Up Existing Revisions
For revisions that already exist, two approaches work well:
- WP-Optimize plugin: A free plugin that can delete all existing revisions in bulk with a few clicks. Good option for non-developers.
- WP-CLI: If you have server command-line access, you can run
wp post delete $(wp post list --post_type='revision' --format=ids)to delete all revisions at once.
Cleaning up revisions is one of the simplest database optimization steps you can take, and it’s something our WordPress development services team handles as part of any performance audit.
Conclusion
WordPress pages are stored in a MySQL database, inside the wp_posts table, with supporting metadata in wp_postmeta and site-wide settings in wp_options. The file system handles themes, plugins, and media, but the content itself lives entirely in the database. That means your database is the single most important thing to back up on any WordPress site.
Understanding where WordPress pages are stored isn’t just a trivia question. It shapes how you approach backups, migrations, troubleshooting, and performance. The revision bloat issue alone catches a lot of experienced site owners off guard. A quick check of your wp_posts table and a single line in wp-config.php can save you from a slow database and a painful migration down the road.
Need help with a WordPress project that’s grown more complicated than expected? Take a look at our WordPress development services.
Frequently Asked Questions
Q1. Can WordPress run without a database?
No. WordPress requires an active MySQL (or MariaDB) database connection to function. Every page request triggers a database query to retrieve content. Without it, the site throws a connection error and nothing loads. Static site generators like Jekyll work without a database, but WordPress is not one of them.
Q2. What is the difference between wp_posts and wp_postmeta?
wp_posts stores the core content of each page or post: the title, body, slug, status, and type. wp_postmeta stores additional data associated with a specific post, such as SEO fields, featured image references, custom field values, and page builder data. Every row in wp_postmeta links back to a row in wp_posts via a post_id column.
Q3. Does WordPress delete revisions automatically?
By default, WordPress keeps all revisions and never deletes them. They accumulate silently until you either add a WP_POST_REVISIONS limit to wp-config.php or use a plugin or WP-CLI to clean them up manually. Unlimited revisions are the default behaviour even on large sites, which is why revision bloat is so common.
Q4. Where are WordPress media files stored?
The physical media files are stored in the /wp-content/uploads/ directory on the server, organized into year and month subfolders. However, the metadata for each file, including the alt text, file URL, attached page, and description, is stored in the wp_posts table with a post_type of ‘attachment’.
Q5. If I switch themes, do I lose my page content?
No. Page content is stored in the database, completely separate from the theme files. Switching themes changes the layout and design, not the content. Your pages, posts, and custom content will all remain intact. This separation between content and presentation is one of WordPress’s core design principles.

Ekta Lamba
Ekta Lamba is a tech writer at DevDiggers focused on making WordPress and WooCommerce straightforward for non-developers. She covers plugin errors, platform updates, and WordPress basics, written so readers can follow along without a second tab open to translate the jargon.
Join thousands of readers getting smarter every week.

Leave a Reply