Speeding up a WordPress website with tens or hundreds of thousands of posts can be challenging. The number of posts can potentially slow down your website, affecting the overall user experience, SEO ranking, and, most importantly, Google’s Core Web Vitals scores. However, there are several techniques and plugins available that you can utilize to speed up your WordPress installation.

1. ElasticSearch Integration

Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents. Elasticsearch can significantly speed up search and query operations on WordPress, making it very beneficial for sites with a lot of content or high traffic volumes.

To integrate Elasticsearch into your WordPress site, you need an Elasticsearch server and the ElasticPress plugin. Here’s a high-level step-by-step guide:

1. Setup an Elasticsearch Cluster

Firstly, you need to set up your Elasticsearch cluster. You can do this on your server, or use a managed service like Amazon Elasticsearch Service, Elastic Cloud, or any other provider. The exact setup will depend on the provider, but you’ll need to install Elasticsearch, set it up to start on boot, and secure it.

2. Install and Configure the ElasticPress plugin

You can install the ElasticPress plugin from the WordPress plugin repository or its Github page. After installing and activating the plugin, you must connect it to your Elasticsearch server.

Here are the steps to follow in your WordPress Dashboard:

  • Navigate to the ElasticPress dashboard inside your WP admin area. The path would look like this: “http://your-site.com/wp-admin/admin.php?page=elasticpress”.
  • In the ElasticPress settings page, set the Elasticsearch host in the form of a URL which usually looks like “http://localhost:9200” or “https://your-es-domain.com:port”.
  • Save changes.

1. Update the wp-config.php file

To take full advantage of the ElasticPress plugin, you need to add a few lines of code to your wp-config.php file.

define('EP_HOST', 'https://your-es-domain.com:port');
define('ES_SHIELD', 'username:password');

Where ‘https://your-es-domain.com:port’ is your Elasticsearch server address and ‘username:password’ are the Elasticsearch server credentials if any.

2. Index the site content

After setting up the plugin, you need to index your site content. You can do this by clicking the “Start Indexing” button on the ElasticPress dashboard in the WordPress admin area. The time this process takes depends on the amount of content on your site.

3. Test and Optimize

After indexing, test your site to see the improvements. You can also use the ElasticPress dashboard to adjust what content gets indexed and how search results should be weighted.

Integrating Elasticsearch with WordPress can have several benefits:

  • Speed: Elasticsearch can handle search and query operations much faster than a traditional MySQL database, especially for large sites.
  • Scalability: Elasticsearch is built to be distributed, which means it can scale up with your site as it grows.
  • Relevance: Elasticsearch allows for complex queries that can improve the relevance of search results.
  • Resilience: Due to its distributed nature, Elasticsearch can continue working even if one or more nodes fail, increasing the reliability of your WordPress site

2. Redis object cache

Using Redis as a caching system can significantly speed up your WordPress site. The reason is that Redis stores your data as in-memory data structures, allowing for faster data retrieval than other databases that require data to be read from disk. This means that when WordPress needs data, it can retrieve it more quickly from Redis than it can from the default MySQL database.

The Redis Object Cache plugin is a way to integrate Redis caching into WordPress. Here’s a simplified breakdown of how it works:

  1. Initialization: When you install and activate the Redis Object Cache plugin, it stores data in the Redis cache.
  2. Caching: Whenever WordPress needs to retrieve data, it first checks if the data is available in the Redis cache. If the data is present (a cache hit), it will be served directly from Redis, faster than retrieving it from the MySQL database.
  3. Updating: If the data is not in the cache (a cache miss), WordPress retrieves it from the MySQL database, and the Redis Object Cache plugin will store it in the Redis cache for future use.
  4. Invalidation: When data is updated in the WordPress database, the corresponding data in the Redis cache will be invalidated to ensure that outdated data is not served.

This system is called object caching. In WordPress, “objects” refer to the SQL queries and their results. By caching these objects, Redis reduces the need for WordPress to interact with the MySQL database, which speeds up your website.

Benefits of using Redis for caching include:

  • Speed: As mentioned, Redis is an in-memory database, which makes it faster than disk-based databases like MySQL. This makes your WordPress site run more smoothly and quickly.
  • Scalability: Redis can handle large amounts of data and high traffic loads, which is ideal for websites with many visitors.
  • Reliability: Redis uses various data persistence options, which means your data is safe even if your server crashes or restarts.

Remember that caching is not a one-size-fits-all solution. You should test different types of caching to see what works best for your site and monitor your site’s performance regularly to ensure that your caching solution is working as expected.

3. Separate Subdomain for Static Files

To enhance the performance of your WordPress website, one common strategy is to offload static content onto a separate subdomain. Static content refers to elements like images, CSS, and JavaScript files that do not change frequently. Here are some reasons why this is beneficial:

  1. Parallel Downloads: Browsers limit the number of concurrent connections (downloads) to a single domain, usually it’s six connections. By using a separate subdomain, you effectively increase the limit, allowing the user’s browser to download more files at the same time, thereby speeding up page load times.
  2. Cookieless Domain: When a browser requests a server, it sends all the cookies associated with that domain. Static files like images, CSS, and JS don’t need any cookie information to be served. By serving static content from a cookieless environment, you can reduce the total amount of data transferred, thereby saving bandwidth and improving response times.
  3. Caching Advantages: Storing static content on a subdomain makes it easier to control cache settings. For example, you can set long expiry times for static resources, which means that users will store these files in their local browser cache and won’t need to re-download them on subsequent visits, leading to faster load times.

Example of Using KeyCDN Plugin in WordPress:

KeyCDN is a high-performance content delivery network (CDN) that can help deliver your website’s static content faster to users. Here’s an essential way you might set it up with WordPress:

  1. Sign Up for KeyCDN: First, sign up and create a Pull Zone on KeyCDN (or go to step 2 if you don’t want to use any external services)
  2. Install CDN Enabler Plugin: KeyCDN offers a WordPress plugin called CDN Enabler which allows you to link your website to KeyCDN easily. Install and activate this plugin on your WordPress site.
  3. Configure CDN Enabler: In the CDN Enabler settings, input the CDN URL or Zone Alias you’ve set up on KeyCDN. You can also specify included directories, exclusions, and other settings as necessary.
  4. Validate Setup: After saving your settings, you can view the source of your website to confirm that your static assets (images, CSS, JS) are being served from the KeyCDN servers (or point a static subdomain to your webserver if you don’t want to use external services).

Setting up static cookieless subdomain using NGINX as a Reverse Proxy:

A reverse proxy is a server that sits between client devices and a web server, forwarding client requests to the web server and returning the server’s responses to the clients. NGINX is popularly used as a reverse proxy server. It can help make your static subdomain cookieless and manage cache settings.

To make a domain cookieless, you must ensure that your application or website doesn’t set any cookies for that domain. NGINX can’t directly control cookies (as your application sets them), but you can use it to serve static content from a separate, cookieless domain or subdomain.

Here’s a simple NGINX configuration that could be used to set long expiration times for your static content:

server {
    listen 80;
    server_name static.yourdomain.com;

  location / {
    root / path / to / your / static / files;
        expires max;

        location ~* \.(jpg | jpeg | gif | png | css | js | ico | xml)$ {
            access_log        off;
            log_not_found     off;
            expires           30d;

In this configuration, we’ve set the maximum expiration time for all static files and a 30-day expiry for specific file types. expires max; sets the expiry date as far in the future as possible, which is usually one year. The path /path/to/your/static/files should be replaced with the actual path to your static content.

Remember to replace static.yourdomain.com with your actual static subdomain and ensure that this subdomain doesn’t set any cookies. Also, be sure to restart NGINX after making these changes.

4. Optimize images and videos (use WebP & WebM)

Why use WebP for images and WebM for videos?

Both WebP and WebM are open standards developed by Google. They provide high-quality compression options for images and videos, respectively, making them suitable for internet use where lower file sizes can mean faster load times and reduced bandwidth usage.

  1. WebP: This image format provides superior lossless and lossy compression for images on the web. Using WebP, web admins and web developers can create smaller, richer images that make websites faster. WebP lossless images are 26% smaller compared to PNGs, and WebP lossy images are 25-34% smaller than comparable JPEG images at an equivalent SSIM quality index.
  2. WebM: This is a video file format. It is primarily intended to offer a royalty-free alternative for the HTML5 video and the HTML5 audio elements. WebM files consist of video streams that are compressed with the VP8 or VP9 video codecs and those that are compressed with the Vorbis or Opus. The format is widely used due to its low computational footprint, meaning it can deliver high-quality videos without causing a strain on system resources.

WordPress Plugins to convert images to WebP and videos to WebM:

  1. WebP Converter for Media: This free WordPress plugin converts your photos to the WebP format. It generates a WebP version of every image you upload to your Media Library. It also supports bulk conversion of existing images.
  2. EWWW Image Optimizer: This is another popular plugin that can convert your images to WebP format. It can also optimize your existing images and convert them into the WebP format.
  3. ShortPixel Image Optimizer and ShortPixel is a freemium plugin that can optimize your images and convert them into WebP. It offers both lossy and lossless image compression along with a perfect glossy JPG that is perfect for photographers who want to preserve image quality and reduce file size.

For videos, WordPress does not natively support WebM. You might need to host your videos on a platform that supports WebM, like YouTube or Vimeo, and then embed the videos on your site.

Command line tools for conversion:

1. For WebP (using cwebp): The cwebp tool is a command line utility part of the libwebp library. It allows you to convert images to the WebP format.

Here is a simple command for converting a JPEG or PNG image to WebP:

webp - q 80 input.jpg - o output.jpg.webp

In this command, -q 80 sets the quality of the output file. You can adjust this value to balance the quality and file size.

2. For WebM (using FFmpeg): FFmpeg is a free and open-source tool that can handle various multimedia tasks, including converting video formats.

Here’s a simple command to convert an MP4 video to WebM using VP9 codec and Opus for audio:

ffmpeg - i input.mp4 - vcodec libvpx - vp9 - acodec libopus output.webm

In this command, -i input.mp4 is the input file, -vcodec libvpx-vp9 sets the video codec to VP9, -acodec libopus sets the audio codec to Opus, and output.webm is the output file.

Nginx configuration:

To serve WebP images conditionally (only if the client supports it), you can add a few lines to your Nginx configuration file.

Here is an example configuration:

location ~* ^.+\.(png | jpg | jpeg)$ {
    add_header Vary Accept;
  $uri.webp $uri = 404;

This configuration works by checking if a .webp version of an image exists whenever a request for a PNG, JPEG, or JPG image is made. If a .webp version exists and the client’s browser indicates that it can accept WebP images (via the Accept header), the .webp image is served. Otherwise, the original image is served.

Remember to reload or restart Nginx after making these changes:

sudo service nginx reload

Finally, don’t forget to test your website after making these changes to ensure everything works as expected, and use online tools like Google’s PageSpeed Insights to see the impact on your site’s loading speed.

5. Enable Gzip and Brotli Compression

Gzip and Brotli are methods of compressing files for faster network transfer. They can be used to reduce the size of files sent from your server, thereby increasing the speed of your website.

To understand why compression is essential, you must comprehend how browsers retrieve websites. When a user visits your website, their browser sends a request to your server to deliver the website’s files (HTML, CSS, JavaScript, images, etc.). The size of these files can significantly affect your site’s load time—the larger the files, the longer it takes for a page to load.

Compression works by finding and eliminating redundancy in the data, which reduces the overall size of the files. The browser of your website’s visitor will then decompress the files upon receiving them, reconstituting them into their original state. The entire process is nearly instantaneous and transparent to the user.

Gzip is the more widely supported compression method, while Brotli is newer and offers slightly better compression ratios but isn’t as universally supported.

It’s generally a good idea to enable both and let the browser choose which one to use. Most modern browsers prefer Brotli if it’s available, but it will fall back on Gzip if not.

Here is how to enable Gzip and Brotli on both Nginx and Apache.

Enable Gzip and Brotli on Nginx

First, make sure you have the modules installed:

sudo apt install nginx-module-brotli

Then, open your Nginx configuration file, which is typically located at /etc/nginx/nginx.conf or /etc/nginx/sites-available/default. Add the following inside the http block:

http {
    #... existing configuration

    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml;

    brotli on;
    brotli_static on;
    brotli_types *;

    #... existing configuration

Save and close the file, then test your configuration to make sure there are no syntax errors:

sudo nginx -t

If the test is successful, restart Nginx:

sudo systemctl restart nginx

Enable Gzip and Brotli on Apache

Apache requires the mod_deflate and mod_brotli modules for Gzip and Brotl, respectively. These modules might not be enabled by default.

To enable them:

sudo a2enmod deflate
sudo a2enmod brotli

Then, open your Apache configuration file, typically located at /etc/httpd/conf/httpd.conf or /etc/apache2/sites-available/000-default.conf. Add the following:

<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/x-javascript

<IfModule mod_brotli.c>
    AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css text/javascript application/javascript application/json

Save and close the file, then restart Apache:

sudo systemctl restart apache2

Finally, you can use online tools such as Google’s PageSpeed Insights, GTMetrix, or any other site that checks for Gzip/Brotli compression to verify if your server is correctly compressing your site’s files.

Please note before making any changes to configuration files, it is always a good idea to back them up first.

6. Disable unused or heavy plugins

WordPress, like many content management systems, can suffer from slow load times if not properly optimized. This can have a significant impact on user experience and search engine rankings. Several factors can contribute to a slow WordPress site, and plugins are a major one. Here’s why:

  1. Unused Plugins: Every plugin you add to your WordPress site comes with its own set of scripts, stylesheets, and database entries. While these resources are necessary for the plugin to function, they can slow down your site if they’re not used efficiently or if they’re not used at all. By disabling and deleting unused plugins, you’re reducing the unnecessary resources your site needs to load. Even if a plugin is deactivated, it can still have overhead on your site if its code is poorly written.
  2. Heavy Plugins: Some plugins are resource-intensive. They may make numerous database queries or require a lot of processing power to function. If your site uses several of these ‘heavy’ plugins, your server could become overwhelmed, leading to slow load times. You can significantly improve your site’s performance by identifying and disabling these plugins. It’s best to look for lightweight alternatives that offer similar functionality or consider custom coding the needed functions.

Try to optimize WordPress further with the Perfmatters plugin. This performance plugin for WordPress helps you speed up your site by disabling unnecessary WordPress default settings and features. This plugin offers a lot of functionalities that can help optimize your WordPress site:

  1. Disable WordPress options: Perfmatters allows you to turn off specific WordPress default settings that could slow down your site, like emojis, embeds, RSS feeds, XML-RPC, RSD links, shortlinks, and more.
  2. Disable scripts per page/post basis: Perfmatters allows you to turn off scripts on specific pages. This is beneficial because a script (like a contact form plugin) is often only used on one page of your site, yet the script is loaded on every page. This feature allows you to turn off that script on all the pages where it’s not needed, reducing the load time of those pages.
  3. Database optimization: Perfmatters has a database optimization feature that lets you delete post revisions, drafts, spam comments, and more. These things can pile up in your database and slow down your site, so keeping your database clean can help improve performance.
  4. DNS Prefetching: By adding DNS Prefetch, your browser can resolve domain names (perform a DNS lookup in the background) before a user clicks on a link, which will help loading speed.
  5. Google Analytics Optimization: Perfmatters offers an option to host Google Analytics locally, which can help satisfy the ‘Leverage Browser Caching’ warning often seen in site speed testing tools.

Remember, while optimizing the performance, don’t compromise the functionality and look of your site. The goal is to balance the functionality you need and the performance you want. Sometimes, a well-coded plugin might have more impact than multiple lightweight, poorly coded plugins. The key is to monitor your website performance and adjust as needed regularly.

7. Enable page-level caching

Page-level caching is essential to speed up WordPress because it significantly reduces server load and increases website speed. Here’s how it works: WordPress is a dynamic content management system, meaning every time a user visits your site, WordPress queries the database, then compiles the results into HTML content, which is then served to the user. This process can be resource-intensive and time-consuming, especially for websites with high traffic.

Page-level caching mitigates this by storing the final HTML page output in a cache. When the same user (or a different user) revisits the same page, instead of querying the database and recompiling the results, the cached HTML content is served directly. This dramatically reduces the load on the server and makes the website load faster for the user.

Setting up Page-Level Caching via Nginx

Using the FastCGI cache module, you can set up page-level caching in Nginx. This module caches dynamic content processed by the FastCGI server (php-fpm). Here’s a basic configuration to get you started:

  1. Open the main Nginx configuration file:
sudo nano /etc/nginx/nginx.conf

2. Add the following lines in the http section:

fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=MYAPP:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

3. Open your website’s server block configuration:

sudo nano /etc/nginx/sites-available/your_website

4. And add these lines in the location ~ \.php$ section:

fastcgi_cache MYAPP;
fastcgi_cache_valid 200 60m; # Cache successful responses for 60 minutes

5. Restart and test nginx configuration:

sudo systemctl restart nginx
sudo nginx -t

Setting up Page-Level Caching via Apache

With Apache, you can use the mod_cache module to enable page-level caching. Here’s how to do it:

  1. Enable the mod_cache module:
sudo a2enmod cache
sudo a2enmod cache_disk

2. Open your website’s configuration file:

sudo nano / etc / apache2 / sites - available / your_website.conf

3. Add these lines to enable caching:

<IfModule mod_cache.c>
    CacheQuickHandler off
    CacheLock on
    CacheLockPath /tmp/mod_cache-lock
    CacheLockMaxAge 5
    CacheIgnoreHeaders Set-Cookie
    <Location />
        CacheEnable disk
        CacheHeader on
        CacheDefaultExpire 600
        CacheMaxExpire 86400
        CacheIgnoreNoLastMod On

4. Restart Apache:

sudo systemctl restart apache2

WordPress Plugins for Page-Level Caching

If you don’t have direct access to the server or lack the technical expertise to modify server configuration files, you can use WordPress plugins to enable page-level caching:

  1. W3 Total Cache: This plugin offers a comprehensive set of caching tools, including page caching, object caching, database caching, browser caching, CDN integration, and more.
  2. WP Super Cache: This is a more user-friendly caching plugin. It offers page caching, cache preloading, CDN support, and advanced settings for controlling how the caching functions.
  3. WP Rocket: This is a premium caching plugin. It is highly user-friendly and offers features like page caching, cache preloading, browser caching, GZIP compression, minification and concatenation of CSS and JavaScript files, lazy loading of images, and more.

8. Server-level optimizations

Optimizing your PHP-FPM and Nginx or Apache configuration can significantly improve the performance and scalability of your WordPress website. This can result in faster page load times, better user experience, and improved SEO rankings.

Below are example configurations and optimizations you can make for PHP-FPM, Nginx (or Apache). Please note that these are general configurations, and your specific requirements may vary. It’s recommended that you understand each setting before modifying your configuration files.


The main configuration file is typically located at /etc/php/8.x/fpm/pool.d/www.conf (replace 8.x with your PHP version). Some key parameters to optimize are:

  • pm = dynamic: This setting configures the way PHP-FPM manages child processes. Values can be static, dynamic, or ondemand. Dynamic is a good choice for most WordPress websites as it allows PHP-FPM to scale based on demand.
  • pm.max_children: This directive sets the maximum number of child processes allowed to spawn. The perfect value depends on your available server memory. A typical formula to calculate this is: (total server memory - memory used by other processes) / memory used by each PHP-FPM process.
  • pm.start_servers, pm.min_spare_servers, pm.max_spare_servers: These control the number of servers started on startup and the minimum/maximum number of idle server processes. These values should be optimized based on the server’s available memory and average load.
  • pm.max_requests: This directive sets the number of requests each child process should execute before respawning. This can be helpful to work around any memory leaks in third-party libraries. A value of around 500 is a reasonable starting point.


The main Nginx configuration file is often found at /etc/nginx/nginx.conf. Here are some directives to look at:

  • worker_processes auto: The worker_processes directive sets the number of worker processes (1 by default). The optimal setting depends on many factors, but as a rule of thumb, setting it to the number of CPU cores on your server is a good start. Setting it to ‘auto’ will automatically set it to the number of CPU cores.
  • worker_connections: This directive sets the maximum number of simultaneous connections that a worker process can open. A typical value is 1024.
  • sendfile on: This directive allows Nginx to use the sendfile function to speed up static content delivery.
  • gzip on: This directive enables Gzip compression, reducing the data size that must be sent to clients.
  • fastcgi_buffer_size, fastcgi_buffers: These directives help optimize how Nginx communicates with your PHP-FPM setup.


Apache configuration files are often located in /etc/httpd/conf/httpd.conf or /etc/apache2/apache2.conf. Here are a few optimizations:

  • KeepAlive On: This setting allows connections to be reused for multiple requests, significantly reducing network latency for clients making several requests.
  • MaxKeepAliveRequests 100: This setting controls the maximum number of requests allowed per persistent connection. If it’s set to 0, unlimited requests will be allowed.
  • KeepAliveTimeout 5: This setting controls the number of seconds Apache will wait for a subsequent request before closing the connection.
  • StartServers, MinSpareServers, MaxSpareServers, MaxRequestWorkers: These directives control the number of child server processes and threads. These should be optimized based on your server size and load.

Please note that after any changes to these configuration files, you need to restart the corresponding services for the changes to take effect. Testing your website after making changes is also important to ensure everything is working as expected. And remember, optimization is an iterative process, so you may need to do several rounds of changes and tests to find the best configuration for your situation.

9. Use Dedicated Server or Cloud-based solutions

Sophisticated setups, such as dedicated servers with separate database servers or cloud-based solutions with multiple nodes, can significantly improve the performance of a WordPress site for several reasons:

  1. Reduced Server Response Time: Quality hosting providers offer optimized server configurations, significantly reducing server response time. When a user requests your site, the server’s response time is when it takes to respond to the request. The quicker the response time, the faster your website will load.
  2. Resource Allocation: With shared hosting, your site is on the same server as many others, and if one site experiences a spike in traffic, it can slow down all the others. On the other hand, a dedicated server means all the server’s resources are devoted to your website. This leads to faster load times and less downtime. Moreover, a separate database server ensures that your website and database operations don’t compete for resources, leading to even better performance.
  3. Scalability: High-quality hosts or dedicated server solutions can grow with your site. If your website traffic increases, your server can handle the increased load, whether it’s more disk space, higher bandwidth, or the ability to handle more simultaneous connections.
  4. Advanced Technologies: Better hosts often provide access to newer, more advanced technologies. This can include the latest versions of PHP and MySQL, faster disks like SSDs, and better network infrastructure, all of which can help improve your website’s speed.
  5. Security: Best hosting providers often provide better security options, such as sophisticated firewalls, regular malware scans, and automatic backups. This ensures your website stays secure and reduces the risk of downtime due to security issues.
  6. Support: With a quality hosting provider, you’ll have access to technical support that can help you diagnose and fix any issues. This can save you time and reduce downtime.

If we consider a cloud-based solution with multiple nodes, we add even more advantages:

  1. High Availability: Cloud-based solutions can be designed to be highly available. Even if one node fails, the traffic can be directed to other nodes, ensuring your site stays up and running. This makes it an ideal solution for websites with high traffic or websites that cannot afford any downtime.
  2. Load Balancing: Traffic can be distributed across multiple servers to balance the load and avoid any single point of failure. This helps keep your website running smoothly even under heavy load.
  3. Geographical Distribution: With cloud-based solutions, you can have servers in different locations. This means your website can be served from a server closer to the user, resulting in faster load times.

10. Use a Lightweight Theme

Theme selection is critical for the speed of your website. While it’s true that many factors contribute to your site’s overall speed, the theme is one of the most crucial elements. The Enfold theme is a great choice because it’s well-optimized for performance.

11. Disable Hotlinking

Hotlinking is when one website uses another’s resources, such as images, which can use a significant amount of bandwidth. To prevent this, you can add this code to your .htaccess file:

RewriteEngine on
RewriteCond % { HTTP_REFERER }! ^ $
RewriteCond % { HTTP_REFERER }! ^ http(s) ?://(www\.)?yourdomain.com [NC]
RewriteRule \.(jpg | jpeg | png | gif)$ - [NC, F, L]

Or, if you’re using Nginx, update your website configuration file using the following code:

location ~ .(gif|png|jpe?g)$ {
  valid_referers none blocked yourdomain.com *.yourdomain.com;
  if ($invalid_referer) {
  return 403;

Don’t forget to replace “yourdomain.com” with your actual domain.

12. Keep Your WordPress Site Updated

Always ensure that your WordPress core, themes, and plugins are up to date. Besides the security part, these updates often include performance improvements.

13. Use Lazy Loading

If your posts have a lot of images, then every time a user scrolls down your website, the images load, even if the user never reaches them. To fix this, you can use A3 Lazy Load plugin. This plugin only loads images when they are visible to the user.


Optimizing a WordPress site with tens or hundreds of thousands of posts can be a complex task, but it can be achieved by following the steps mentioned above. Remember, every site is different, so what works for one might not work for all. The important part is to test and experiment to see what provides the most significant benefit for your specific site. Lastly, using performance tools like Google’s PageSpeed Insights, GTmetrix, or Pingdom can provide additional insights into how well your site is performing and identify potential areas for further improvement.