app.nzapp
AppsProjectsReposPullsChatIntegrationsGatewayModelsEvalsToolsDatasetsMCPDeploysPricingBlogDocsAssistantsCharactersArtMusic
Sign inStart building
Agent stack
Cloud coding agentAgents SDKIntegrationsBrowser agentMonitors & auto-agentsSchedulersAgent skillsMCP serversDeep research
Models & API
AI GatewayModel catalogModel evalsModel spacesPlaygroundText to imageImage to 3DText to 3DMusic & SFXAudio editorMedia optimizerAI art & libraryChatAPI referenceSchemaBecome a provider
Compute & hosting
DeploysAddonsPostgres hostinggobed vector searchSite hostingAnalyticsCog GPU hostingRL trainingBuilds & CIWorkersTask queuesDomainsGit hosting
Tools
AI toolsDrawDiffusion canvasLive DrawWriteSheetsArtifactsVideo studioNotebooksDatasets
Learn
DocsBlogEval guidesPrompt libraryCLIAlternativesPapersAI charactersArt gallerySecurityConsulting
Company
PricingEnterpriseSettingsBillingStatusInvestorsCreate accountTerms of ServicePrivacy Policy
app.nzapp.nz

AI agent cloud for coding, deploys, model routing, and research. Built for teams shipping software.

Built in New Zealand by App AI NZ.

Social
X / TwitterGitHubYouTube
The app.nz network
GpuBrainPapersReading TimeNetwrckText-Generator.ioCodex InfinityOpenPathsCuteDSLAI Art GeneratorAIArt-Generator.artSiteSimSimplexGenDictatorFlowWebFiddleRing.nzChatGibidyBitBankExperimentFlowEvangelerHires.nzHow.nzV5 GamesAddicting Word GamesBig Multiplayer ChessWord SmashingreWord GameMultiplication Master
© 2026 App AI NZ Ltd. All rights reserved.All systems normalTermsPrivacy
Blog
July 15, 2026·5 min read·Lee Penkman

polyserve deploy docs: Go, Python, and Bun quickstarts

Per-language deploy quickstarts for polyserve spaces plus the full host control protocol: deploy, usage, health, routing, scale-to-zero, env vars, addons, and the autoscaler contract.

polyserve is extreme-lightweight, in-process serverless hosting: one host process per language serves many apps ("spaces") with per-second usage metering, hot-swap deploys, and scale-to-zero. It runs the app.nz hosting platform and is cheap enough to run yourself on a $4 VPS. Every language host implements the same HTTP control surface, so the control plane treats hosts uniformly.

HostDefault portSpace model
Go8440Compiled binary behind a unix socket, or a .so plugin fully in-process
Python8441ASGI app / handle() imported in-process by an asyncio host
Bun8442fetch handler imported in-process by Bun.serve

Background reading: the announcement, the Go host deep dive, and in-process ONNX serving.

Running the hosts

git clone https://github.com/lee101/polyserve
cd polyserve
make build               # builds all hosts
make e2e                 # deploys every example against real hosts and asserts
./hosts/go/polyserve-go  # serve Go spaces on :8440

Go quickstart

A Go space is a normal net/http binary with zero polyserve dependencies (see examples/go-hello). Build it for linux and POST it to the host:

GOOS=linux go build -o hello ./examples/go-hello
curl -X POST localhost:8440/_polyserve/deploy -F space=lee101/hello -F binary=@hello
curl localhost:8440/s/lee101/hello/

The binary is saved to slots/<owner>/<name>/bin-<N>, started on a fresh unix socket, traffic is atomically switched, and the old process is drained for 5s then killed — zero dropped requests. Cold start budget: under 100ms.

Python quickstart

A Python space exposes an ASGI app or a handle() function; the asyncio host imports it in-process (see examples/python-hello and examples/python-onnx-tiny). Deploy the module as a source file or tar:

curl -X POST localhost:8441/_polyserve/deploy -F space=lee101/hello-py -F [email protected]
curl localhost:8441/s/lee101/hello-py/

# multi-file spaces: upload a tar
tar -cf onnx-tiny.tar -C examples/python-onnx-tiny .
curl -X POST localhost:8441/_polyserve/deploy -F space=lee101/onnx-tiny -F [email protected]

New deploys load in a fresh module namespace; the old namespace is dropped after the switch. Cold start budget: import under 500ms.

Bun quickstart

A Bun space default-exports a fetch handler (see examples/bun-hello):

export default {
  fetch(req: Request): Response {
    const url = new URL(req.url);
    return Response.json({ hello: "world", space: "bun-hello", path: url.pathname });
  },
};
curl -X POST localhost:8442/_polyserve/deploy -F space=lee101/hello-bun -F [email protected]
curl localhost:8442/s/lee101/hello-bun/

Cold start budget: import under 100ms.

Control protocol

If POLYSERVE_ADMIN_TOKEN is set, control endpoints require Authorization: Bearer <token>.

POST /_polyserve/deploy

Multipart hot-swap deploy.

FieldDescription
spaceRequired. owner/name.
binaryGo: compiled executable. New process on a fresh unix socket, atomic traffic switch, old process drained (5s) then killed.
modulePython/Bun: source file or tar. Loaded in a fresh module namespace; old namespace dropped after switch.
envRepeatable KEY=VALUE pairs injected into the space (addon credentials like DATABASE_URL).

Response: {"ok":true,"space":"owner/name","generation":N}.

GET /_polyserve/usage

Per-second billing source of truth. Counters are monotonic; the control plane diffs between scrapes. Usage is also appended once per minute to usage.jsonl for crash-safe billing.

{"spaces":{"owner/name":{"requests":123,"busy_ms":4567,"warm_s":890,"loaded":true}}}
  • busy_ms — cumulative wall time with >=1 in-flight request (billable compute)
  • warm_s — cumulative seconds loaded in memory (billable residency)

GET /_polyserve/health

Returns {"ok":true,"spaces_loaded":N,"uptime_s":N}.

DELETE /_polyserve/spaces/:owner/:name

Unload and remove the space.

Routing

  • GET/POST/... /s/<owner>/<name>/<rest> routes to space owner/name with path /<rest>.
  • Or by Host header when a custom domain is mapped (the host consults its spaces.json state file).
  • Unknown space: 404 {"error":"unknown space"}.
  • Space present but scaled to zero: the host loads it, then serves.

Scale-to-zero

A space with no requests for POLYSERVE_IDLE_TTL (default 900s) is unloaded — Go: process stopped; Python/Bun: module released. State stays in spaces.json so the next request cold-starts it transparently.

Environment variables

VariableDescription
POLYSERVE_PORTHost listen port (defaults: Go 8440, Python 8441, Bun 8442)
POLYSERVE_DATA_DIRState directory (default ./polyserve-data)
POLYSERVE_IDLE_TTLScale-to-zero idle timeout (default 900s)
POLYSERVE_ADMIN_TOKENIf set, control endpoints require Authorization: Bearer <token>

Addons

Spaces get env injected per-space: the app.nz control plane provisions addons (Postgres, MongoDB, ...) and passes DATABASE_URL etc. at deploy time. Locally:

curl -X POST localhost:8440/_polyserve/deploy \
  -F space=lee101/pgapp \
  -F binary=@pgapp \
  -F env=DATABASE_URL=postgres://user:pass@host:5432/db

The examples/go-postgres example shows the app.nz Postgres addon via injected DATABASE_URL.

Autoscaler

The autoscaler/ control loop scrapes /_polyserve/usage from every worker, computes aggregate busy-ratio, and scales a provider (Hetzner implementation, RunPod GPU implementation) between MIN_WORKERS and MAX_WORKERS. Workers self-register by running hosts under systemd; the scaler only needs each worker's address list.

polyserve is MIT licensed: github.com/lee101/polyserve, mirrored at app.nz/lee101/polyserve.

Build what you just read

Ship agents, models, and apps on one cloud.

Start with free credits, then use the same platform from the web app, CLI, desktop app, or MCP.

Start building freeRead the docs

Keep reading

polyserve: in-process serverless that packs hundreds of apps into one process

Announcing polyserve, the open-source in-process serverless host behind app.nz: per-second billing via busy_ms and warm_s, hot-swap deploys, scale-to-zero, and autoscaling to Hetzner and RunPod GPUs.

Inside the polyserve Go host: fasthttp, unix-socket slots, and zero-drop hot swaps

How one fasthttp process serves many compiled Go apps with microsecond proxy overhead, atomic generation swaps with a 5s drain, and Postgres addons via injected DATABASE_URL.

Serving tiny ONNX models serverlessly, in-process

Why in-process beats a dedicated model server for small ONNX models: warm sessions in one asyncio host, sub-500ms cold starts, honest per-second metering, and RunPod GPU autoscaling for bigger models.