Cache Tags ve revalidateTag (Next.js)
Kısaca: Next.js, sunucu verilerini yalnızca zamana göre değil, adlandırılmış bir “etiket” altında önbelleğe alabilir — revalidateTag() çağrısı ise yalnızca o etiketi taşıyan önbelleğe alınmış verileri geçersiz kılar, önbelleğin geri kalanına dokunmaz.
Biraz daha ayrıntılı: TTL (yaşam süresi, güvenlik ağı olarak) ile, altta yatan verileri gerçekten değiştiren eylemlerde hedefli, anında geçersiz kılmanın birleşimine olanak tanır. Next.js 16’dan beri revalidateTag() ikinci bir argüman gerektirir (bir önbellek profili, örneğin "max") — stale-while-revalidate davranışını kontrol eder: etiket bayat olarak işaretlenir, ancak bu ikinci argümanın olmadığı eski Next.js sürümlerindeki gibi artık tüm istemciler için mutlaka hemen ve sert biçimde silinmez.
Bizim bağlamımız: Emzett’te app/utils/homeContentCache.ts, ana sayfa yazılarını/öne çıkan incelemeleri unstable_cache ile, 60 sn TTL + her yazı değişikliğinde revalidateTag(HOME_CONTENT_CACHE_TAG, "max") ile hedefli geçersiz kılma kullanarak önbelleğe alır. Mağazanın ürün listesi için bilerek KULLANILMAZ — sınırlı sürümlerde canlı stok kesin olmalıdır; önbelleğe alınmış bir “yalnızca 3 kaldı” fazla satışa yol açabilir.
Ayrıntılı
Temel kalıp
Bir işlev unstable_cache() ile sarılır ve bu sırada bir veya daha fazla etiket alır:
const getHomeContent = unstable_cache(
async () => db.query.posts.findMany({ where: eq(posts.featured, true) }),
["home-content"],
{ tags: [HOME_CONTENT_CACHE_TAG], revalidate: 60 },
);Bir yazı değiştiğinde, sorumlu sunucu eylemi revalidateTag(HOME_CONTENT_CACHE_TAG, "max") çağırır — önbellek girdisi, hâlâ süren 60 saniyelik TTL’den bağımsız olarak hemen geçersiz ilan edilir. Bu, iki dünyanın avantajlarını birleştirir: güvenlik ağı olarak TTL (bir geçersiz kılma unutulursa önbellek en geç TTL’den sonra yeniden tazedir), bilinen değişikliklerde anında tutarlılık için hedefli geçersiz kılma.
Neden her şey için tek bir genel etiket olmasın?
Birkaç bağımsız önbellek alanı olduğunda önemli: olabildiğince belirgin ve ayrık etiketler kullan (her şey için tek bir genel etiket yerine) — aksi hâlde bir yerdeki küçük bir değişiklik, tamamen farklı, değişmemiş önbellekleri de gereksiz yere geçersiz kılar; bu da önbelleğe almanın amacını (daha az veri tabanı yükü) boşa çıkarır. Yaygın bir gelenek etiketleri hiyerarşik adlandırmaktır (örneğin posts, posts:featured, posts:${postId}) ve bir değişiklikte yalnızca etkilenen düzeyi geçersiz kılmaktır — tek bir değişen yazı, kendisi öne çıkarılmadıysa tüm öne çıkanlar listesini mutlaka geçersiz kılmak zorunda değildir.
Yalnızca zamana dayalı önbellekten farkı
Saf TTL tabanlı önbellek (etiketsiz revalidate: 60) daha basittir, ancak yapısal bir dezavantajı vardır: gerçek bir veri değişikliği ile bir sonraki TTL bitişi arasında kullanıcılar bayat veri görür — 60 saniyelik TTL ile en kötü durumda neredeyse bir dakika boyunca. Etiket tabanlı geçersiz kılma, BİLİNEN değişiklikler için bu aralığı pratikte sıfıra indirir; TTL ise BİLİNMEYEN veya unutulmuş değişiklik yolları için (örneğin düzenli kod yolunun dışında doğrudan bir veri tabanı müdahalesi) hâlâ güvenlik ağı görevi görür.
Next.js 16’dan beri ikinci argüman
revalidateTag() fonksiyonunun Next.js 16’dan beri zorunlu ikinci argümanı ("max" gibi bir önbellek profili) geçersiz kılmanın ne kadar agresif olduğunu kontrol eder. Önceki Next.js sürümleri yalnızca tüm istemciler için aynı anda sert, anında bir silme bilirdi — yeni, daha ayrıntılı model ise bunun yerine, tarayıcıda/CDN’de tutulan ve zaten teslim edilmiş yanıtların mutlaka hemen atılmasına gerek olmadığı, arka planda tazelenebildiği stale-while-revalidate benzeri davranışa izin verir. Bu, eski eğitim bilgisinin yapay zekâ asistanlarını yanıltabileceği Next.js 16 tuzaklarından biridir, çünkü revalidateTag() eskiden yalnızca tek bir argüman kabul ederdi.
Ayrıca bak: Next.js App Router, React.cache(), TTL