A huge server rack overflowing with paper pages, a browser window grid buried below, the words TOO MANY QUERIES stamped on the rack.
Blog
Adult WordPress7 min read

Why a WordPress tube is slow, and what 40,000 videos demand

The slowness of a big WordPress tube is mechanical: meta queries, imports on page load, shared hosting, whole MP4 files. Where each one comes from, and the fix.

Published
By the Jimp team
Also in
Français

A WordPress tube gets slow for mechanical reasons, and almost never for the reason its owner blames first. It is not the theme. It is the database asked to sort tens of thousands of posts by a value stored as text, imports that run while a visitor waits, a shared server that was never sized for it, a grid of third-party thumbnails and players loaded all at once, and video files served whole from the same machine. Each one is fixable. A site of 40,000 videos needs all of them fixed, because at that size every shortcut shows.

We built and ran WordPress adult sites for years before Jimp. What follows is what we saw break, in the order it usually breaks.

Measure first, with the right number

Before touching anything, open PageSpeed Insights on three pages, not one: the home page, a category page, and a video page. They are slow for different reasons.

PageSpeed shows two kinds of data, and its documentation is clear on the difference. The top block is field data, what real Chrome users experienced on your pages over the previous 28 days. The block below is lab data, a simulated load of the page on one device and one fixed set of network conditions. The field data is what your visitors lived through; the lab data is what tells you why. A new or small site often has no field data at all, and then the lab run is all you have.

The three numbers that matter are the Core Web Vitals. Largest Contentful Paint should be under 2.5 seconds, Interaction to Next Paint under 200 milliseconds, Cumulative Layout Shift under 0.1, measured on three visits out of four. On a tube, LCP is usually the first thumbnail or the player poster, and CLS is usually a grid of images without dimensions jumping as they load, or a banner that arrives late and pushes everything down.

Write the three pages' numbers down. Every change below should move one of them, and if it does not, undo it.

The database was not built for this

WordPress stores anything that is not a title, a body or a date in a separate table, wp_postmeta, as one row per key per post. A video imported by a typical embedder plugin carries a dozen of those keys or more: the source, the video id at the source, the embed code, the thumbnail, a set of screenshots, the duration, a trailer, a flag or two. At 40,000 videos, that table holds hundreds of thousands of rows, and it grows with every import.

Reading one post's meta is cheap. Sorting or filtering on it is not. "Most viewed", "longest", "HD only": every one of those listings asks the database to find the right meta key across every post, read its value as text, convert it, and sort the lot, and the value column is not indexed for that. The WordPress VIP documentation says it directly. The table has an index on the key but not on the value, and some of these queries can be turned into taxonomy queries. On a home page with four such blocks, that is four of these queries per uncached view.

The fixes, cheapest first. A persistent object cache (Redis or Memcached, if the host offers it) so the same query does not run for every visitor. Turn the filters you list by into categories or tags, which WordPress indexes. And store a view count in its own table if the theme sorts by it, instead of rewriting a meta row on every play.

Imports that run while a visitor waits

Mass import plugins fetch feeds on a schedule, and on most WordPress installs that schedule is WP-Cron. The plugin handbook explains what it actually is: not a system scheduler, but a check that runs on page loads. When a task is due, a visitor's request triggers it.

For a blog that publishes once a day, nobody notices. For a tube that imports hundreds of videos per run, downloads their thumbnails, creates posts and terms, and pings the source for each one, the visitor who happened to trigger it waits, and so does everyone arriving while the server is busy. The handbook gives the fix on its system cron page: set DISABLE_WP_CRON in wp-config.php and call wp-cron.php from a real system cron every few minutes. Imports then run on their own clock, off the path of any visitor.

While you are in there, check what the import plugin downloads. Thumbnails copied locally on every import are a disk that fills and a backup that grows; if the source serves them from its own CDN, and the plugin lets you keep the remote URL, keep it.

Shared hosting has a ceiling you cannot see

Most WordPress tubes start on shared hosting, because they start small. Shared plans limit CPU time, memory and simultaneous PHP processes per account, and those limits are not always printed on the sales page. The symptom is recognizable. The site is fine at night, slow at peak, and throws a 503 or a "resource limit reached" page on the day a post takes off.

No amount of optimization moves that ceiling; it moves how soon you hit it. Page caching does the most (the WordPress optimization guide calls it the biggest benefit for the smallest hassle), because a cached page is served without starting PHP at all. For logged-out visitors, which on a tube is nearly all of them, a full-page cache (at the host, in a plugin, or at a CDN in front) turns most requests into a file read. After that, the honest fix for a site that has outgrown shared hosting is to leave it.

Third-party thumbnails and players, all at once

A category page shows a grid, and every cell is an image, often hosted by the source tube on its own domain. Forty thumbnails is forty requests, often to several different hosts, each with its own connection to open. Add hover previews loaded up front and the page is heavy before anyone has clicked anything.

The browser can do most of the work here if you let it. Give every thumbnail its width and height so the grid does not shift. Load the first row normally and add loading="lazy" to the rest, as web.dev's guidance on lazy loading recommends, but never on the first image, which is usually your LCP. Load hover previews on hover, not before.

The player is the heavier problem. An embedded tube player is an iframe that pulls the source's scripts, its ads and its tracking the moment the page loads. Lighthouse's own audit suggests a facade: show the poster image with a play button, and load the real iframe only when the visitor clicks. On the video pages we worked on it was the largest single gain, and it costs a click that the visitor was going to make anyway.

A whole MP4 is not a stream

If your WordPress hosts video itself, uploaded MP4s or trailers copied from a sponsor, it serves them as files. A browser playing an MP4 from a plain web server downloads it progressively, from the same machine that also runs PHP for every page, at one quality whatever the visitor's connection. Seeking into the middle only works if the server answers range requests, which not every setup in front of PHP does cleanly. On shared hosting, a few people watching at once is enough to slow every page of the site.

Video at scale is served differently. The file is cut into short segments at several qualities, listed in a playlist (HLS is the common format), and served from storage built for it rather than from the application server. The player picks the quality the connection can hold and fetches only the segments it plays. That is not a WordPress setting. It is a separate pipeline, and it is why sites that host their own video end up putting it somewhere other than wp-content/uploads.

What a 40,000 video site needs

Put together, a large tube needs five things, and none of them is a theme. Listings filtered on indexed data, not on meta. Imports on a real schedule, away from visitors. Pages served from a cache without starting PHP. Thumbnails and players that load when they are seen, not before. And video, if you host any, in segments from storage built for it.

You can get there on WordPress with enough work, a good host and discipline about plugins. Or you can move. When a Jimp site takes over from a WordPress tube, the WordPress migration copies the files the old site hosted and serves MP4s in HLS, while embedded videos stay with their tube, and the custom domains page of the docs explains the switch day. Whichever you pick, measure the three pages before and after. The numbers are the only opinion that counts.

Keep reading

  1. Adult WordPressMoving a WordPress adult tube without losing its rankingsA migration is not a copy. What Google keeps when a tube changes platform, the three mistakes that lose rankings, and the switch order that keeps them.6 min readRead
  2. LegalThe UK law of 6 November: what changes for a tube or cam affiliate siteFrom 6 November 2026, publishing realistic porn that shows strangulation, suffocation or incest becomes a crime in England and Wales. What the text says, what it does not, and what a site that only shows embeds and widgets should clean this week.6 min readRead
Try it

Build a site that does all of this by default.

Get started

Three minutes, no card, a real site with your niche and your codes.