چطور یک پروژه طراحی سایت نکست جی اس رو از حالت معمولی به مقیاس‌پذیر تبدیل کردم

چند ماه پیش یک پروژه سپرده شده بود که مشتری میخواست یک وبلاگ حرفه‌ای (با چند بخش محتوایی جداگانه) با نکست بسازه. اهدافش اینا بود:

  • سایت سریع باشه،

  • قابلیت کامنت و لایک داشته باشه،

  • تعداد بازدید هر پست رو نشون بده

  • و در آینده بتونه چند نویسنده داشته باشه بدون اینکه سایت کند بشه.


مرحله اول: تحلیل نیازها

وقتی پروژه رو بررسی کردم، دیدم مشتری فقط یک سایت استاتیک ساده نمی‌خواد؛ نیاز به ویژگی‌های پویا داره:

  • - نمایش تعداد بازدید واقعی هر پست (view count)

  • - امکان لایک و اشتراک‌گذاری با شمارش

  • - کامنت‌ها (با قابلیت پاسخ به پاسخ)

  • - مدیریت چند بخش محتوایی (مثل چند وبلاگ کوچک زیر یک دامنه)

  • - پنل ساده برای نویسنده‌ها (بدون اینکه هر بار کل سایت rebuild بشه)

به من یک تمرین نشون داد که از نکست و مارک داون و نمایش تعداد بازدیدها استفاده میکرد. اگر فقط از نکست با مارک داون یا حتی ISR (Incremental Static Regeneration) استفاده می‌کردم، برای ویژگی‌های پویا مثل کامنت و شمارنده بازدید به مشکل می‌خوردیم. پس نیاز به یک بک‌اند واقعی داشتیم.


انتخاب دیتابیس اصلی: PostgreSQL

برای داده‌های اصلی (پست‌ها، کاربران، کامنت‌ها، روابط بین‌شون) مستقیم رفتم سراغ PostgreSQL. دلایلم این‌ها بود:

- روابط پیچیده رو خیلی خوب مدیریت می‌کنه

(مثل پست → کامنت → پاسخ به کامنت)

  • - Row Level Security (RLS) داره که برای پروژه‌های چندکاربری (multi-tenant) عالیه

  • - ACID کامل → داده‌ها گم نمی‌شن حتی اگر مشکلی پیش بیاد

  • - با ابزارهایی مثل Prisma یا Drizzle خیلی راحت در نکست جی اس کار می‌کنه

سرویس PostgreSQL ابری انتخاب کردیم (با رم کافی و ترافیک نامحدود) تا سرور و بکاپ‌ها رو خودمون مدیریت نکنیم. و خودکارسازی این فرایندها انجام بشه.


اما چالش شمارنده‌ها کجا بود؟

اگر بخوایم هر بار که کسی پست رو باز می‌کنه، یک UPDATE روی جدول PostgreSQL بزنیم (مثل `view_count = view_count + 1`)، در بازدیدهای بالا:

  • - فشار زیادی روی دیتابیس می‌ره

  • - latency یا تاخیر افزایش پیدا می‌کنه

  • - اگر چند کاربر همزمان بازدید کنن، ممکنه race condition پیش بیاد (هرچند PostgreSQL خوب مدیریت می‌کنه، اما بهینه نیست)

اینجا بود که ردیس Redis وارد پروژه شد.

چرا ردیس Redis؟

Redis رو دقیقاً برای همین کارها ساختن:

  • - سرعت فوق‌العاده (زیر ۱ میلی‌ثانیه برای عملیات ساده)

  • - دستورهای اتمیک مثل `INCR` (افزایش شمارنده بدون race condition)

  • - in-memory بودن → هیچ دیسکی در کار نیست، پس فوق‌العاده سریع

  • - می‌تونیم بازدیدها رو موقت در ردیس Redis نگه داریم و هر چند دقیقه (مثلاً هر ۵-۱۰ دقیقه) با یک job ساده sync کنیم به PostgreSQL (تا داده‌ها دائمی بشن)

چطور پیاده کردم؟

  • - برای هر پست یک کلید در Redis ساختیم: `post:views:{postId}`

  • - وقتی کاربر پست رو باز می‌کرد، با یک Server Action یا Route Handler:

  • - چک می‌کردیم آیا این کاربر قبلاً در ۳۰ دقیقه اخیر بازدید کرده (با یک set موقت یا IP-based)

  • - اگر نه → `INCR post:views:{postId}`

- برای نمایش تعداد بازدید: اول از Redis می‌خوندیم (اگر نبود fallback به PostgreSQL)

  • - هر ۱۰ دقیقه یک cron job (با Upstash QStash یا یک edge function) بازدیدها رو جمع می‌زد و به جدول اصلی PostgreSQL منتقل می‌کرد.


نتیجه پروژه

  • - سایت خیلی سریع‌تر شد (زمان پاسخ APIها برای شمارنده‌ها از ~۵۰-۱۰۰ میلی‌ثانیه به زیر ۵ میلی‌ثانیه رسید)

  • - PostgreSQL فقط برای عملیات مهم (نوشتن کامنت، ذخیره پست جدید) فشار می‌دید، نه برای هر بازدید

  • - مشتری بعداً گفت حتی در ساعات پیک (چند هزار بازدید همزمان) سایت هیچ کندی نداشت

  • - هزینه کلی هم پایین موند، چون ردیس Redis (مثل Upstash) فقط بر اساس مصرف واقعی پول می‌گیره

درس های این پروژه برای شما

در طراحی سایت مدرن با نکست جی اس، همیشه لازم نیست همه چیز رو در یک دیتابیس نگه داریم.

  • - PostgreSQL برای داده‌های مهم، روابط و پایداری → انتخاب اول

  • - Redis برای کارهای سریع، موقت و پرتکرار (کش، شمارنده، realtime) → مکمل عالی

اگر پروژه تون در حال رشد باشه، این ترکیب (Postgres + Redis) یکی از بهترین الگوهای سال ۲۰۲۵-۲۰۲۶ است. خیلی از وبلاگ‌های بزرگ و اپلیکیشن‌های محتوایی همین روش رو استفاده می‌کنن.


اگر تو هم پروژه مشابهی داری و می‌خوای در مورد پیاده‌سازی دقیق‌تر (مثل کد Prisma + Redis یا تنظیم sync) صحبت کنیم، خوشحال می‌شم کمک کنم!