Case StudyMedia & Publishing

99.97% Fewer Server Errors and Faster, Steadier Pages for a News Site with 830K Monthly Visits

From Next.js to Astro: How we made a high-traffic news platform with 830K monthly visits faster, more stable, and more reliable.

Solution
Framework Migration & Performance Tuning
Impact
Faster, Stable, Error-Free Pages
99.97% Fewer Server Errors and Faster, Steadier Pages for a News Site with 830K Monthly Visits

The Context

With approximately 830,000 monthly visits and 1.9 million pageviews, this news platform needed to deliver fast, reliable access to content, even during sudden traffic spikes.

But heavy JavaScript, frequent server errors, and shifting page elements were affecting the reading experience. The challenge was to improve performance and stability without disrupting a platform that thousands of readers rely on every day.

Our Services

Framework migration (Next.js to Astro) Core Web Vitals tuning CDN and caching strategy on Cloudflare Real-user performance measurement

The Mission

Our mission was to make the platform faster, more stable, and easier to use, while ensuring it could handle high traffic without compromising the reading experience.


The Challenge

The site ran on Next.js, with React rendering on every page. For a publication that is mostly text, images and ads, that meant shipping and running a lot of JavaScript that readers never needed. Three problems showed up in the real-user data.

Errors under load. In the week before the migration, the site returned an average of 12,852 HTTP 500 errors a day, with a worst day of 25,596.

Layout shift. Ads, embeds and images loaded without reserved space, so content moved as the page filled in. CLS at the 75th percentile was 0.051 across the site and 0.144 on the homepage, where readers land first. Only 83.8% of page views had a "good" CLS score.

Slow tails. Most readers got a reasonable Largest Contentful Paint, but the slowest tenth waited over two seconds (LCP p90 of 2,163 ms), and the homepage LCP p75 was 1,751 ms.

The Solution

We cut over to Astro on 22 October and then tuned the new stack in small, measured deploys, checking real-user data after each one.

1. Server-rendered Astro with only the interactivity readers use

Pages are now rendered on the server by Astro, with Alpine.js for the few interactive pieces such as navigation and search. There is no client-side React app to download and start, and the HTML itself is 10% smaller (86 KB to 77 KB).

2. Consent first, everything else when it's needed

The consent manager now loads first, and telemetry and ad start-up wait for it. Ad zones and article embeds only activate when they come within about 600 px of the viewport, and tweets load on demand instead of with the page.

3. Reserved space for everything that loads late

Image dimensions are inferred so the browser reserves the right space, ad slots hold their height before the ad arrives, and social embeds get a placeholder of the right size. Fonts are self-hosted WOFF2 subsets with the headline font preloaded, so text no longer reflows when a web font arrives.

4. Right-sized images and a cache that actually caches

Article and card images are served responsively, with visible images prioritised and the rest deferred. On Cloudflare, we set cache rules for fonts and images (7 days at the edge, 1 day in the browser) and fingerprinted static assets so they can be cached safely.

What each deploy changed

22 Oct, 18:50 — Cutover to Astro

HTTP 500s fall from thousands a day to a handful.

22 Oct, 21:49 and 22:16 — Consent first, lazy ads and embeds

Third parties are deferred, offscreen ads and embeds wait until they're needed, and a mobile navigation shift is removed.

23 Oct, 17:36 — Reserved media and ad slots

Space is held for images and ads, and CMS requests run concurrently. LCP p90 drops from 2,132 ms to 1,624 ms.

24 Oct, 00:30–01:11 — Cache rules, responsive images, self-hosted fonts

Static-asset revalidations fall from about 15% to zero, the cache hit share climbs from about 8% to about 25%, and CLS p75 drops to effectively zero.

24 Oct, 12:26 and 25 Oct, 16:35 — Homepage image priority, reserved social embed space

CLS reaches 0 and stays there every day from 26 Oct.

26 Oct and 27 Oct — Editorial photo optimisation, on-demand tweet embeds

Page load keeps falling, to a p75 of 2,676 ms on 28 Oct.

The Results

Server errors are effectively gone. From 23 October the site has returned an average of 4 HTTP 500 errors a day, down from 12,852, a 99.97% drop, while serving the same audience.

The slowest page loads got the biggest win. LCP p75 fell 15% (1,176 ms to 1,003 ms) and LCP p90 fell 24% (2,163 ms to 1,649 ms). On the homepage, LCP p75 fell 33%, from 1,751 ms to 1,176 ms. The share of page views with a "good" LCP rose from 92.0% to 95.5%.

Layout shift is gone. CLS p75 has been 0 every day since 26 October, down from 0.051. On the homepage it went from 0.144 to 0.021 across the after period. The share of page views with a "good" CLS score rose from 83.8% to 93.5%.

Pages finish loading sooner. Page load times were already trending down in the week before the migration, so we measure from the 21 October level rather than the weekly average. Against that day, page load p75 fell from 3,201 ms to 2,850 ms on 27 October, the last full day measured (−11%), and to 2,676 ms on 28 October. Page load p90 fell from 5,912 ms to 5,053 ms (−15%).

The CDN now does its job. Before the change, about 15% of static-asset requests were revalidated with the origin and only 7.6% were served straight from the edge cache. After the cache rules went live, revalidations dropped to effectively zero and the hit share rose to about 25–28% a day.

Results Dashboard

99.97%

Fewer HTTP 500 errors

0

CLS p75 since 26 Oct

−24%

LCP p90

−33%

Homepage LCP p75

What These Improvements Mean for the Business

Beyond the technical metrics, these improvements create a stronger foundation for the platform's growth.

  • More reliable access to content: Fewer server errors mean a lower risk of readers encountering unavailable pages, especially during traffic spikes.
  • Better reading experience: Faster loading and more stable page layouts make it easier for visitors to consume content without interruptions.
  • Stronger SEO foundations: Improved Core Web Vitals support the technical performance signals that contribute to page experience.
  • More efficient infrastructure: Improved caching reduces unnecessary requests to the origin server and helps the platform handle traffic more efficiently.

The result is a faster, more dependable platform built to support both its readers and its future growth.

Metric Before (14–21 Oct) After (23–28 Oct) Change
LCP p751,176 ms1,003 ms−15%
LCP p902,163 ms1,649 ms−24%
Homepage LCP p751,751 ms1,176 ms−33%
CLS p750.0510 daily since 26 Oct—
Homepage CLS p750.1440.021—
Good CLS share83.8%93.5%—
Good LCP share92.0%95.5%—
Page load p753,201 ms (21 Oct)2,850 ms (27 Oct)−11%
Static asset cache hit share7.6%~25% (from 25 Oct)—
HTTP 500s per day12,8524−99.97%
HTML size86 KB77 KB−10%

Real-user data from Cloudflare Web Analytics (sampled) and Cloudflare HTTP request analytics. 28 Oct is a partial day.

Interaction stayed fast throughout, with INP p75 at 68 ms, well inside Google's "good" threshold of 200 ms.

The Tech Stack

Astro Alpine.js Cloudflare CDN Cloudflare Web Analytics GitLab CI WOFF2 self-hosted fonts

Is Your Website Struggling with Speed or Stability?

Slow pages, server errors, or poor Core Web Vitals? Let's identify what's holding your website back and find the right solution.