Skip to content

Docs

Quickstart

From an uninstrumented Node service to a deploy-annotated latency timeline, in five steps.

sgl 2.4.0updated 6 Aug 2026 · 10 min read

Before you start

  • Node 20 or newerthe SDK ships ESM only
  • A service you can redeploythe deploy mark is step 4
  • Ten minutesnothing here is irreversible

Already installed? Jump to sgl deploy mark.

This guide takes a Node service from zero to a deploy-annotated latency timeline. It takes about ten minutes, and nothing here is reversible in a way that should worry you — the SDK is a no-op until an ingest key is present.

1

Install the CLI

The CLI is a single binary. It is the same tool your CI uses, so install it the same way in both places.

terminalbash

brew install signalhq/tap/sgl
# or: curl -fsSL https://get.signal.sh | sh

sgl --version
# sgl 2.4.0 (darwin/arm64)
2

Create a service

A service is the unit everything else hangs off: spans, alerts, deploys and cost. Create one per deployable, not per repo.

terminalbash

sgl login
sgl service create payments-worker --env prod

# wrote SIGNAL_INGEST_KEY to .env.local
# scoped to payments-worker/prod
# rotate with: sgl key rotate
3

Instrument it

The SDK wraps HTTP, gRPC and your database driver. It has to load before your application code, which is what the --import flag is for.

instrument.tsts

import { init } from "@signal/node";

init({
  service: "payments-worker",
  env: process.env.SIGNAL_ENV ?? "dev",
});
package.jsonjson

{
  "scripts": {
    "start": "node --import ./instrument.js dist/app.js"
  }
}

Running the collector yourself? Set SIGNAL_ENDPOINT before this step. In self-hosted mode the SDK never opens a connection to signal.sh — the checks to run first are under sgl collector.

4

Mark your deploys

This is the step that makes the rest of Signal worth having. Run it at the end of your deploy job, after traffic shifts.

.ci/deploy.shbash

sgl deploy mark \
  --service payments-worker \
  --env prod \
  --sha "$(git rev-parse HEAD)" \
  --by "$CI_ACTOR"
5

Watch it

Once a deploy and a few thousand spans are in, the timeline can attribute a change to a release. Add --json to the same command to gate a rollout in CI.

terminalbash

sgl watch --env prod --since 15m
sgl watch --env prod --since 15m --json | jq '.regressions'

The first request, returned

A local request proves the middleware emitted a trace before you deploy anything.

~/payments — local request
$ curl -i http://localhost:3000/checkout/health

HTTP/1.1 200 OK
content-type: application/json
{"ok":true,"traceId":"local-7ce91b2a"}
local · 200 OK · 38 ms

One local request, one trace ID: the middleware emitted a span before anything was deployed.