Skip to content

use case

API backends, close to UK users

An API lives or dies on tail latency. Put it in London, on NVMe, behind a proxy you control, and keep the p99 boring.

What you get underneath

Each FastNode instance is a VMware virtual machine with the vCPU and RAM allocation of the plan you choose, NVMe-backed storage, a 1 Gbps port and one IPv4 address. You have root. There is no platform layer deciding which runtime versions you may use or how long a request can take, so long-polling, WebSockets, server-sent events and gRPC streams all work without workarounds.

For a UK audience the geography matters. Requests from Manchester, Bristol or Edinburgh reach a London server in a handful of milliseconds. Shaving a transatlantic round trip off every call is worth more than most code-level optimisation, especially for chatty clients that make several requests per screen.

A minimal production layout

Keep the shape simple and every part replaceable:

  • Reverse proxy on ports 80 and 443 terminating TLS. Caddy issues certificates automatically; Nginx with certbot works just as well.
  • App processes bound to 127.0.0.1 on high ports, supervised by systemd.
  • State in Postgres or Redis, also bound to localhost or a firewall-restricted interface.
  • Firewall rules in the portal allowing 22 from your addresses and 80/443 from anywhere. Nothing else.

Supervise with systemd

You do not need a process manager on top of the init system you already have. A unit file restarts crashed processes, captures logs to the journal and starts the service on boot.

[Unit]
Description=orders API
After=network-online.target
Wants=network-online.target

[Service]
User=api
WorkingDirectory=/srv/orders
EnvironmentFile=/etc/orders.env
ExecStart=/srv/orders/bin/server --listen 127.0.0.1:8080
Restart=on-failure
RestartSec=2
LimitNOFILE=65535
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/srv/orders/data

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now orders
journalctl -u orders -f

Proxy and TLS with Caddy

Point your DNS A record at the VPS, then:

api.example.co.uk {
    encode zstd gzip
    reverse_proxy 127.0.0.1:8080 {
        health_uri /healthz
        health_interval 10s
    }
    header {
        Strict-Transport-Security "max-age=31536000"
        -Server
    }
}

Reload with sudo systemctl reload caddy. Certificates renew on their own. If you prefer Nginx, set proxy_http_version 1.1 and pass the Upgrade and Connection headers for WebSocket routes.

Rate limiting at the edge

Abusive clients should be stopped before they reach your application code. In Nginx:

limit_req_zone $binary_remote_addr zone=perip:10m rate=20r/s;
server {
    location /v1/ {
        limit_req zone=perip burst=40 nodelay;
        proxy_pass http://127.0.0.1:8080;
    }
}

Apply a stricter zone to login and token endpoints. Return 429 with a Retry-After header so well-behaved clients back off.

Size by measured load

Shape of the serviceStart on
Single app process, hosted database elsewhere, low trafficSpark
App plus Redis and proxy, a few hundred requests per secondBoost
App and Postgres on one hostTurbo or Nitro
Several workers, background queues, heavy JSON serialisationWarp

Load-test before launch with wrk or k6 from a separate machine, watching memory as well as CPU. Interpreted runtimes often hit RAM limits before cores are saturated.

Deploy without dropping requests

Run two instances of the app on different ports and list both as upstreams. Deploy by restarting one, waiting for its health check to pass, then restarting the other. The proxy drains each in turn and clients never see a refused connection. Snapshot the VM before schema migrations so you have a fast way back if a migration goes wrong.

Wire it into your tooling

Scoped API keys from the portal let scripts and dashboards read account state, and webhooks push events to an endpoint you run. Keys are displayed once on creation, so drop them straight into your secret store. See the API page for what is available today.

Questions

Which plan should a new API start on?

Boost handles most early-stage APIs: 2 vCPU and 4 GB is enough for an app server, a reverse proxy and a modest Redis. Move to Turbo when you add a database on the same host or see sustained CPU above 60 percent.

Can I run the database on the same VPS as the API?

Yes, and for small services it is often the lowest-latency setup because queries never leave the machine. Split them onto separate VMs once either side needs to scale or be patched independently.

Do you provide a managed load balancer?

No. FastNode sells virtual machines. You can run HAProxy, Nginx or Caddy yourself on a VPS in front of several app servers, which gives you full control of health checks and routing.

Can I get notified when a VM changes state?

Yes. Account webhooks in the portal post events to an HTTPS endpoint you choose, and scoped API keys let your own tooling query the account.