When a WordPress export keeps failing, the cause is almost always the server, not your content. The export runs as a PHP script, and on a large site it hits a timeout, a memory cap, or a file-size limit and stops partway, leaving you with a truncated or empty file. The quick fix is to export in smaller pieces. The deeper point is that the XML it produces is a WordPress backup, not a clean portable format, so for a migration a crawl-based export is both more reliable and more useful. WPBuildAI exports your content from the rendered site, which does not depend on the export script finishing at all.
Why large exports stall
WordPress builds the whole export in one pass, and a big site asks too much of a single PHP request. The exporter gathers all the selected content into memory and writes one file, so three things can stop it: the PHP execution time runs out before it finishes (a timeout), the script exhausts its memory limit assembling the data, or the resulting file exceeds an upload or response limit. The 2024 Web Almanac shows how large real sites become over the years, with thousands of posts, revisions, and attachments, and that accumulated volume is exactly what trips these limits. WordPress’s own export tool documentation describes the standard export, which works fine for small sites and strains on large ones. So the failure is not random or a sign of corruption; it is a predictable consequence of asking one PHP request to package more data than the server’s limits allow.
How to get a large export to complete
The reliable way to push a large export through is to make each export smaller. The export screen lets you choose what to include, so export one content type at a time, posts first, then pages, then any custom types, and split further by date range if a single type is still too big, so each file stays under the server limits. Several smaller exports that each succeed beat one giant export that keeps dying at the same point. You can also ask your host to temporarily raise the PHP execution time and memory limit, which gives the script more room to finish, though splitting is usually simpler and does not require host changes. The principle is to reduce the work per request below the threshold that is failing, rather than repeatedly retrying the same oversized export and hoping it completes this time.
The format problem behind the failure
Even when you do get the export to complete, it is worth asking whether the XML is the right tool, because often it is not. WordPress XML (WXR) is a backup format designed to move content between WordPress installs, where another WordPress decodes it. It is not a clean, portable format: it carries shortcodes, serialized metadata, and theme-specific markup that mean nothing outside WordPress, so it imports poorly into other platforms, static generators, and AI builders, the problem detailed in why WordPress XML won’t import into Cursor. So a failing export is often a signal to change approach, not just settings: if your destination is anything other than another WordPress site, the XML you are fighting to produce will not import cleanly anyway. For a migration you usually want clean Markdown, JSON, or CSV, which means the better move is frequently to abandon the XML route entirely rather than to coax the failing export across the line.
A worked example: a 5,000-post export that kept dying
Picture a ten-year-old blog with 5,000 posts plus years of revisions and media. The owner tries a full export and it times out every time, around the same point, producing a half-written file. They split by content type: posts alone still fail, so they split posts by year, and the per-year exports finally complete, leaving a dozen XML files to stitch together. It works, but it is fiddly, and the resulting XML is still a WordPress backup full of shortcodes that the owner’s intended destination, a static site, cannot use. The alternative would have been simpler: crawl the rendered blog once, capturing all 5,000 posts as clean files with no dependence on the export script, and get the URL list for redirects as a bonus. The split-XML approach got the data out eventually, but in the wrong format and with real effort; the crawl would have produced usable content in one pass.
The reliable alternative: a crawl-based export
The approach that sidesteps both problems, the script limits and the format, is to export from the rendered front end. A crawl reads your live pages the way a visitor’s browser does and captures the real content, images, and structure as clean files, with no dependence on a fragile PHP export script that can time out. Because it reads page by page, there is no single giant request to exceed a limit, and because it captures the rendered output, it produces clean content rather than WordPress’s backup markup. It also yields the URL list you need for redirects, per Google’s site move guidance. Ahrefs found in its search traffic study that a small share of pages carries most traffic, so a complete capture matters, and a crawl that covers every URL delivers it. This is the same crawl-first approach behind mapping a site’s structure, exporting a whole site to one file, and rebuilding without losing data.
What a crawl gives you that XML does not
The crawl-based export is not just a workaround for the failure; it produces a better result. XML gives you WordPress’s internal representation, shortcodes, serialized fields, and all, which you then have to clean and convert. A crawl gives you the finished content as it actually appears, clean text, headings, and resolved markup, which is what a non-WordPress destination needs. It also captures things the XML omits or buries: the rendered output of shortcodes (rather than the raw shortcode), the actual image URLs in use (including those from themes and builders that the media-library-based export can miss), and the real URL of every page for the redirect map. And it scales with site size gracefully, since it reads pages incrementally rather than packaging everything in one request. So for a migration off WordPress, the crawl is both more reliable to run and more useful in what it produces, which is why a persistent export failure is often best answered by switching methods rather than fixing the export.
When XML is fine
To be balanced: the XML export is not useless, and there are cases where it is the right tool. If you are moving between two WordPress installs, WXR is exactly what the destination expects and will import cleanly, so for a WordPress-to-WordPress move it is the correct format and worth getting to complete via the splitting techniques above. If your site is small, the export will not hit the limits in the first place. And as a rough backup of your content, a successful XML export has value. The XML becomes the wrong tool specifically when the destination is not WordPress, a static generator, a React or Next.js front end, an AI builder, a Supabase backend, because then its WordPress-specific structure is baggage rather than content. So match the method to the destination: XML for WordPress-to-WordPress, a crawl-based clean export for everything else, which also happens to dodge the script limits.
Common mistakes with failing exports
The recurring errors come from fighting the wrong battle. Repeatedly retrying the same oversized full export wastes time on a request that will keep hitting the same limit. Assuming the failure means the content is corrupted, rather than the script timing out, sends you debugging the wrong thing. Forcing the XML through by splitting, then trying to import it into a non-WordPress destination, produces a file that does not import cleanly anyway. Trusting the completed XML to carry images, when theme and builder images may be missing from it, leaves gaps. And ignoring that the export is the wrong format for the destination means doing the hard work twice. Each is avoided by diagnosing the failure as a server-limit issue, splitting only if the destination is WordPress, and otherwise switching to a crawl-based clean export that scales and produces the format the destination actually needs.
Key points to remember
A WordPress export keeps failing because the export runs as one PHP request that, on a large site, hits a timeout, memory cap, or file-size limit and stops partway, not because your content is broken. To get it through, export in smaller pieces, one content type or date range at a time, or have your host raise the limits temporarily. But the deeper issue is format: WXR is a WordPress-to-WordPress backup full of shortcodes and serialized data, so if your destination is not WordPress, fighting the export produces a file that will not import cleanly anyway. The more reliable route for a migration is a crawl-based export from the rendered front end, which dodges the script limits, scales with site size, produces clean content, and yields the URL list for redirects. WPBuildAI exports from the rendered site, so a large or fragile WordPress install still exports completely; send your site URL for a fixed quote.
Not affiliated with WordPress or Lovable.