ETag, Last-Modified, Server Cache
@fastify/caching
Add HTTP cache hints to your responses and an optional server-side cache helper. Real performance gains come from combining this with a CDN or reverse proxy.
What you'll learn
- Install @fastify/caching
- Use reply.etag and expiresIn
- Combine with a reverse-proxy or CDN cache
@fastify/caching does two things: it sets cache-related response headers and exposes a small in-process cache. Most of the real performance wins come from getting the headers right and letting a CDN do the heavy lifting.
Install & Register
npm install @fastify/caching import caching from '@fastify/caching'
await app.register(caching, {
privacy: 'public',
expiresIn: 60,
}) That sets Cache-Control: public, max-age=60 on every response unless you override it.
Per-Route Headers
For hot, cacheable endpoints, set explicit headers and an ETag.
import { createHash } from 'node:crypto'
app.get('/articles/:slug', async (req, reply) => {
const article = await app.db.articles.findUnique({ where: { slug: 'x' } })
const etag = createHash('sha1').update(JSON.stringify(article)).digest('hex')
reply
.header('Cache-Control', 'public, max-age=300, stale-while-revalidate=60')
.header('ETag', etag)
.send(article)
}) If the request includes If-None-Match matching the ETag, return 304 to skip the body.
CDN First
The plugin gives you the headers, but the speed comes from the CDN. Front Fastify with Cloudflare, Fastly, or a Varnish layer, and the same response can serve thousands of clients for a single origin hit. Combine stale-while-revalidate with a short max-age for invisible refreshes.