Running a LLM router on a 2009 netbook. It works.
Repo: https://github.com/turbolego/freellmapi
FreeLLMAPI β 34 free providers, 635 free model endpoints, OpenAI-compatible /v1



Hardware and Goal
- Intel Atom D525 Dual-core 1.8 GHz
- No SSE4.1/4.2, no AVX, no AES-NI
- 2 GB RAM total
- Debian-based, SSH only
Goal: run freellmapi as a fallback proxy for Hermes at localhost:3001. Forever-free tiers only. Run as non-root user hermes.
Step-by-step Installation Guide
Step 1 β Prepare the system
Update packages and install Node.js 20+:
sudo apt update
sudo apt install -y curl git nodejs npm ca-certificates
node --version # v20.x or newer required
npm --versionCreate the non-root user:
sudo useradd -m -s /bin/bash hermes || trueStep 2 β Clone and reset ownership
sudo -u hermes -i
cd ~/
git clone https://github.com/turbolego/freellmapi-atom-d525.git freellmapi
cd freellmapi
rm -rf node_modules package-lock.json
chown -R hermes:hermes ~/freellmapiThis removes any previous build artifacts and ensures ownership is correct.
Step 3 β Install dependencies
Install production dependencies only. Atom D525 has limited CPU/RAM, so skip dev packages and audits.
npm ci --omit=dev --no-audit --no-fundStep 4 β Set environment for constrained hardware
export NODE_OPTIONS=--max-old-space-size=384
export NODE_ENV=production
export PORT=3001NODE_OPTIONS=--max-old-space-size=384 caps V8 heap to 384 MB to stay inside the 2 GB RAM budget.
Step 5 β Test manually
node server.jsIn another terminal, health check:
curl -s http://localhost:3001/v1/models | jq '.data | length'
curl -s http://localhost:3001/healthYou should see a model count and a JSON health response.
Step 6 β Create systemd service with memory limits
Create /etc/systemd/system/freellmapi.service:
[Unit]
Description=FreeLLMAPI fallback proxy for Hermes
After=network-online.target
[Service]
User=hermes
Group=hermes
WorkingDirectory=/var/lib/hermes/freellmapi
Environment=NODE_ENV=production
Environment=PORT=3001
Environment=NODE_OPTIONS=--max-old-space-size=384
ExecStart=/usr/bin/node server.js
Restart=on-failure
RestartSec=5
MemoryMax=512M
MemoryHigh=384M
MemoryLow=128M
CPUQuota=80%
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=/var/lib/hermes/freellmapi
[Install]
WantedBy=multi-user.targetEnable and start:
sudo systemctl daemon-reload
sudo systemctl enable --now freellmapi.service
systemctl status freellmapiStep 7 β Configure Hermes fallback
In Hermes, set provider:
Provider: http://localhost:3001/v1
Model: auto
Test:
curl -s -X POST http://localhost:3001/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"auto","messages":[{"role":"user","content":"ping"}]}' | jq .choices[0].message.contentStep 8 β Free-tier discipline
- Forever-free tiers only
- Router picks best available model, auto failover on rate-limit
- Per-key usage tracking, encrypted keys
- Cut dead/non-free providers decisively
Step 9 β Monitoring on 2GB
ps -o pid,rss,cmd -C node
systemctl show freellmapi --property=MemoryCurrentKeep RSS <400 MB, heap <384 MB.
Step 9.5 β Performance Metrics
After running for a while, you can check the performance of freellmapi on the Atom D525. Below are sample metrics from a system running for over two weeks:
| Metric | Value |
|---|---|
| Resident Set Size (RSS) | ~142 MB |
| Heap limit (NODE_OPTIONS) | 384 MB |
| MemoryMax (systemd) | 256 MB (effective) |
| MemoryHigh (systemd) | 384 MB |
| MemoryLow (systemd) | 128 MB |
| CPUQuota | 80% |
| Uptime | 2 weeks 3 days |
| Total CPU time | 1h 52m |
You can get current metrics with:
# Check memory usage
ps -o pid,rss,cmd -C node
systemctl show freellmapi --property=MemoryCurrent,MemoryMax
# Check service status for detailed stats
systemctl status freellmapi
# Check CPU time
grep 'CPU:' /proc/$(pgrep -f node)/stat 2>/dev/null || echo 'Use ps -o cputime -C node'
# Or simpler:
ps -o pid,pcpu,pmem,etime,cmd -C nodeNote: Actual numbers will vary based on workload, number of providers, and request volume.
Benchmark Results
The following benchmark results were collected from the Atom D525 system running FreeLLMAPI:
| Metric | Value |
|---|---|
| Model count | 271 |
| Sample models | auto, fusion, qwen-3.8-27b, nemotron-3-ultra-550b, muse-glimmer-30b, gemma-4-31b |
| Request latency (min) | 307ms |
| Request latency (max) | 12971ms |
| Request latency (mean) | 2088ms |
| Request latency (median) | 503ms |
| Request latency (stdev) | 4009ms |
| Successful requests | 10/10 |
| Memory usage (RSS) | 135 MB |
| Memory usage (systemd) | 147 MB |
| CPU usage | 0.2% |
Note: The latency variation is due to:
- Free-tier providers with rate limits and throttling
- Network latency to distributed providers
- Model startup time for cold requests
- Auto-failover when a provider is rate-limited
The system remains stable under these conditions, with RSS consistently below 400 MB and CPU usage well under the 80% quota.
Step 10 β Security
Run as hermes:hermes, never root. Tailscale only. Weekly npm audit. Security audit priority.
Result: one OpenAI-compatible endpoint, 34 free providers, stable on Atom D525, non-root, reproducible.
This document shows how to run FreeLLMAPI on Intel Atom D525 2GB RAM as a non-root hermes:hermes fallback proxy for Hermes with systemd memory limits.
Links
- Repo: https://github.com/turbolego/freellmapi
- Dashboard: https://freellmapi.co