back to docs
mainnet

Beam Worker Guide

Build, register, and connect a Go worker to a Beam orchestrator

A Beam worker carries transfer data between storage endpoints. It registers with BeamCore over HTTP, then connects to its orchestrator over BeamLink/WCP to receive work and report results.

If you used the old guide
The current worker is a Go binary. The old Python `worker.py`, `WORKER_GATEWAY_URL`, and WebSocket setup no longer apply. The current [official worker guide](https://github.com/Beam-Network/beam/blob/main/docs/worker.md) also requires a subnet-registered worker hotkey.

1. Prepare and build

You need Go 1.24+, stable outbound access to BeamCore, storage endpoints, and your orchestrator, plus a Bittensor hotkey registered on subnet 105. Ask the orchestrator operator for its WCP address, CA certificate, TLS server name, and orchestrator ID.

Run subnet registration from your wallet host so the coldkey stays off the worker server. Check the transaction and fee before registering the hotkey:

btcli subnet register --netuid 105 --subtensor.network finney \
  --wallet.name YOUR_WALLET --wallet.hotkey YOUR_HOTKEY

Build the worker from the official repository:

git clone https://github.com/Beam-Network/beam.git
cd beam
mkdir -p bin
go build -trimpath -o bin/beam-worker ./cmd/beam-worker
./bin/beam-worker version

Keep data/worker/ on persistent storage. It contains your node key and workload journals; replacing the node key changes your BeamLink identity.

2. Register with BeamCore

Sign the exact message YOUR_HOTKEY_SS58:YOUR_PUBLIC_IP:9000 with the worker hotkey. The IP and port in your signature must match the request body. Replace the sample bandwidth with your actual capacity:

curl -X POST https://beamcore.b1m.ai/workers/register \
  -H 'Content-Type: application/json' \
  -d '{
    "hotkey": "YOUR_HOTKEY_SS58",
    "coldkey": "YOUR_COLDKEY_SS58",
    "ip": "YOUR_PUBLIC_IP",
    "port": 9000,
    "claimed_bandwidth_mbps": 100,
    "signature": "0xYOUR_SIGNATURE"
  }'

Save the returned worker_id and api_key securely. Registration with BeamCore alone does not place the worker in an orchestrator pool.

The port value is part of this registration payload and its signed message. For ordinary transfers, the worker’s WCP connection is outbound to the orchestrator; its owner-local control API listens on 127.0.0.1:8780.

3. Join an orchestrator

Generate or read the worker’s persistent node ID:

./bin/beam-worker node-id --node-key data/worker/node.key

Give the worker_id and node ID to your orchestrator operator. They must add the membership through their owner-local POST /v1/orchestrator/memberships endpoint. Ask them for a base64url delegation value if the membership includes one.

Create an environment file outside the Git clone, such as /etc/beam/worker.env with mode 600:

BEAM_WORKER_ID=YOUR_WORKER_ID
BEAM_ORCHESTRATOR_ID=YOUR_ORCHESTRATOR_ID
BEAM_WCP_ADDRESS=orchestrator.example.com:8782
BEAM_WCP_CA=/path/to/wcp-ca.pem
BEAM_WCP_SERVER_NAME=orchestrator.example.com

Add BEAM_ORCHESTRATOR_DELEGATION=YOUR_DELEGATION if the orchestrator issued one. The CA and server name must match the orchestrator’s TLS endpoint. WCP uses TLS 1.3.

4. Run the worker

For ordinary storage transfers, start with the transfer.multipart capability. Replace the user and absolute clone path, then save this as /etc/systemd/system/beam-worker.service:

[Unit]
Description=Beam Worker
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=YOUR_LINUX_USER
WorkingDirectory=/ABSOLUTE/PATH/beam
EnvironmentFile=/etc/beam/worker.env
ExecStart=/ABSOLUTE/PATH/beam/bin/beam-worker serve --node-key data/worker/node.key --capabilities transfer.multipart
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

Keep the environment file readable by systemd; the service user needs read access to the CA file and write access to data/worker/. Start the service after replacing all placeholders:

sudo systemctl daemon-reload
sudo systemctl enable --now beam-worker
sudo journalctl -fu beam-worker

5. Check the connection

curl http://127.0.0.1:8780/healthz
curl http://127.0.0.1:8780/v1/status
sudo journalctl -u beam-worker -n 100 --no-pager

/healthz confirms the local process is running; /v1/status shows its identity, capabilities, resources, and current workload count. Neither proves the WCP session is connected. Check the orchestrator’s worker list and the Beam dashboard for pool status and work. beam-worker doctor --worker-id YOUR_WORKER_ID currently checks the local ID and version only.

Updating

To update, record the current revision, build from the latest official source, and restart:

git rev-parse HEAD
git pull --ff-only
go build -trimpath -o bin/beam-worker ./cmd/beam-worker
sudo systemctl restart beam-worker

Troubleshooting

  • BeamCore registration fails: the signed message must use the same hotkey, public IP, and port as the request body. Check the worker hotkey’s subnet registration too.
  • Worker is healthy but disconnected: compare BEAM_WCP_ADDRESS with the orchestrator’s listener. Check the CA file, TLS server name, port reachability, membership IDs, and any delegation.
  • Connected but no work: check that transfer.multipart is advertised and that the orchestrator is connected to BeamCore and ready. A qualifying orchestrator receives calibration work before production work.
  • Session disappears after another start: Beam displaces the older session when the same worker identity connects elsewhere. Keep one active process per worker identity and preserve data/worker/node.key.
  • Task fails after assignment: check the worker’s network access to the source and destination URLs and inspect the task result in BeamCore.
Command Palette
Search for a command to run...