The quickest reliable way to speed up a Ghost blog on Ubuntu is to keep one well-supported Ghost origin server, then place HTTP caching and, when traffic warrants it, a CDN or reverse-proxy cache in front of that server. Start with Ubuntu 24, Node.js 22 LTS, MySQL 8.0, NGINX, systemd and at least 1 GB of memory. Use Ghost-CLI so the standard database, web server, TLS, migration, user-permission and service pieces are configured consistently.
Antihost offers Linux VPS plans with full root access, unlimited traffic on a 1 Gbps port and a 14-day free trial.
Measure an uncached request before changing anything. Then fix the actual bottleneck, enable Ghost’s documented caching for suitable Content API responses, add Redis only when persistent or larger object caching is useful, and cache public traffic at the edge. Ghost does not support clustering or sharding as the recommended scaling pattern; for growth, its official guidance is a cache and/or CDN in front of one Ghost instance.
As an Amazon Associate I earn from qualifying purchases.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →The architecture that usually delivers the biggest speed improvement
A Ghost installation has two different performance problems that are often confused. The origin server must execute Ghost, query MySQL and render or serve content. Public visitors, however, frequently request the same pages and assets. Repeating that work for every visitor is unnecessary. A cache can answer repeat requests without contacting Ghost, reducing time to first byte and protecting the origin during traffic spikes.
Use this order of operations:
- Confirm the supported software stack and available memory.
- Observe CPU, RAM, disk I/O, database activity and request timings while reproducing the slowdown.
- Make sure NGINX and Ghost are working as a clean production stack, preferably installed or checked against Ghost-CLI’s layout.
- Enable HTTP caching for responses that can safely be reused.
- Add Redis for selected cache data when process-memory caching is insufficient or must survive a restart.
- Put a CDN or reverse-proxy cache in front of the single origin and bypass it for administration and authenticated traffic.
- Measure again after each change.
This sequence avoids adding services that do not address the bottleneck. A CDN will not repair a saturated MySQL server, and Redis will not make a public page faster if every request is already being served from an effective edge cache.
#1 Best Overall
Check the supported Ubuntu production baseline
Before tuning, verify that the server resembles Ghost’s supported production arrangement. A faster configuration built on an unsupported runtime can fail during an upgrade or migration and is difficult to troubleshoot.
| Component | Baseline for this guide | Why it matters |
|---|---|---|
| Operating system | Ubuntu 24 | Provides the current platform assumed by the stated production stack. |
| Node.js | Node.js 22 LTS | Ghost’s application runtime; an LTS release reduces runtime churn. |
| Database | MySQL 8.0 | Stores posts, settings, members and other Ghost data. |
| Web server | NGINX | Terminates connections, handles TLS and can serve or cache requests before they reach Ghost. |
| Service manager | systemd | Keeps the Ghost process running and restarts it after failures or reboots. |
| Memory | At least 1 GB | Leaves room for Ghost, MySQL, NGINX and the operating system; caches require additional headroom. |
Ghost-CLI is the useful reference point even if the current server was assembled manually. Its production setup configures MySQL, NGINX, SSL, migrations, a low-privilege Ghost user and systemd. Compare a hand-built installation with those components before changing cache behavior. Missing TLS termination, an application running as an overly privileged user, or a service that is not supervised can appear to be a performance issue while actually being an operational defect.
Recommended Free Tools
Check memory before adding a cache
Ghost, MySQL and the operating system compete for RAM. A cache that simply consumes the last available memory can trigger swapping or the Linux out-of-memory killer, making response times worse. Record memory use under normal traffic and during a realistic burst. If the machine is already near its limit, fix that constraint or increase capacity before enabling another resident service.
Measure the slowdown instead of guessing
Take two measurements for the same public URL: one that reaches the origin without a warm cache and one delivered through the intended cache. Record time to first byte (TTFB), total load time and the response status. Repeat enough times to distinguish a one-off network delay from a consistent origin problem. The useful comparison is not “the page feels faster”; it is whether the cache removes origin work and lowers TTFB for repeat visitors.
While reproducing the request, inspect:
- Ghost application logs for errors, slow operations and repeated restarts. Ghost-CLI’s
ghost logcommand is the first place to look for application output. - NGINX errors and access logs for upstream timeouts, connection failures and unexpectedly uncached responses.
- CPU utilisation and load average to identify a compute-bound process.
- Memory and swap activity;
free -hgives a quick view of available RAM. - Disk capacity and I/O latency; a full or busy volume can delay both MySQL and Ghost.
- MySQL saturation, including connections and query activity, when database-backed requests are slow.
Useful host checks include sudo nginx -t to validate NGINX syntax, systemctl status nginx to confirm the web server is healthy, free -h for memory and df -h for disk space. Run the checks while the problem is occurring, not only after it has disappeared. Change one variable at a time so a later improvement can be attributed to a specific action.
Rank #2
Use Ghost’s HTTP caching for repeatable API responses
Ghost documents a caching configuration with maxAge values for Content API responses. The setting tells compatible intermediaries and clients how long a response may be reused. It is most appropriate for responses whose content does not need to change on every request, such as stable public API output used by a theme or an integration.
Choose what can safely be cached
Start with public, read-only responses. A longer freshness period reduces origin requests but delays the appearance of an edit until the cached response expires or is purged. A shorter period reflects publishing changes sooner but produces more origin traffic. Set the duration according to the editorial requirement of the specific response rather than using one aggressive value for every endpoint.
Do not cache a response merely because it is technically possible. Administration, login, account and other authenticated requests can contain user-specific data. Those paths should reach Ghost directly or use a private cache policy. The cache must also vary correctly when a response depends on cookies, authorization headers or other request identity.
Validate cache headers and behavior
After applying the documented configuration, inspect the response headers from the public URL. Confirm that the intended Cache-Control policy is present, that a repeat request is a cache hit, and that a content edit is eventually reflected within the selected freshness window. Test an uncached request separately from a warm-cache request; otherwise a browser cache can hide an origin problem.
HTTP caching is often enough for a small publication because it reduces work without introducing another database-backed service. It also lets a CDN or reverse proxy make its own edge-caching decision from explicit freshness information.
When Redis is useful—and when it is not
Ghost documents a Redis adapter for cache data that benefits from persistence across process restarts or should not be constrained by Ghost’s process memory. The documented examples cache image sizes and the tags Content API endpoint. Redis is therefore a targeted object-cache choice, not a blanket replacement for page caching.
| Question | Redis can help when… | Redis is unlikely to help when… |
|---|---|---|
| What is being cached? | Repeated object or API data, such as image-size information or tags data, is expensive to recreate. | The dominant cost is rendering a complete public page that an edge cache could serve directly. |
| What happens after a restart? | Retaining cache data across a Ghost restart avoids rebuilding the cache immediately. | The cache is small, disposable and cheap to regenerate. |
| Where is capacity limited? | The desired cache is larger than the Ghost process should hold in memory. | The server has little spare RAM; Redis would intensify memory pressure. |
| What administration is required? | You can monitor Redis memory, connectivity and eviction behavior as another production service. | You want the fewest moving parts and have not identified a cache-specific bottleneck. |
Configure and observe it conservatively
Use the Redis adapter and settings documented for your Ghost version rather than copying an example intended for another release. Confirm that Ghost can connect, then watch Redis memory use and eviction behavior under normal and peak traffic. A cache that evicts hot entries constantly, or a connection failure that blocks application requests, is not an improvement.
Redis does not remove the need for HTTP cache-control. Keep public page and API freshness rules explicit, and use Redis for the internal data that benefits from it. If the only goal is to reduce repeated delivery of an unchanged public page, an HTTP cache in NGINX or a CDN is usually the more direct layer.
Add a CDN or reverse-proxy cache in front of the origin
Ghost’s official scaling guidance recommends putting a cache and/or CDN in front of the blog. This layer can terminate TLS, serve cached public responses close to visitors and shield the one Ghost process from repeated requests. It is the preferred scale path for traffic growth because it reduces origin load without requiring unsupported application clustering.
Define cache scope
Begin with publicly readable pages and static responses. Decide which URLs may be stored, how freshness is determined, and how an edit invalidates or expires an entry. Keep administration and authenticated paths out of the shared cache. The bypass rule must be based on the request’s authentication and cookie state, not merely on whether a URL happens to look like a page.
Rank #4
A reverse proxy on the same server can reduce repeated origin work but still shares the server’s CPU, memory and network limits. A CDN adds distributed edge capacity and is generally the lower-effort option when readers are geographically dispersed or traffic is bursty. The exact monthly price is not stated in the available Ghost material and depends on the provider, transfer volume and features.
Protect TLS and origin access
Keep HTTPS enabled from the visitor to the cache and, where supported, from the cache to the origin. Ensure the origin accepts traffic only through the intended proxy or otherwise remains protected; do not expose an administrative endpoint through a public shared cache. Verify that the proxy forwards the host and protocol information Ghost needs to generate correct canonical URLs and redirects.
Check invalidation after publishing
Publish or edit a test post and request it through the CDN. Confirm that readers see the new version according to the stated cache policy. If the result remains stale longer than intended, shorten the freshness period for that content or use the cache’s purge mechanism. If every edit requires a full-site purge, the invalidation design may be too coarse for a frequently updated publication.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCan multiple Ghost servers make the blog faster?
Not as a supported Ghost scaling strategy. Ghost states that clustering and sharding are not supported and recommends reducing the infrastructure to one node with caching. Adding application nodes behind a load balancer can introduce shared-session, file-storage, migration and cache-consistency problems without delivering a supported architecture.
Keep one Ghost origin, make that origin healthy, and scale the layer that is explicitly intended to absorb repeat traffic. If a single origin remains saturated after effective caching, investigate the measured bottleneck—memory, database, disk, application work or network—rather than adding an unsupported cluster by assumption.
Best Value
End-to-end implementation procedure
- Record a baseline. Save TTFB, total load time, status code and response headers for an uncached public request and for a warm request. Note the server’s CPU, memory, disk and database state at the same time.
- Verify the foundation. Confirm Ubuntu 24, Node.js 22 LTS, MySQL 8.0, NGINX, systemd and at least 1 GB of memory. Use Ghost-CLI’s arrangement as the checklist for TLS, migrations, the low-privilege user and service supervision.
- Remove immediate faults. Correct NGINX syntax errors, Ghost restarts, exhausted disk space, swap pressure, upstream timeouts and database saturation before tuning cache policy.
- Set HTTP freshness. Apply Ghost’s documented
cachingandmaxAgesettings to suitable Content API responses. Keep private and authenticated responses out of shared caches. - Warm and test. Request the same public resource repeatedly, inspect headers and verify that the second request is served according to the intended policy. Test a newly edited resource to confirm the freshness window is acceptable.
- Add Redis only if justified. Configure the documented adapter for cache data such as image sizes or tags when persistence or capacity beyond process memory is valuable. Monitor memory and eviction behavior.
- Place the edge layer. Configure a CDN or reverse proxy to cache public responses, bypass administration and authenticated traffic, preserve HTTPS and origin headers, and provide a defined invalidation method.
- Re-measure one change at a time. Compare the new uncached and cached timings with the baseline, and keep the change only if it improves the target metric without creating stale or private-content failures.
Choosing between the available caching layers
| Layer | Cache scope | Survives restart? | Invalidation control | Origin-load reduction | Operational complexity | TLS and admin handling | Monthly cost |
|---|---|---|---|---|---|---|---|
| Ghost HTTP caching | Configured Content API responses | Depends on the Ghost process and configured adapter | Controlled by freshness settings and expiration | Reduces repeated API work | Lowest; part of Ghost configuration | Handled by the surrounding NGINX/CDN design | Not stated by the cited Ghost material |
| Local Redis | Selected internal objects, including documented image-size and tags examples | Yes, when configured for persistence and available after restart | Redis eviction and application cache rules | Reduces repeated object or API computation | Additional service, memory and monitoring | Does not replace the public TLS or admin-path policy | Not stated by the cited Ghost material |
| Same-server reverse-proxy cache | Public HTTP responses | Depends on the proxy cache configuration | Proxy expiration and purge rules | Can remove repeated requests from Ghost while sharing host resources | Moderate NGINX configuration | Proxy terminates TLS; private paths must bypass it | Not stated by the cited Ghost material |
| CDN | Public HTTP responses at edge locations | Usually, according to the provider’s cache policy | Provider expiration, purge and revalidation controls | Highest shielding for geographically distributed or bursty public traffic | Lower origin administration, but provider configuration is required | Handles edge TLS; authenticated and admin requests must bypass shared caching | Not stated by the cited Ghost material |
The practical choice follows the bottleneck. Use Ghost’s own HTTP settings for straightforward API reuse, Redis for targeted persistent object caching, and a CDN or reverse proxy for public page delivery. Combining them is reasonable when each layer has a distinct job; stacking all three without measurement only increases failure modes.
Common failure modes and fixes
The cache never records a hit
Check that the response is public, carries cacheable headers, and is not marked private or no-store. Cookies, authorization headers and bypass rules can intentionally prevent sharing. Inspect the proxy’s cache-status information and compare the request with a plain uncached origin request.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Visitors see old content
The freshness period is longer than the editorial requirement, or invalidation is not reaching every cache layer. Reduce the relevant maxAge or proxy TTL, or use the layer’s purge mechanism for edited content. Do not solve a single stale endpoint by disabling all caching.
Adding Redis made the server slower
Check RAM, swap and Redis eviction statistics first. A memory-starved host can spend more time reclaiming memory than serving Ghost. Remove Redis if the measured workload does not benefit from persistent or larger object caching, or move the cache to a host with appropriate capacity.
NGINX or the CDN returns errors after a change
Validate NGINX configuration before reloading it, inspect upstream and application logs, and temporarily bypass the cache for a controlled diagnostic request. Restore the last known-good proxy policy, then reintroduce one rule at a time. Confirm that the origin is reachable over the expected protocol and that forwarded host information produces the correct Ghost URL.
Several origin servers produce inconsistent results
This is a sign of an unsupported clustering design rather than proof that more nodes are needed. Return to one Ghost origin and use a cache/CDN for public scale, then diagnose the original bottleneck with measurements.
What Ghost’s release figures do—and do not—tell you
The Ghost Foundation reported in its 2022 Ghost 5.0 changelog that requests per second increased by 20%, memory usage at boot fell by 15%, peak memory usage fell by 22% and boot time improved by 16%. Those are release-era aggregate figures, not a performance guarantee for an individual Ubuntu installation. Hardware, theme code, database size, traffic mix, cache hit rate and configuration all change the result. Use them as context for keeping Ghost current, not as a substitute for measuring your own origin and cache.
Quick Recap
Final decision checklist
- Is the stack on Ubuntu 24 with Node.js 22 LTS, MySQL 8.0, NGINX and systemd?
- Does the server have at least 1 GB of memory plus headroom for the selected caches?
- Have you captured uncached and cached TTFB and total load time?
- Are CPU, memory, disk I/O and MySQL activity understood during the slowdown?
- Are Ghost’s documented Content API cache settings applied only where stale data is acceptable?
- Is Redis solving a measured persistence or capacity problem rather than being added by default?
- Does the CDN or reverse proxy cache public traffic while bypassing administration and authenticated requests?
- Is there a tested invalidation or expiration path after publishing?
- Is the architecture one supported Ghost origin rather than an unsupported cluster?
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




