Where Are WordPress Posts and Pages Stored? (SQL Lookup Guide)
WordPress posts and pages live in one table, wp_posts, split by post_type. Where your content, metadata and Rank Math titles sit, with the SQL to find them.

WordPress posts and pages are stored in the same database table, wp_posts, and told apart by the post_type column (post vs page). Their extra data — including SEO titles like rank_math_title — sits in wp_postmeta. The database itself is held by MySQL, not in your public_html folder; your images, themes, and plugins live on disk in /wp-content.
On this page
- TL;DR
- How does WordPress store your content?
- Where are WordPress posts and pages stored in the database?
- What columns does the wpposts table hold?
- Where is post metadata stored? (wppostmeta)
- What are all the default WordPress database tables?
- Where does the database physically live? (not in publichtml)
- How to access your WordPress database via phpMyAdmin
- Useful SQL queries to find and manage your content
- Where are WordPress files stored?
- How to back up your WordPress database
- Final take
- Common questions
Short answer: your posts and pages are not files.
They are rows in one database table called wp_posts, and WordPress tells them apart with a single column, post_type. That is the whole answer. The rest of this page is where each piece actually sits.
I have migrated and debugged enough WordPress sites to live inside this database. When a migration breaks, when a plugin mangles a thousand titles, or when I need to bulk-edit content the admin will not let me touch, this is where I go.
So this is not the textbook tour. It is where things actually are, and the SQL I actually run to find them.
How does WordPress store your content?
WordPress is database-driven. It does not save each post as an HTML file on disk. Instead it stores your content as data in a MySQL or MariaDB database and builds the page fresh on every request.
That is why you cannot find a "posts" folder on your server. The text of every post and page sits in database tables, and your theme assembles it into HTML when someone visits.
Two things live in two different places, and mixing them up is the root of most confusion:
- Content (the words, titles, status) → the database, managed by MySQL.
- Files (images, themes, plugins) → the disk, in your
/wp-contentfolder.

Where are WordPress posts and pages stored in the database?
Both posts and pages live in the wp_posts table. There is no separate table for pages. The post_type column is what separates them:
| post_type | What it is |
|---|---|
post | A blog post |
page | A page |
attachment | A media upload (the file is on disk; this is the record) |
revision | A saved revision of a post or page |
nav_menu_item | A single item in a navigation menu |
product | A WooCommerce product (added by the plugin) |
So "where are my pages stored" and "where are my posts stored" have the same answer: wp_posts, filtered by post_type.
One table, one column tells them apart. This one query lists every published post:
SELECT ID, post_title, post_date, post_name
FROM wp_posts
WHERE post_type = 'post' AND post_status = 'publish'
ORDER BY post_date DESC;Swap 'post' for 'page' and you have every page. The post_name column, by the way, is your URL slug.
What columns does the wp_posts table hold?
The wp_posts table has 23 columns. You rarely need all of them, but these are the ones I reach for most:
ID: the unique post ID (the number in?p=123and in most other tables).post_title,post_content,post_excerpt: the actual content.post_status:publish,draft,pending,private,trash,auto-draft.post_type: what kind of content it is (see the table above).post_name: the slug used in the URL.post_author: the user ID, which joins towp_users.post_parent: the parent post/page ID, used for page hierarchy and for attachments.post_date/post_modified: when it was published and last changed.post_mime_type: only used for attachments, where it stores the file type likeimage/jpeg.
If you want a quick map of what is in your site, count everything by type:
SELECT post_type, COUNT(*) AS total
FROM wp_posts
GROUP BY post_type
ORDER BY total DESC;That one line tells you how many real posts you have versus how many revisions and auto-drafts are quietly bloating the table.
On an old site, the revision count is usually the shock.
Where is post metadata stored? (wp_postmeta)
The wp_posts row holds the core content. Everything extra, the featured image link, the SEO title, the custom fields, lives in wp_postmeta.
It is a simple key-value table with four columns: meta_id, post_id, meta_key, and meta_value. Each row attaches one piece of data to one post by its post_id.
If a value is not in wp_posts, it is almost always in wp_postmeta.

To see everything stored for a single post:
SELECT meta_key, meta_value
FROM wp_postmeta
WHERE post_id = 123;The featured image is stored here too, as a meta_key of _thumbnail_id pointing at the attachment's ID, not the image URL itself.
How to find your Rank Math SEO title and description in the database
This is the question that brings most people to this table, so let me answer it directly. Your SEO plugin does not have its own table. It writes into wp_postmeta.
For Rank Math, the SEO title and meta description are stored as two meta_key rows: rank_math_title and rank_math_description. To pull every custom SEO title on the site:
SELECT p.ID, p.post_title, m.meta_value AS seo_title
FROM wp_postmeta m
JOIN wp_posts p ON p.ID = m.post_id
WHERE m.meta_key = 'rank_math_title';Change rank_math_title to rank_math_description for the meta descriptions. If you use Yoast instead, the equivalent meta_key values are _yoast_wpseo_title and _yoast_wpseo_metadesc.
This is how you audit or bulk-fix SEO meta across hundreds of pages at once. Just preview with a SELECT first, then turn it into an UPDATE, and treat the SEO meta itself as a technical SEO asset worth getting right, not a throwaway field.
Back up before you write to the database
A SELECT is safe: it only reads. An UPDATE or DELETE is not. It writes instantly, ignores the trash, and there is no undo. Export the database first (see the backup section below), and run the SELECT version of any query before you change SELECT to UPDATE.
What are all the default WordPress database tables?
A fresh WordPress install creates 12 tables (your wp_ prefix may differ). This is the whole wordpress database structure in one view:
| Table | What it stores |
|---|---|
wp_posts | Posts, pages, attachments, revisions |
wp_postmeta | Extra data for each post (SEO meta, custom fields) |
wp_comments | Comments |
wp_commentmeta | Extra data for each comment |
wp_users | User accounts |
wp_usermeta | User profile data and preferences |
wp_options | Site-wide settings (site URL, active plugins) |
wp_terms | Categories and tags |
wp_termmeta | Extra data for terms |
wp_term_taxonomy | Whether a term is a category, tag, or custom |
wp_term_relationships | Which posts belong to which terms |
wp_links | The old blogroll (legacy, rarely used) |
Plugins add their own tables on top of these, but every core piece of content traces back to this set.
Where does the database physically live? (not in public_html)
This trips up almost everyone, so it is worth being exact. Your WordPress files live in public_html (or www, or htdocs).
The database does not.
The database is run by a separate service, MySQL or MariaDB. Its raw data files sit in the MySQL data directory, usually /var/lib/mysql on a Linux server, which is outside your website folder, and on many managed or cloud hosts on a completely different server.
You almost never touch those raw files. You reach the database through a tool instead: phpMyAdmin, Adminer, your host's database manager, or the mysql command line over SSH. The connection details that link WordPress to it live in wp-config.php:
define( 'DB_NAME', 'your_database' );
define( 'DB_USER', 'your_user' );
define( 'DB_PASSWORD', 'your_password' );
define( 'DB_HOST', 'localhost' );If DB_HOST is not localhost, your database is on a separate host. That is common on cloud and managed WordPress platforms.
How to access your WordPress database via phpMyAdmin
phpMyAdmin is the tool most hosts give you to read and run SQL against the database. The flow is the same nearly everywhere:
- Log in to your hosting control panel (cPanel, Plesk, or the host's dashboard) and open phpMyAdmin.
- In the left sidebar, select the database named in your
wp-config.phpDB_NAME. - Click a table like
wp_poststo browse rows, or open the SQL tab to run a query. - Paste a query, run the
SELECTto check the result, then act on it.
If your host does not offer phpMyAdmin, Adminer is a single-file alternative you can upload, and managed hosts usually have their own database browser that works the same way.
Useful SQL queries to find and manage your content
These are the everyday queries I keep around. Run them in the phpMyAdmin SQL tab.
Find a post by a keyword in its content:
SELECT ID, post_title, post_date
FROM wp_posts
WHERE post_content LIKE '%your-keyword%'
AND post_type = 'post' AND post_status = 'publish';List posts with their author's name:
SELECT p.ID, p.post_title, u.display_name
FROM wp_posts p
JOIN wp_users u ON p.post_author = u.ID
WHERE p.post_type = 'post' AND p.post_status = 'publish';Find every attachment and its file type (this is where post_mime_type earns its place):
SELECT ID, post_title, post_mime_type
FROM wp_posts
WHERE post_type = 'attachment';Where are WordPress files stored?
The content is in the database; the files are on disk. Everything that is a real file lives under /wp-content:
/wp-content/uploads: your media, inyear/monthfolders. The image bytes are here; the database only keeps the reference./wp-content/themes: your themes./wp-content/plugins: your plugins.
So an image is split across both worlds: the file in /wp-content/uploads, and its record (the attachment row plus its alt text and sizes in wp_postmeta) in the database.
How to back up your WordPress database
Before any direct database change, take a backup. There are three honest ways to do it:
- phpMyAdmin: select the database, click Export, choose Quick + SQL. Fine for small to mid sites.
- mysqldump over SSH:
mysqldump -u user -p database > backup.sql. The cleanest method for large databases. - A backup plugin: UpdraftPlus or similar, if you would rather not touch the command line.
Whichever you pick, download the file off the server. A backup that lives only on the same server is not really a backup.
Stuck inside the database?
Migrations, broken meta, bulk content fixes, and the SQL behind them — send us the site and what you are trying to do. The first reply comes from Sunny, not a sales team.
See WordPress developmentFinal take
Posts and pages both live in wp_posts, separated by post_type. Their extra data, including your Rank Math or Yoast SEO titles, lives in wp_postmeta. The database is held by MySQL, not in public_html, and your files sit in /wp-content.
Once that map is in your head, the database stops being scary and becomes the fastest way to find, audit, and fix content at scale.
Just back up first, read before you write, and let the SELECT confirm what the UPDATE is about to do.
Common questions
Where are WordPress posts and pages stored?
Both live in the wp_posts table of your WordPress MySQL database. They are not separate files. WordPress tells a post from a page using the post_type column: post_type = "post" for blog posts, "page" for pages. The same table also holds revisions and attachments.
Where does WordPress store the database — in public_html?
No. Your WordPress files sit in public_html, but the database is managed by MySQL separately. Its raw data files live in the MySQL data directory (commonly /var/lib/mysql on Linux), and on many hosts on a different server entirely. You reach it through phpMyAdmin or the credentials in wp-config.php.
Where is the Rank Math title and description stored in the database?
In wp_postmeta. Each post has rows with meta_key = "rank_math_title" and "rank_math_description", and the meta_value holds the text, keyed to the post by post_id. Yoast uses the meta_keys "_yoast_wpseo_title" and "_yoast_wpseo_metadesc" instead.
Can I edit WordPress posts directly in the database?
Yes, with a SQL query in phpMyAdmin or the command line, which is how bulk edits and migrations are done. But it is irreversible and bypasses WordPress hooks, so always export a backup first and test the SELECT before you run the UPDATE.
Where are WordPress images stored?
The image files themselves live on disk in /wp-content/uploads, organised by year and month. The database only stores a reference: each upload is a row in wp_posts with post_type = "attachment", and details like the alt text and sizes sit in wp_postmeta.
What is the difference between a post and a page in the database?
There is no separate table. Posts and pages share the wp_posts table and differ only by the post_type value — "post" or "page". Pages can also use the post_parent column to nest under another page; posts use categories and tags stored in the term tables instead.

SEO Specialist and product builder with 10+ years in search. The notes come from the work, not the theory.