From 3d51b3b83a222b40ea457cb31443e342c79d9b9e Mon Sep 17 00:00:00 2001 From: Zareian Date: Sun, 11 Oct 2026 22:27:54 +0330 Subject: [PATCH] CLAUDE.md: capacity under load (measured vs estimated), open launch-day caps, how to load-test the shared server safely Co-Authored-By: Claude Opus 5.5 --- CLAUDE.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 28e009d..fc7c2f3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -451,6 +451,31 @@ preferred setup, because there is then no key to leak. **Never let the server ru `django-insecure-…` fallback from `config/settings.py`: that string is committed here, so anyone who can read this repo can forge a token for any user.** +## ظرفیت زیرِ بار — روی سرور از ۲۰۲۶-۱۰-۱۱ (بک‌اند `98bf05f`، فرانت `16cf5c9`) + +گزارشِ سینیور: `~/Desktop/گزارشات Tadrisino/گزارش-۳۳/ظرفیتِ-اپ-زیرِ-بار.html` (و PDF). بکاپِ تغییرهای یک‌باره‌ی +سرور: `.deploy-backups/env-before-db-pool-20261011-202211` (حذفِ `DB_CONN_MAX_AGE`) و +`unit-gunicorn-mathapp-before-db-pool-20261011-202211.service` (حذفِ `--workers 3`؛ تعداد حالا در `gunicorn.conf.py`). + +- **سنجیده:** لپ‌تاپ با Postgresِ ۱۴ و `max_connections=60` (مثلِ سرور)، ۱۰۰ کاربرِ هم‌زمان: پیش از pool ۲۱٪ خطای ۵۰۰، + بعد ۰ خطا و ۷۱۴ درخواست در ثانیه (۴ worker). روی خودِ سرور، نسخه‌ی موقتِ ۲ worker، ۴۰ کاربر، ۱۵ ثانیه: ۰ خطا، + ۱۱۲ درخواست در ثانیه، p99 ۰٫۶۷ ثانیه، وقتی CPUِ ماشین ~۸۰٪ مشغول بود. ثبتِ جواب ۱۵٫۴→۱۱ ms، `/api/home` ۱۲٫۴→۸٫۶ ms. +- **برآورد (نه سنجیده):** ۱۰۰۰ تا ۱۵۰۰ بازیکنِ هم‌زمان (فرض: یک درخواست در ۸ ثانیه)، ۴ تا ۶ هزار آنلاین. سقفِ واقعی CPUِ + مشترک است، نه حافظه یا دیتابیس؛ worker بیشتر روی همین ماشین ظرفیت نمی‌سازد، CPUِ دیگران را می‌گیرد. +- **سقف‌های تنظیمی:** پیامک ۳۰۰ در روز برای کلِ سامانه و دستیار ۳۰۰۰ سوال در روز — هر دو برای روزِ لانچ کم‌اند و + **تصمیمِ مالک/سینیور** است (`OTP_SMS_GLOBAL_DAILY_MAX`، `AI_GLOBAL_DAILY_MAX` در `.env`؛ هیچ‌کدام الان در `.env` نیست). + هر IP: ۱۰۰ درخواستِ کد و ۳۰۰ ثبتِ کد در ساعت (تصمیمِ مالک، برای کلاس روی یک وای‌فای). +- **پیشنهادشده، ساخته نشده:** جلسه‌ی آزمون به سبکِ دولینگو (سوال و کلید با هم دانلود، سنجش روی گوشی، ارسالِ یک‌جا + و سنجشِ دوباره در سرور) بارِ بازی را حدوداً نصف می‌کند؛ کلید روی گوشی می‌رود، پس تصمیمِ محصولی است. کلِ محتوا + فشرده ≈ ۱ مگابایت است. +- **نسنجیده:** GapGPT با ۴۸ سوالِ هم‌زمان، کاوه‌نگار زیرِ رگبار، رفتارِ ArvanCloud با صدها نفر از یک IP. + +**تستِ بار روی سرور (ماشینِ مشترک، با احتیاط):** throttleهای پروداکشن دست نمی‌خورند؛ یک gunicornِ موقت روی سوکتِ جدا +در `~/mathapp-v2/.lt/` با `READ_THROTTLE_RATE` بالا و **`DB_POOL_MAX_SIZE=4 --workers 2`** (تا با ۳۲ اتصالِ پروداکشن از ۵۷ +نگذرد)، فقط GET با یک حسابِ تستی، ۱۵ ثانیه، و آخرش پاک کردنِ `.lt`. در اسکریپت `wait` نزن: منتظرِ همان gunicornِ پس‌زمینه +می‌ماند و تا ابد گیر می‌کند (یک بار شد). روی لپ‌تاپ: `ab` در هم‌زمانیِ بالا خودش خراب می‌شود و macOS صفِ اتصال را ۱۲۸ و +پورت‌های کلاینت را محدود می‌کند؛ gunicorn را روی سوکتِ unix بالا بیاور و بارزنِ پایتونی بزن. + ## بکاپ: کپیِ زنده روی سرورِ ۲۴۷ — از ۲۰۲۶-۱۰-۱۰ **هر تغییرِ دیتابیس لحظه‌ای به سرورِ دیگری می‌رود؛ بکاپِ شبانه‌ی خودمان (`backup_db`/`backup_verify`/cron) حذف شد.**