Reduce Server Response Time (TTFB): Get HTML to the Browser Faster
Time to First Byte measures how fast your server responds. Learn what causes slow TTFB and how to optimize server performance, caching, and infrastructure.
Time to First Byte (TTFB) is the foundation of your page's performance. Nothing can render until the HTML arrives — and TTFB measures how long that takes.
Why TTFB Matters
- Blocks everything — FCP, LCP, and all rendering waits for the HTML
- Compounds with every request — CSS, JS, and image requests each have their own TTFB
- Reflects server health — high TTFB usually indicates server-side problems
| TTFB | Rating | Impact |
|---|---|---|
| ≤ 200ms | Excellent | Maximum headroom for other metrics |
| 200–800ms | Acceptable | May impact FCP/LCP on slow connections |
| > 800ms | Poor | Likely causing poor Core Web Vitals |
Diagnosing TTFB
Chrome DevTools
- Open DevTools → Network
- Click on the HTML document request
- Look at the Timing tab — "Waiting for server response" is your TTFB
WebPageTest
Run a test and check the "First Byte" time in the waterfall chart. Test from multiple locations to see geographic variance.
How to Fix High TTFB
1. Use a CDN
A CDN serves content from servers close to the user:
- Without CDN: User in Tokyo → Server in Virginia = 200ms+ round trip
- With CDN: User in Tokyo → Edge server in Tokyo = 20ms round trip
Popular CDN options:
- Vercel Edge Network — automatic with Vercel deployments
- Cloudflare — free tier available, easy setup
- AWS CloudFront — integrates with AWS infrastructure
- Fastly — real-time purging, edge compute
2. Server-Side Caching
Don't regenerate pages for every request:
// Next.js — Incremental Static Regeneration
export const revalidate = 3600; // Regenerate at most every hour
export default async function Page() {
const data = await fetchData();
return <PageContent data={data} />;
}
For API routes:
export async function GET(request) {
const data = await fetchData();
return Response.json(data, {
headers: {
"Cache-Control": "public, s-maxage=3600, stale-while-revalidate=86400",
},
});
}
3. Optimize Database Queries
Slow queries are the most common cause of high TTFB in dynamic apps:
-- ❌ BAD — scans entire table
SELECT * FROM posts WHERE published = true ORDER BY created_at DESC;
-- ✅ GOOD — uses index, limits results
SELECT id, title, slug, excerpt, created_at
FROM posts
WHERE published = true
ORDER BY created_at DESC
LIMIT 20;
-- Add the index
CREATE INDEX idx_posts_published_date ON posts(published, created_at DESC);
4. Implement Redis/In-Memory Caching
Cache expensive computations:
import Redis from "ioredis";
const redis = new Redis();
async function getPageData(slug) {
// Check cache first
const cached = await redis.get(`page:${slug}`);
if (cached) return JSON.parse(cached);
// Cache miss — fetch from database
const data = await db.query("SELECT ...", [slug]);
// Cache for 1 hour
await redis.setex(`page:${slug}`, 3600, JSON.stringify(data));
return data;
}
5. Use Static Generation When Possible
If content doesn't change per-request, generate it at build time:
// Next.js — Static Generation
export async function generateStaticParams() {
const posts = await getAllPosts();
return posts.map(post => ({ slug: post.slug }));
}
// This page is generated at build time — TTFB is just CDN latency
export default async function PostPage({ params }) {
const post = await getPost(params.slug);
return <Article post={post} />;
}
6. Avoid Cold Starts in Serverless
Serverless functions (Vercel, AWS Lambda) can have 1-3 second cold starts:
- Keep functions warm with scheduled pings
- Reduce bundle size — smaller functions cold-start faster
- Use edge functions — lighter runtime, faster cold starts
- Provision concurrency — keep instances pre-warmed
7. Eliminate Redirects
Each redirect adds a full round-trip:
301 → 302 → 200 (three TTFB waits!)
Audit your redirects and update links to point directly to final URLs.
Quick Wins Checklist
- Add a CDN if you don't have one (Cloudflare free tier works)
- Enable server-side caching (ISR, Cache-Control headers)
- Add database indexes for common queries
- Cache expensive queries in Redis or memory
- Use static generation for content that doesn't change per-request
- Measure TTFB from multiple geographic locations
- Eliminate redirect chains
Ready to stop wasting ad spend?
Track your landing page performance, monitor Core Web Vitals, and calculate exactly how much slow pages cost you.
Start Free — No Credit Card