All writing

Article

I'm Building a GPU PC, So I Made It a Private AI Server for My Friends

How GPUShare splits public from private, where the inference actually runs, and what the cost figures do and do not measure.

21 March 2026 · 3 min read

Self-hosted AI Economics

A dark illustration of two wireframe globes, each with a lightning bolt at its centre, beside a panel of text lines.

GPUShare started with a practical question: if a desktop GPU is idle most of the day, can a trusted group share it without turning a home PC into a pretend cloud region?

It is an open-source, self-hosted app for local AI inference and queued Blender rendering. There are accounts and invites, API keys, an OpenAI-compatible chat API, optional cloud routing, MCP tool connections and usage accounting, all behind a React interface.

The current request path

Browser or API client
        ↓
Vercel-hosted React frontend
        ↓
Cloudflare Tunnel → public FastAPI middleware
        ↓  X-Internal-Token
private hardware backend
        ├─ Ollama on the host
        ├─ Blender render worker
        ├─ optional Cloudflare R2 file storage
        └─ optional OpenRouter cloud models

The middleware owns JWT and API-key authentication, account and admin operations, billing integration, aggregation, and short-lived in-process caches. Hardware requests are forwarded to a second FastAPI service using a shared secret. The Cloudflare ingress points at the middleware, not the backend. Docker Compose does still publish the backend port on the host, so the application-level internal token remains an important boundary.

Local AI, with an explicit cloud option

The standard /v1/chat/completions and model endpoints follow OpenAI-compatible shapes. Responses can stream over Server-Sent Events, and structured tool calls are normalised for both Ollama and OpenRouter. Local Ollama requests are serialised through a process-local GPU queue.

OpenRouter is optional. A selected OpenRouter model sends the request to that provider, as does the configured auto model when its rules pick cloud. It is not an automatic failover that retries a failed Ollama request. When local-only routing is selected, model inference runs on the host; when a cloud route is selected, prompt data leaves the host under that provider’s terms.

What “electricity cost” means in the implementation

GPUShare does not directly meter the wall-power consumed by each inference request. It estimates local usage with configured or detected GPU and system wattage, the configured electricity tariff, estimated token counts, and a default throughput assumption. Render estimates use elapsed job time and configured wattage. Optional OpenRouter requests use provider pricing.

estimated local cost = estimated kWh × configured electricity tariff

The calculator below is illustrative and uses the same kind of assumptions; it is not a utility-meter reading.

GPUShare cost calculator

See what local inference actually costs on a 5070 Ti against cloud APIs.

504,000
1500
$0.01$0.60

Per response

—

Daily

—

Monthly

—

vs cloud

—

Cloud equivalent (GPT-4o mini): —

Local (Llama 3.1 8B): —

The accounting record itself is append-only: usage charges, cloud usage, render usage, top-ups, payments, and adjustments are separate ledger entry types, and the displayed balance is their sum.

Blender rendering is a trusted-user feature

Users can submit .blend files with frame, resolution, engine, sample, and output settings. The backend validates the file type and size, removes Blender text blocks, uploads the cleaned file to optional R2 storage, and queues a separate worker. Completed output is packaged and exposed through a time-limited signed URL.

Removing embedded text blocks is a useful guardrail, but it is not a full process, filesystem, network, or resource sandbox. The current upload path is suitable only for trusted invited users, not arbitrary public files.

Operational limits

  • If the host or Cloudflare Tunnel is offline, local inference and render submission are offline.
  • Cloud routing is optional model selection, not automatic availability failover.
  • Local cost and energy values are estimates, not direct per-request measurements.
  • The cross-platform setup scripts automate detection and configuration, but their current migration command still names the removed fastapi Compose service after the backend/middleware split.
  • The repository currently has no first-party automated test suite, so the project should not be presented as production-hardened managed infrastructure.

What I was actually building is the layer around the hardware: an interface and an accounting system for a machine that is private, finite and often switched off. It is a tool for a handful of people I know, and that is the whole scope.

The source is available at github.com/Slaymish/GPUShare.