Upgrade Temps

Temps includes a self-upgrade command that downloads the latest release from GitHub, verifies its checksum, and replaces the binary atomically. Database migrations run automatically on the next restart.


Check your current version

temps --version

Output:

v0.0.6 (abc1234) built 2026-03-04 12:34:56 UTC

Check for updates

See if a newer version is available without installing it:

temps upgrade --check

Or use the health check command, which includes an update check along with other system diagnostics:

temps doctor

If a newer version exists, you will see:

WARN Update: v1.1.0 available - run 'temps upgrade' to update

Back up before upgrading

Before any upgrade, create a backup of your data:

If you have S3 backup storage configured:

Trigger a manual backup from the dashboard (Settings > Backups > Run Backup) or via the API.

If you do not have S3 configured:

At minimum, back up the Temps data directory and database:

# Back up the data directory (contains encryption key, auth secret, GeoLite2 DB)
cp -r ~/.temps ~/.temps-backup-$(date +%Y%m%d)

# Back up the PostgreSQL database
docker exec temps-timescaledb pg_dumpall -U postgres | gzip > temps-db-backup-$(date +%Y%m%d).sql.gz

Run the upgrade

Upgrade to the latest version

temps upgrade

If the binary is in a root-owned location (e.g. /usr/local/bin/temps):

sudo temps upgrade

The upgrade process:

  1. Detects your platform (Linux/macOS, x86_64/ARM64)
  2. Fetches the latest release from GitHub
  3. Compares versions — exits if already up to date
  4. Shows the upgrade plan (current version, target version, download size)
  5. Asks for confirmation
  6. Downloads the release tarball
  7. Verifies the SHA-256 checksum (if available)
  8. Replaces the binary atomically (write to temp file, then rename)

Options

# Upgrade to a specific version (ignores the channel)
temps upgrade --version v1.1.0

# Skip the confirmation prompt
temps upgrade --yes

# Track a release channel (stable is the default)
temps upgrade --channel beta

# Upgrade a binary at a different path
temps upgrade --path /opt/temps/bin/temps
FlagDefaultDescription
--channel <stable|beta>stableWhich release stream to track. See Release channels.
--version <vX.Y.Z>latest in channelPin a specific version. Bypasses channel filtering entirely.
--path <path>currently running binaryPath to the temps binary to replace.
--yes, -yoffSkip the confirmation prompt.
--checkoffPreview the planned upgrade without installing.

Other upgrade methods

temps upgrade is the recommended path because it verifies the checksum and swaps the binary atomically. These alternatives exist for installs that were set up with the deploy script or that prefer a one-shot command.

Upgrade script (deploy.sh installs)

If you installed Temps with deploy.sh, the upgrade script handles everything in one command — it backs up your encryption key, downloads the latest binary, upgrades Localup if tunnel mode is detected, and restarts the services:

curl -fsSL https://temps.sh/upgrade.sh | bash

To pin a specific version:

curl -fsSL https://temps.sh/upgrade.sh | bash -s vX.Y.Z

Re-run the installer

The installer downloads the latest binary for your platform and replaces the one at ~/.temps/bin/temps, preserving all configuration, data, and certificates. It accepts the same --channel flag as temps upgrade:

# Latest stable (default)
curl -fsSL https://temps.sh/install.sh | bash

# Latest beta
curl -fsSL https://temps.sh/install.sh | bash -s -- --channel beta

Then restart the service (see Restart Temps).

Manual download

Download a release tarball directly from GitHub, extract it, and replace the binary:

curl -LO https://github.com/gotempsh/temps/releases/latest/download/temps-linux-amd64.tar.gz
tar -xzf temps-linux-amd64.tar.gz
sudo mv temps /usr/local/bin/temps
sudo systemctl restart temps

To pin a version, swap latest/download for download/vX.Y.Z.


Release channels

temps upgrade tracks one of two release streams, selected with --channel:

ChannelSelectsNotes
stable (default)Non-prerelease GitHub releases onlyTags without a - suffix, e.g. v1.2.0.
betaBoth stable and prerelease releasesIncludes tags like v1.2.0-beta.4 or v1.2.0-rc.1.

Running temps upgrade with no flags always lands on stable.

Because GitHub returns releases newest-first and beta accepts both kinds, a beta host always upgrades to the freshest available version — including a newly shipped stable that supersedes the latest beta on the same line. The runtime decision is GitHub's prerelease flag on each release (draft releases are never selectable on either channel), not literal tag-string parsing.

Pinning a specific --version ignores the channel entirely and fetches that exact release directly.

The install.sh installer

The curl-pipe installer accepts the same --channel flag with matching semantics (default stable, accepts only stable or beta):

# Install the latest stable release (default)
curl -fsSL https://temps.sh/install.sh | bash

# Install the latest beta release
curl -fsSL https://temps.sh/install.sh | bash -s -- --channel beta

Stable resolves through GitHub's /releases/latest endpoint (which returns the newest non-prerelease); beta takes the newest tag from /releases?per_page=20. Passing an explicit version positional argument ignores the channel. One divergence from the Rust CLI: the bash installer does not filter draft releases — it trusts that the GitHub API only returns shipped releases, whereas the CLI explicitly skips drafts.


Restart Temps

The upgrade replaces the binary but does not restart the running process. You need to restart manually.

If running under systemd (typical server setup)

sudo systemctl restart temps

If you run the proxy as a separate process:

sudo systemctl restart temps-proxy

If running in a terminal

Stop the current process (Ctrl+C) and start it again:

temps serve

Database migrations

Migrations run automatically when temps serve starts. There is no separate migration command. When the server boots, it:

  1. Connects to PostgreSQL
  2. Runs all pending migrations (120-second timeout)
  3. Backfills any new TimescaleDB continuous aggregates
  4. Starts serving traffic

If migrations fail, the server will not start. Check the logs for the specific migration error.


Verify the upgrade

After restarting:

# Check the version
temps --version

# Confirm the service is healthy
curl -sf http://localhost:8081/health

# Run diagnostics
temps doctor

The doctor command checks:

  • Data directory integrity
  • Encryption key presence
  • Database connectivity and version
  • TimescaleDB extension
  • Migration count
  • Docker daemon availability
  • External connectivity (GitHub API, Docker Hub, Let's Encrypt)
  • Git providers and DNS providers

If everything passes, your upgrade is complete. Visit the dashboard to confirm it loads correctly.


Upgrade the database

TimescaleDB runs as a Docker container and is upgraded independently of Temps:

# Pull the latest image
docker pull timescale/timescaledb-ha:pg18

# Stop and remove the old container (data persists in the volume)
docker stop temps-timescaledb
docker rm temps-timescaledb

# Start with the new image
docker run -d \
  --name temps-timescaledb \
  --restart unless-stopped \
  -e POSTGRES_USER=temps \
  -e POSTGRES_PASSWORD="YOUR_DB_PASSWORD" \
  -e POSTGRES_DB=temps \
  -p 127.0.0.1:5432:5432 \
  -v temps-db-data:/home/postgres/pgdata/data \
  timescale/timescaledb-ha:pg18

# Restart Temps to reconnect
sudo systemctl restart temps

Your database password is stored in ~/.temps/.wizard-state/db_password if you used the deploy script.


Switch to Enterprise Edition

temps upgrade --tier ee switches a running install from the open-source binary (the default) to the Enterprise Edition (EE) binary. The EE binary lives in a license-gated proxy, so you must supply a license JWT.

temps upgrade --tier ee --license-path /path/to/license.jwt

EE flags

FlagDefaultDescription
--tier <oss|ee>ossWhich edition to install. oss downloads from GitHub releases. CLI-only — no env-var fallback.
--license-path <path>Path to the EE license JWT. Required with --tier ee.
--ee-api <url>https://temps.shBase URL of the Temps Cloud EE proxy (--tier ee only). A trailing slash is trimmed.
--data-dir <path>$TEMPS_DATA_DIR, else ~/.tempsData dir whose data/license.jwt receives the license. Also reads the TEMPS_DATA_DIR env var.

If you pass --tier ee without --license-path, the command errors with:

--tier ee requires --license-path <path-to-license.jwt>. Download yours from https://temps.sh/dashboard/license

What the switch does

  1. Validates the license JWT shape before downloading anything. The CLI decodes (but does not verify the signature — the EE binary checks the signature at boot) and rejects: malformed JWTs that are not three dot-separated segments, any tier claim that is not premium or enterprise, and licenses whose exp claim is already in the past.
  2. Resolves the version — the pinned --version, or the latest from <ee-api>/api/ee/releases.
  3. Fetches the checksum and tarball from <ee-api>/api/ee/download/<version>/<asset>/sha256 and <ee-api>/api/ee/download/<version>/<asset>, authenticating with the license JWT as an Authorization: Bearer header. The asset name is temps-ee-<version-without-v>-linux-amd64.tar.gz. The checksum is verified before the swap.
  4. Replaces the current binary atomically.
  5. Copies the license to <data-dir>/data/license.jwt (mode 0600).
  6. Best-effort systemd wiring (Linux only): if /etc/systemd/system/temps.service exists and does not already contain a TEMPS_EE_LICENSE_PATH= line, the upgrader inserts Environment=TEMPS_EE_LICENSE_PATH=<installed-license-path> after the [Service] header and runs systemctl daemon-reload, so the binary finds its license on every restart. If the variable is already present it is left untouched; non-Linux hosts and missing units are skipped silently.

Use --check to preview the planned switch without installing, and -y/--yes to skip the confirmation prompt. After the switch, restart the service to activate:

sudo systemctl restart temps

Upgrade Localup (tunnel)

If you use tunnel mode and are not using the upgrade script, upgrade the localup binary separately:

curl -fsSL https://localup.dev/install.sh | bash

# Restart the tunnel service
sudo systemctl restart localup-tunnel    # Linux
launchctl kickstart -k gui/$(id -u)/dev.temps.localup-tunnel # macOS

Rolling back

Downgrade to a specific version by passing it to the upgrade command:

temps upgrade --version vX.Y.Z

If the new version added database migrations, restoring from a pre-upgrade backup is the safest path:

# 1. Restore the database backup
docker exec -i temps-timescaledb psql -U temps temps < temps-backup-YYYYMMDD.sql

# 2. Downgrade the binary
temps upgrade --version vX.Y.Z

# 3. Restart
sudo systemctl restart temps

Rolling back database migrations is not automatically supported. If a new version added migrations, restoring the database from a pre-upgrade backup is the safest way to revert.


Troubleshooting

Service fails to start after upgrade

# Check logs for errors
sudo journalctl -u temps -n 50 --no-pager   # Linux
tail -50 ~/.temps/logs/temps.log            # macOS

# Common fix: ensure data directory permissions are correct
chmod 700 ~/.temps/data
chmod 600 ~/.temps/data/encryption_key

Database migration errors

Migrations run on startup and the server will not start if they fail. Confirm the database is reachable, then read its logs:

# Check that the database is reachable
docker exec temps-timescaledb pg_isready -U temps

# Check database logs
docker logs temps-timescaledb --tail 50

If the database container is not running, start it first:

docker start temps-timescaledb

Was this page helpful?