منتجك شغّال طول الأسبوع، وأول ما يجي إعلان أو يدخل عدد ناس مرة وحدة، يبدأ يطلع خطأ مثل remaining connection slots are reserved for roles with the SUPERUSER attribute، أو في الإصدارات قبل 16 remaining connection slots are reserved for non-replication superuser connections، أو sorry, too many clients already، أو من الـ pooler في Supabase max client connections reached. الصياغة تختلف حسب الإصدار والخدمة، والمعنى واحد: قاعدة البيانات وصلت للحد الأقصى من الاتصالات المفتوحة، وترفض أي اتصال جديد.
إيش يعني بالضبط
قاعدة بيانات Postgres، اللي تحت Supabase و Neon و Replit وغيرها، تسمح بعدد محدود من الاتصالات في نفس الوقت. العدد يعتمد على حجم الخطة، والخطط الصغيرة حدها صغير. كل اتصال مثل خط هاتف مفتوح: إذا كل الخطوط مشغولة، المتصل الجديد يسمع «الخط مشغول»، حتى لو أغلب الخطوط المفتوحة ما فيها أحد يتكلم.
ليش يصير في المنتجات المبنية بالذكاء الاصطناعي
- كل طلب يفتح اتصال جديد: الكود ينشئ اتصال بقاعدة البيانات داخل كل طلب، وما يسكّره. مع مستخدم واحد ما تحس. مع مئة، الخطوط تخلص.
- الاستضافة بدون سيرفر (serverless): على Vercel و Netlify، كل طلب ممكن يشتغل في نسخة منفصلة من الكود، وكل نسخة تفتح اتصالها. زحمة صغيرة تعني عشرات النسخ وعشرات الاتصالات.
- Prisma أو مكتبة مشابهة بدون إعداد: الكود ينشئ
PrismaClientجديد في كل ملف أو كل طلب، وكل واحد يفتح مجموعة اتصالات. - الاتصال المباشر بدل الـ pooler: Supabase يعطيك أكثر من رابط اتصال. الذكاء الاصطناعي غالبًا ياخذ أول رابط، وهو الاتصال المباشر، مو اللي مصمّم للاستضافة بدون سيرفر.
كيف تتأكد بنفسك
- افتح سجل الأخطاء في منصة النشر وقت الزحمة: إذا الخطأ يطلع مع ارتفاع الزوار ويختفي لما يخف، هذا هو.
- في Supabase، افتح SQL Editor وشغّل:
select usename, application_name, state, count(*) from pg_stat_activity group by 1, 2, 3 order by 4 desc;النتيجة تقول لك كم اتصال مفتوح، ومن أي تطبيق، وكم منهاidleيعني فاتح وما يسوي شي. عدد كبير منidleعلامة إن الكود ما يسكّر اتصالاته. - شوف رابط الاتصال في إعدادات منصة النشر: في Supabase، رابط الـ pooler في وضع transaction يكون على المنفذ
6543. إذا الرابط على5432والاستضافة serverless، هذا غالبًا السبب.
الحل اللي لا تسويه
- ترقية الخطة كأول حل. الخطة الأكبر ترفع الحد، والكود اللي يفتح اتصال لكل طلب يوصل للحد الجديد بعد زحمة أكبر شوي. تدفع أكثر وتبقى المشكلة.
- إعادة تشغيل قاعدة البيانات كل ما طلع. يسكّر الاتصالات مؤقتًا، ويقطع على المستخدمين اللي في نص عملية.
- رفع حد الاتصالات بيدك من إعدادات Postgres. كل اتصال ياخذ ذاكرة، ورفع الحد فوق قدرة السيرفر يبطّئ كل شي أو يوقفه.
الحل الصح
- pooler: خلّ التطبيق يتصل عن طريق الـ pooler، وهو وسيط يشارك عدد قليل من الاتصالات الحقيقية بين طلبات كثيرة. في Supabase اسمه Supavisor، ووضع transaction هو المناسب للاستضافة بدون سيرفر.
- اتصال واحد للتطبيق كله: المكتبة اللي تكلّم قاعدة البيانات تنعمل مرة وحدة وتنستخدم في كل مكان، مو في كل طلب.
- حد صغير لكل نسخة: في الاستضافة بدون سيرفر، كل نسخة تحتاج اتصال واحد أو اثنين، مو عشرة. Prisma مثلًا يحتاج إعدادات خاصة عشان يشتغل مع الـ pooler في وضع transaction، ومكتوبة في توثيقه.
- سكّر اللي ما تحتاجه: أي سكربت أو مهمة تفتح اتصال، تسكّره لما تخلص.
بعد التعديل، اختبر بزحمة مصطنعة على نسخة تجريبية، مو على منتجك الحقيقي. الطريقة في درس منتجك يبطّأ لما يكثر الناس؟.
تبي أحد يشوفه معك؟
إذا الخطأ يطلع عندك الحين، مكالمة استشارية نوصل فيها للسبب ونغيّر الإعداد معك. إذا تجهّز لإطلاق أو حملة إعلانية وتبي تعرف إيش بيتعطّل قبلها، تدقيق جاهزية الإطلاق يغطي الأداء والتكلفة ضمن جوانبه. وإذا منتجك على Replit، شوف مشاكل Replit الأشهر.