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

FreeLLMAPI dashboard β€” Models page with the monthly token budget

The free tier, stacked

Feature overview

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 --version

Create the non-root user:

sudo useradd -m -s /bin/bash hermes || true

Step 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 ~/freellmapi

This 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-fund

Step 4 – Set environment for constrained hardware

export NODE_OPTIONS=--max-old-space-size=384
export NODE_ENV=production
export PORT=3001

NODE_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.js

In another terminal, health check:

curl -s http://localhost:3001/v1/models | jq '.data | length'
curl -s http://localhost:3001/health

You 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.target

Enable and start:

sudo systemctl daemon-reload
sudo systemctl enable --now freellmapi.service
systemctl status freellmapi

Step 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.content

Step 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=MemoryCurrent

Keep 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:

MetricValue
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
CPUQuota80%
Uptime2 weeks 3 days
Total CPU time1h 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 node

Note: 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:

MetricValue
Model count271
Sample modelsauto, 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 requests10/10
Memory usage (RSS)135 MB
Memory usage (systemd)147 MB
CPU usage0.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