License Relay Server
Every rotobot_next process checks out a license seat from a
lightweight HTTP relay before it begins work. The relay enforces concurrent-seat
limits, surfaces upcoming-expiry warnings, and releases the seat automatically
when the worker exits.
Under the hood the relay is a self-hosted instance of
keygen-api,
backed by the keygen.sh
licensing service. Each worker derives a fingerprint from the host machine-id
(the same value exposed by py-machineid)
combined with the process ID, so seats are counted per rotobot_next
process rather than per host.
Pointing the binary at a relay
The relay URL is configured via the TOKGAN_RELAY_URL environment
variable. If unset, the binary falls back to http://0.0.0.0:6349
(a relay running on the same host on port 6349).
# Same-host relay (default):
TOKGAN_RELAY_URL=http://0.0.0.0:6349 rotobot_next --image_folder ./frames
# Remote relay on your network:
TOKGAN_RELAY_URL=https://relay.example.com:6349 \
rotobot_next --image_folder ./frames
# Persistent for the shell:
export TOKGAN_RELAY_URL=https://relay.example.com:6349
rotobot_next --image_folder ./frames The relay must be reachable for the duration of the run; loss of connectivity mid-run will surface a license error and stop the worker.
How seats are counted
Seats are counted per process, not per machine. The relay
fingerprints each checkout as <machine-id>-<pid>-<uuid8>,
so:
- One
rotobot_nextworker uses one seat. - Running two workers in parallel on the same machine consumes two seats simultaneously — useful at 1080p / 1440p where a single GPU has the VRAM headroom for two workers.
- When a worker exits cleanly the seat is released immediately. Crashed workers free their seat when the relay's heartbeat-timeout window elapses.
If your batches consistently run N workers, you need at least N seats in your pool.
License warnings
The relay prints a warning to stderr on every checkout when the license is within three days of expiry:
LICENSE WARNING! Now is UTC 2026-05-13 02:27:06+00:00 License will
expire within three days contact Tokgan
LICENSE WARNING! Now is UTC 2026-05-13 02:27:06+00:00 License will
expire on 2026-05-13 20:40:07+00:00 To renew or extend a license, contact sales.
Troubleshooting
connection refusedat startup-
The relay isn't running at the URL you configured, or a firewall blocks
port 6349. Verify with
curl $TOKGAN_RELAY_URL/healthz. - License error mid-batch
- Either the relay restarted, the network briefly dropped, or the seat pool was exhausted by another job. Re-launch the worker; the failed frame can be resumed by re-running against the same output folder (the JSON-based skip logic in your batch scripts will not re-do completed clips).
- Want to run more workers than seats
- Either request a larger pool, or stagger workers so they don't all hold seats concurrently.
Roadmap — node-locked custom build
The relay distributed today runs on the stock keygen-api
server. A future release will replace it with a custom cryptographic
build that is node-locked to the ethernet (MAC) address of the license
server host: the binary will only start when it can verify it is running
on the hardware it was issued for, and the relay's signing keys will be
derived at build time from that address.
This hardens the relay against being lifted from one host and run on another, and gives Tokgan a verifiable per-customer deployment artefact rather than a generic open-source binary. Implementation will need collaboration on the build pipeline and the binding-key derivation scheme.
Further reading
- keygen.sh documentation — concepts behind licenses, policies, entitlements, and machine fingerprints.
- keygen-sh/keygen-api — source for the self-hosted relay server.
- py-machineid on PyPI — the Python helper for reading the host machine-id used in the per-worker fingerprint.