A Next.js demonstration application showcasing the capabilities of cached-middleware-fetch-next - a fetch wrapper that enables caching in Next.js edge middleware using Vercel's Runtime Cache.
View Live Demo - Experience real-time caching behavior with performance metrics and cache status indicators.
This application demonstrates how middleware-level caching can dramatically improve performance by caching slow API responses. The demo includes:
- SWR (Stale-While-Revalidate) Caching: Serves cached data instantly while refreshing in the background
- Performance Metrics: Real-time comparison of cached vs uncached response times
- Cache Status Visibility: Clear indicators showing HIT, MISS, or STALE cache states
- Background Refresh: Non-blocking cache updates using Vercel's
waitUntil()
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ User Request │───▶│ Proxy │───▶│ Slow API │
│ (Browser) │ │ (cachedFetch) │ │ (1000ms delay)│
└─────────────────┘ └──────────────────┘ └─────────────────┘
│
▼
┌──────────────────┐
│ Vercel Runtime │
│ Cache │
└──────────────────┘
- Proxy (
proxy.ts): Intercepts requests to/and fetches from the demo API with caching - Demo API (
/api/demo): Simulates a slow external service with a 1000ms delay - Cache Layer: Uses Vercel Runtime Cache for persistence across requests
- Cache Status:
MISS - Response Time: ~1000ms (full API delay)
- Behavior: Fresh data fetched from API
- Cache Status:
HIT - Response Time: ~0-5ms (served from cache)
- Behavior: Cached data served instantly
- Cache Status:
STALE - Response Time: ~0-5ms (stale data served instantly)
- Behavior: Background refresh triggered via
waitUntil()
- Cache Status:
MISS - Response Time: ~1000ms (cache expired, fresh fetch required)
- Behavior: Cache completely expired, new data fetched
The demo uses the following caching strategy:
const response = await cachedFetch('/api/demo', {
next: {
revalidate: 5, // Consider stale after 5 seconds
expires: 30, // Absolute expiry after 30 seconds
tags: ['demo-api']
}
});- Fresh Period: 0-5 seconds (instant cache hits)
- Stale Period: 5-30 seconds (instant response + background refresh)
- Expired: After 30 seconds (fresh fetch required)
- Node.js 18+
- npm/yarn/pnpm
# Clone the repository
git clone https://github.com/yourusername/middleware-cache-test.git
cd middleware-cache-test
# Install dependencies
npm install
# Start development server
npm run devVisit http://localhost:3000 to see the demo.
The demo can optionally use a custom API hostname:
# .env.local (optional)
API_HOSTNAME=your-custom-api-host.comIf not set, defaults to the production demo API.
| Scenario | Response Time | Cache Status | User Experience |
|---|---|---|---|
| First Visit | ~1000ms | MISS | Initial delay |
| Cached Response | ~0-5ms | HIT | Instant response |
| Stale Response | ~0-5ms | STALE | Instant response + background refresh |
| Expired Cache | ~1000ms | MISS | Fresh fetch required |
Performance Improvement: Up to 200x faster response times for cached requests.
The demo exposes cache information through response headers:
X-Cache-Status: Cache hit status (HIT,MISS,STALE)X-Cache-Age: Age of cached data in secondsX-Cache-Expires-In: Time until cache expires (if applicable)
- Package Documentation: cached-middleware-fetch-next
- Next.js Middleware: Official Documentation
- Vercel Runtime Cache: Edge Functions Documentation
Contributions are welcome! Feel free to:
- Report bugs or issues
- Suggest improvements to the demo
- Submit pull requests
MIT License - see the LICENSE file for details.