حداقل رم مورد نیاز برای اجرای ایجنت برنامهنویسی روی VPS
برای اجرای یک ایجنت برنامهنویسی همیشه روشن، حداقل 4 GB رم و 2 vCPU پیشنهاد میشود. فرآیندهای جانبی مانند Docker build و language server باعث مصرف رم و هنگ کردن سرور میشوند.
یک VPS برای ایجنت برنامهنویسی به چه مقدار RAM نیاز دارد؟
برای یک ایجنت برنامهنویسی که بهصورت دائم در یک مخزن (repository) فعال است، با 4 GB رم و 2 هسته vCPU شروع کنید. بهمحض اینکه یک language server یا یک فرآیند Docker build به نشست (session) اضافه شود—که در اکثر مخازن از همان روز اول رخ میدهد—به 8 GB رم و 4 هسته vCPU ارتقا دهید. خودِ فرآیند ایجنت سبک است؛ آنچه منابع سرور را اشغال میکند، زنجیره ابزارهایی (toolchain) است که ایجنت از طرف شما اجرا میکند.
The data behind this chart
[
{
"plan": "Minimum viable",
"ram_gb": 4,
"vcpu": 2,
"disk_gb": 50
},
{
"plan": "Comfortable",
"ram_gb": 8,
"vcpu": 4,
"disk_gb": 100
},
{
"plan": "Team, 4 sessions",
"ram_gb": 16,
"vcpu": 8,
"disk_gb": 200
}
]هر ردیف در جدول بالا فرض را بر این میگذارد که مدل در جای دیگری اجرا میشود و از طریق یک API در شبکه فراخوانی میگردد. این فرض، تعیینکننده کل محاسبات مربوط به ابعاد سرور است، بنابراین ابتدا تکلیف آن را مشخص کنید.
آیا در حال اجرای agent هستید یا مدل؟
یک coding agent که یک مدل ابری را فراخوانی میکند، در واقع یک کلاینت شبکه است که به یک shell متصل شده است. این agent فایلها و یک طرح را به یک API میفرستد، منتظر پاسخ میماند و سپس فایلها را ویرایش کرده و دستورات را بهصورت محلی اجرا میکند. در حین انتظار، این برنامه تقریباً از هیچ CPU استفاده نمیکند. حافظهٔ مصرفی آن در حد چند صد مگابایت است؛ به همین دلیل، یک ماشین با CPU معمولی، سختافزار مناسب برای این کار است.
اجرای مدل توسط خودتان، محصول متفاوتی است که به سختافزار متفاوتی نیاز دارد. وزنهای مدل تا زمانی که سرور روشن است، در حافظه باقی میمانند. یک مدل 7 میلیارد پارامتری که به 4 بیت کوانتیزه شده است، پیش از در نظر گرفتن key/value cache که با افزایش طول context رشد میکند، به حدود 5 گیگابایت حافظه فقط برای وزنها نیاز دارد. در حالت اجرای صرف روی CPU، یک vCPU اشتراکی تنها چند توکن در ثانیه تولید میکند؛ از آنجا که یک تسک agent میتواند هزاران توکن تولید کند، کاری که با استفاده از API کمتر از یک دقیقه زمان میبرد، بهصورت محلی نزدیک به یک ساعت طول خواهد کشید. اگر هدف شما این است، باید بر اساس VRAM (حافظه ویدیویی روی GPU) سیستم را انتخاب کنید و بهجای این صفحه، آنچه یک VPS با GPU واقعاً به شما میدهد را مطالعه کنید.
تمام موارد زیر فرض را بر استفاده از مدلهای ابری قرار میدهند.
چه چیزی واقعاً از حافظه استفاده میکند
The data behind this chart
[
{
"label": "Agent CLI process, idle",
"typical_mb": 250,
"peak_mb": 600
},
{
"label": "TypeScript language server",
"typical_mb": 700,
"peak_mb": 2000
},
{
"label": "rust-analyzer, large workspace",
"typical_mb": 1200,
"peak_mb": 4000
},
{
"label": "Headless Chrome, one tab",
"typical_mb": 350,
"peak_mb": 900
},
{
"label": "Node test run, 4 workers",
"typical_mb": 1600,
"peak_mb": 3000
},
{
"label": "Docker image build",
"typical_mb": 800,
"peak_mb": 2500
}
]اینها ارقام منتشرشدهٔ معمول برای پروژههای متوسط هستند. آنها را به عنوان یک الگوی کلی در نظر بگیرید، نه تضمینی برای کد خودتان.
این نمودار شامل 6 ردیف است و agent ارزانترین آنهاست. این سرویس در حالت idle حدود 250 MB حافظه مصرف میکند، زیرا فقط یک مکالمه و یک کش فایل کوچک را نگه میدارد و کار دیگری انجام نمیدهد. یک language server برای TypeScript هنگام ایندکسگذاری به حدود 2000 MB میرسد، زیرا برای هر فایلی که از طریق tsconfig.json شما قابل دسترسی است، یک گراف نوع (type graph) میسازد و سپس آن گراف را در حافظه نگه میدارد تا به درخواستهای بعدی سریع پاسخ دهد. rust-analyzer در یک workspace بزرگ، به همین دلیل و در تمامی crateهای موجود در آن workspace، معمولاً از 4000 MB فراتر میرود.
اجرای Headless Chrome برای مرورگر به همراه یک تب، حدود 350 MB هزینه دارد و هر تب اضافی، یک پردازش سیستمعامل مجزا محسوب میشود. اجرای تست Node با چهار worker، شامل چهار پردازش Node است، بنابراین مصرف آن در اوج به حدود 3000 MB میرسد. ساخت یک Docker image در اوج به حدود 2500 MB میرسد، زیرا build، کامپایلر پروژهٔ شما را درون کانتینر اجرا میکند در حالی که daemon در حال نوشتن لایههاست.
پیش از خرید، این موارد را روی مخزن خودتان اندازهگیری کنید
sudo apt update && sudo apt install -y time
/usr/bin/time -v -o /tmp/build.rusage npm run build
grep "Maximum resident set size" /tmp/build.rusageپاسخ به صورت Maximum resident set size (kbytes): 1842160 برمیگردد. آن را بر 1024 تقسیم کنید تا به MB برسید. ابزار GNU time بزرگترین پردازش واحدی را که منتظر آن بوده گزارش میدهد، بنابراین یک build که چهار worker ایجاد میکند، مقدار کمی را نشان میدهد. برای این موارد، کل سیستم را از یک shell دوم با free -h یا systemd-cgtop -m مانیتور کنید.
ستون available از free -h را بخوانید، نه ستون free را. لینوکس تمام صفحات آزاد حافظه را صرف کش دیسک میکند، بنابراین free در یک سیستم کاملاً سالم مقدار کمی است و چیزی را نشان نمیدهد. available همان مقداری است که یک پردازش جدید واقعاً میتواند دریافت کند.
سه پیکربندی کاربردی
حداقلِ قابلاجرا: 4 گیگابایت رم، 2 هسته مجازی، 50 گیگابایت دیسک. یک نشست agent، یک مخزن، یک language server و بیلدهایی که برای اتمام آنها صبر دارید. این سطح کار میکند، اما اولین باری که اجرای یک تست سنگین با ایندکسگذاری language server همزمان شود، با OOM killer مواجه خواهید شد. swap اضافه کنید و تعداد workerهای بیلد را محدود نمایید.
سطح مطلوب: 8 گیگابایت رم، 4 هسته مجازی، 100 گیگابایت دیسک. یک agent، به همراه Docker و یک مرورگر headless برای تستها، با فضای کافی برای یک جهش در بیلد. این سطحی است که اکثر توسعهدهندگان انفرادی باید تهیه کنند. دو برابر کردن تعداد vCPU تقریباً زمان انتظار بیلد را نصف میکند و این تأثیر را بسیار بیشتر از حافظه احساس خواهید کرد.
تیمی: 16 گیگابایت رم، 8 هسته مجازی، 200 گیگابایت دیسک. چهار نشست همزمان، که هر کدام checkout و toolchain اختصاصی خود را دارند. بر اساس پیک بار اندازهگیری کنید، زیرا چهار agent بیکار تقریباً هزینهای ندارند، اما چهار اجرای تست در یک لحظه، چهار برابر ستون پیک بالا هزینه خواهد داشت.
تا آگوست 2026، تفاوت قیمت از ردیف اول تا آخر تقریباً چهار برابر قیمت ماهانه در صورتحسابهای سالانه VPS است: چند دلار در ماه برای پایینترین سطح و دهها دلار برای بالاترین سطح. پیش از برنامهریزی، لیست قیمتهای فعلی را بررسی کنید، زیرا این اعداد تغییر میکنند. سرور بهندرت بخش گرانقیمت ماجراست. برای هر کسی که روزانه از یک agent استفاده میکند، هزینه API مدل بهسرعت از هزینه سرور پیشی میگیرد، بنابراین پیش از کوچک کردن سرور، سقف هزینههای مجاز برای agent را تعیین کنید. برای خودِ بیلد، راهنمای اجرای یک agent کدنویسی روی VPS تنظیمات حساب کاربری و نحوه فعال نگهداشتن نشست پس از قطع اتصال را پوشش میدهد.
چرا فضای دیسک شما زودتر از RAM تمام میشود
The data behind this chart
[
{
"label": "Ubuntu 24.04 base and toolchain",
"typical_gb": 6
},
{
"label": "One JS monorepo checkout",
"typical_gb": 3
},
{
"label": "node_modules across 3 branches",
"typical_gb": 4
},
{
"label": "Docker images and build cache",
"typical_gb": 20
},
{
"label": "Agent logs and journal, 90 days",
"typical_gb": 2
}
]این ردیفها را با هم جمع کنید تا ببینید یک دیسک 50 گیگابایتی، پیش از آنکه حتی یک خط کد بنویسید، تقریباً پر شده است. بزرگترین آیتم تکی، Docker با حدود 20 گیگابایت است، زیرا BuildKit تمام لایههای میانی هر build را تا زمانی که به آن دستور توقف ندهید، نگه میدارد.
docker system df
docker builder prune --filter until=168hدستور docker system df فضای قابل بازیابی را به تفکیک دستهبندی چاپ میکند، پس آن را قبل و بعد از پاکسازی اجرا کنید. فیلتر until=168h کش buildهای قدیمیتر از یک هفته را حذف کرده و کش هفته جاری را نگه میدارد؛ این همان کشی است که همچنان در زمان شما صرفهجویی میکند. دستور docker image prune -a فراتر میرود و تمام imageهایی که هیچ containerای از آنها استفاده نمیکند را حذف میکند، بنابراین انتظار داشته باشید که build بعدی دوباره نیاز به pull کردن داشته باشد.
پروژههای Node به شکل عجیبتری با شکست مواجه میشوند. دستور npm install صدها هزار فایل کوچک ایجاد میکند، بنابراین ممکن است فضای دیسک از نظر inodes تمام شود در حالی که df -h همچنان گیگابایتهای خالی را گزارش میدهد. در این حالت، عملیات نوشتن با خطای No space left on device روی دیسکی که نیمی از آن خالی به نظر میرسد، متوقف میشود.
df -h /
df -i /اگر IUse% عدد 100 را نشان میدهد، دایرکتوریهای node_modules مربوط به branchهایی که دیگر روی آنها کار نمیکنید را حذف کنید، یا به pnpm مهاجرت کنید که هر نسخه از پکیج را یک بار ذخیره کرده و آن را به صورت hard-link در هر پروژه قرار میدهد.
لاگها عامل خاموش هستند. یک agent که همیشه فعال است، رونوشت نشستها را مینویسد و journal سیستمعامل systemd بهطور پیشفرض سهم بزرگی از دیسک را اشغال میکند.
sudo journalctl --disk-usage
sudo journalctl --vacuum-size=200M
du -xh --max-depth=1 / 2>/dev/null | sort -h | tailمقدار SystemMaxUse=200M را در /etc/systemd/journald.conf تنظیم کنید و sudo systemctl restart systemd-journald را اجرا کنید تا این سقف دائمی شود، زیرا یک بار vacuum کردن فقط فضای امروز را به شما بازمیگرداند.
Swap: مزایا و معایب آن
افزودن Swap ارزشمند است، زیرا باعث میشود در صورت مصرف بیش از حد حافظه، بهجای متوقف شدن پردازش، سرعت آن کاهش یابد. اندازه آن را معادل نصف RAM و حداکثر تا 4 GB در نظر بگیرید. دلیلی برای افزایش بیشتر آن در یک سرور build وجود ندارد.
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
swapon --showدستور swapon --show اکنون باید /swapfile را با اندازهای که تعیین کردهاید نمایش دهد. بدون خط /etc/fstab، پس از reboot بعدی، Swap از بین میرود و سرور بیسروصدا به رفتار قبلی خود بازمیگردد. اگر fallocate پاسخ Operation not supported را میدهد، فایل را با sudo dd if=/dev/zero of=/swapfile bs=1M count=4096 بسازید و از chmod ادامه دهید.
echo 'vm.swappiness = 10' | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl --systemمقدار کم swappiness به kernel دستور میدهد که پیش از انتقال حافظه برنامهها به دیسک، cache دیسک را بازیابی کند؛ این کار باعث حفظ پاسخدهی language server میشود.
حال بخشی که Swap پنهان میکند: هنگامی که یک job واقعاً به حافظهای بیش از ظرفیت سرور نیاز دارد، kernel بهجای اجرای build شما، وقت خود را صرف جابهجایی صفحات بین RAM و دیسک میکند. هیچچیز crash نمیکند، اما همه چیز بهکندی پیش میرود و load average بالا میرود، در حالی که CPU بیکار است.
vmstat 1 10اعداد غیرصفر ثابت در ستونهای si و so به معنای swapping مداوم است؛ بنابراین راهحل، کاهش concurrency یا افزایش RAM است و هرگز نباید Swap را بیشتر کرد. در یک سرور کوچک، sudo apt install -y zram-tools امکان استفاده از Swap فشرده در RAM را فراهم میکند که در /etc/default/zramswap تنظیم میشود. این روش بسیار سریعتر از swap file است و با صرف RAM برای ذخیره RAM، به مدیریت صفحات غیرفعال (cold pages) کمک میکند، اما برای buildهایی که به حافظه کاری واقعی نیاز دارند، کارآمد نیست.
چرا ایجنت کدنویسی شما به نظر میرسد که هنگ کرده است
این مورد، شایعترین خطای تشخیصدادهشده در سرورهای کوچک ایجنت است. یک دستور هیچ خروجیای برنمیگرداند، ایجنت منتظر میماند و نشست (session) منجمد به نظر میرسد. پردازش توسط OOM killer (قاتل کمبود حافظه) در هسته سیستمعامل کشته شده است. چون پردازش سیگنال SIGKILL را دریافت کرده، نتوانسته است خطا را چاپ کند، لاگ را تخلیه کند یا به ایجنت بگوید چه اتفاقی افتاده است. ایجنت فقط یک نتیجه خالی و بدون پیام خروج میبیند.
هسته سیستمعامل این رخداد را ثبت میکند:
sudo dmesg -T | grep -iE "out of memory|killed process"
sudo journalctl -k -b | grep -i oomیک خط واقعی به این شکل است:
[Thu Aug 6 11:02:14 2026] Out of memory: Killed process 4711 (node) total-vm:4210880kB, anon-rss:3820104kB, file-rss:0kB, shmem-rss:0kB, UID:1000 pgtables:8236kB oom_score_adj:0anon-rss نشان میدهد که آن پردازش در لحظه مرگ چقدر حافظه اشغال کرده بود. دقت کنید کدام پردازش انتخاب شده است: هسته سیستمعامل امتیازدهی را عمدتاً بر اساس حافظه در حال استفاده انجام میدهد، بنابراین اغلب به جای بیلد (build) که باعث عبور از حد مجاز شده، سرور زبان یا خودِ ایجنت را میکشد. دقیقاً به همین دلیل است که نشانه خطا به صورت "ایجنت خراب شد" دیده میشود.
در داخل Docker، همین رویداد اثر انگشت تمیزتری بر جای میگذارد. کانتینر با کد 137 خارج میشود که برابر با 128 بهعلاوه سیگنال 9 است.
docker ps -a
docker inspect "$(docker ps -lq)" | grep -i oomkilled"OOMKilled": true تأیید میکند که کانتینر به جای کرش کردن خودبهخودی، به محدودیت حافظه خود برخورد کرده است.
راه حل این است که برای دستور سنگین، سقف مشخصی تعیین کنید تا به جای ایجنت، بیلد متوقف شود:
systemd-run --user --scope -p MemoryMax=4G -- npm run buildاکنون بیلد در 4 GB کشته میشود و ایجنت زنده میماند؛ این کار باعث میشود یک هنگِ مرموز به یک دستور شکستخورده معمولی با کد خروجی خوانا تبدیل شود. این کار به یک نشست کاربری systemd نیاز دارد، بنابراین اگر فقط از طریق SSH به سرور دسترسی دارید، loginctl enable-linger $USER را اجرا کنید. MemoryHigh= پردازش را در آستانه تعیینشده محدود (throttle) میکند و به جای کشتن آن، سرعتش را کاهش میدهد؛ این تنظیم اغلب برای بیلدی که ترجیح میدهید به آرامی تمام شود، گزینه مناسبتری است.
اعمال محدودیت حافظه با استفاده از Compose
اگر ابزارهای agent در کانتینر اجرا میشوند، سقف مصرف حافظه را در فایل Compose تعیین کنید تا در هر بار اجرا اعمال شود.
services:
agent:
image: node:22-bookworm
deploy:
resources:
limits:
memory: 2g
cpus: "1.5"نسخه Docker Compose v2 محدودیت deploy.resources.limits را روی یک docker compose up معمولی اعمال میکند، بنابراین نیازی به استفاده از swarm mode نیست. کلید قدیمیتر mem_limit: 2g همچنان کار میکند. راهنمای کامل محدودیتهای حافظه در Compose به بررسی رزروها و اتفاقاتی که هنگام رسیدن کانتینر به سقف مجاز رخ میدهد، میپردازد. اگر Docker هنوز روی سرور نصب نشده است، ابتدا Docker را روی یک VPS نصب کنید.
یک دام رایج وجود دارد که وقت زیادی از کاربران میگیرد. کانتینری که به 2 GB محدود شده است، همچنان مقدار /proc/meminfo میزبان و تعداد CPUهای میزبان را میبیند، زیرا هیچکدام از این موارد در namespace ایزوله نشدهاند. یک ابزار تست که تعداد workerهای خود را بر اساس تعداد CPU انتخاب میکند، هشت worker را داخل یک کانتینر 2 GB روی یک میزبان با هشت vCPU اجرا میکند و سپس با خطای 137 متوقف میشود. این مقادیر را بهصورت دستی تنظیم کنید:
npx jest --maxWorkers=2
export NODE_OPTIONS=--max-old-space-size=1536مقدار --max-old-space-size بر حسب MB است و سقف V8 heap را تعیین میکند. آن را کمتر از محدودیت کانتینر تنظیم کنید تا Node بهجای ناپدید شدن، خطایی تولید کند که قابل خواندن باشد:
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memoryاین پیام یک مزیت بزرگ است، زیرا محدودیت نقضشده و فرآیندی که باعث آن شده را مشخص میکند. OOM killer هرگز چنین کاری نمیکند.
اجرای چندین نشست عامل روی یک سیستم
برنامهریزی را بر اساس هر نشست انجام دهید، نه هر شخص. دو نشست روی یک مخزن واحد همچنان به معنای دو سرور زبان، دو مجموعه کش ساخت در حافظه و دو اجرای تست در صورتی است که هر دو عامل همزمان مشغول شوند. به همین دلیل است که ردیف تیم به 16 گیگابایت افزایش مییابد.
برای هر کاربر یک سقف سخت تعیین کنید تا یک نشست خارج از کنترل نتواند کل سیستم را از کار بیندازد:
id -u alice
sudo mkdir -p /etc/systemd/system/user-1001.slice.d
printf '[Slice]\nMemoryMax=6G\n' | sudo tee /etc/systemd/system/user-1001.slice.d/limit.conf
sudo systemctl daemon-reload
systemctl show user-1001.slice -p MemoryMaxمقدار 1001 را با UID که id -u چاپ کرده است جایگزین کنید. پس از ورود کاربر به سیستم، systemctl show باید MemoryMax=6442450944 را چاپ کند. هنگامی که مجموع مصرف نشست آن کاربر از 6 گیگابایت فراتر رود، هسته سیستمعامل یک پردازش را در slice مربوط به او متوقف میکند و سایر نشستها به کار خود ادامه میدهند. برای عاملی که به جای ترمینال به عنوان یک سرویس اجرا میشود، به جای آن MemoryMax= را در فایل unit آن قرار دهید؛ این الگویی است که باید هنگام میزبانی عامل به عنوان یک سرویس همیشه فعال دنبال کنید.
FAQ
آیا 2 GB رم برای یک coding agent کافی است؟
برای خودِ پردازش agent، بله. اما برای کاری که انجام میدهد، بهندرت. این agent حدود 250 MB رم اشغال میکند، اما یک language server برای TypeScript میتواند در یک مخزن (repository) با اندازه متوسط به 2000 MB برسد و همین بهتنهایی یک سرور 2 GB را به استفاده از swap میکشاند. 2 GB برای ویرایش فایلهای پیکربندی و اسکریپتهای کوچک مناسب است. برای هر کاری که شامل کامپایل یا اجرای تست باشد، 4 GB را بهعنوان حداقل در نظر بگیرید.
آیا برای اجرای یک coding agent روی VPS به GPU نیاز دارم؟
اگر agent از طریق API با یک مدل ابری در ارتباط باشد، خیر. آن بار کاری وابسته به شبکه است، بنابراین یک VPS با CPU معمولی گزینه مناسبی است و GPU فقط با هزینه بسیار بالاتر بلااستفاده میماند. شما تنها زمانی به GPU نیاز دارید که خودِ مدل روی همان سرور اجرا شود؛ در آن صورت، پرسش از رم به VRAM و اندازه مدل تغییر میکند.
چقدر swap باید به VPS مربوط به agent اضافه کنم؟
نصف مقدار رم، تا سقف حدود 4 GB. فضای swap شما را در برابر جهشهای کوتاه مصرف حافظه محافظت میکند، زیرا هسته سیستمعامل میتواند صفحات غیرفعال را به دیسک منتقل کند تا از کشتهشدن پردازش جلوگیری شود. این کار حافظه قابلاستفاده اضافه نمیکند. اگر vmstat 1 ترافیک مداومی را در ستونهای si و so نشان میدهد، سرور دچار thrashing شده است و راهحل، کاهش تعداد workerهای موازی یا ارتقای پلن سرور است.
چرا coding agent من در میانه build متوقف میشود؟
این build تقریباً بهطور قطع توسط OOM killer هسته سیستمعامل متوقف شده است. چون سیگنال SIGKILL ارسال میشود، هیچ پیامی چاپ نمیشود و agent در انتظار لولهای (pipe) میماند که هرگز پر نمیشود. دستور sudo dmesg -T | grep -i "killed process" را اجرا کنید و نام پردازش و مقدار anon-rss آن را بررسی کنید. برای رفع مشکل، build را با systemd-run --user --scope -p MemoryMax=4G محدود کنید و تعداد workerها را کاهش دهید، یا به یک رده بالاتر از نظر رم مهاجرت کنید.