How to Update Hysteria Core to the Latest Version: 3 Methods Explained
You can update Hysteria core using the built-in check-update command, rely on automatic 24-hour background checks, or execute the official install script from scripts/install_server.sh.
Hysteria provides multiple mechanisms to keep its core binary current, ranging from manual CLI commands to fully automatic background updates. Whether you are running a server or client instance, the repository at apernet/hysteria ensures you can quickly verify and install the latest release without manual binary management. This guide covers all update pathways using the actual source implementation.
Method 1: Using the Built-In Update Command
The fastest way to manually verify your version is through the check-update subcommand defined in app/cmd/update.go. This command constructs an UpdateChecker instance and queries the Hysteria update API to compare your current build against the latest release.
When you invoke hysteria check-update, the application executes the check immediately and prints the results. For server deployments, the code uses utils.NewServerUpdateChecker, while client deployments use utils.NewClientUpdateChecker to route the request through the active Hysteria connection, preventing SNI fingerprinting by censors.
# Display current installed version
hysteria version
# Check for available updates
hysteria check-update
Method 2: Automatic Background Updates
Hysteria can automatically check for updates every 24 hours without user intervention. This mechanism is implemented in app/cmd/update.go through the functions runCheckUpdateServer and runCheckUpdateClient, which spawn a background goroutine executing checkUpdateRoutine.
The routine creates a time.NewTicker(updateCheckInterval) set to 24 hours and repeatedly queries the update API. When an update is available, the process logs the new version, download URL, and urgency flag.
To disable this behavior, pass the --disable-update-check flag defined in app/cmd/root.go:
# Start server with automatic update checks disabled
hysteria --disable-update-check server -c config.yaml
Method 3: Updating via the Install Script
For server administrators, the scripts/install_server.sh bash script provides a complete update workflow. The script detects your environment, compares the installed version against the latest release using the vercmp function, and handles binary replacement automatically.
The script supports three operational modes:
- Check mode (
-cor--check): Verifies if an update is available without installing - Install mode (default): Downloads and installs the latest binary via
download_hysteriaonly if newer than the current version - Force mode (
-for--force): Re-installs the binary even whenget_installed_versionmatchesget_latest_version
# Check only without installing
curl -sSL https://get.hy2.sh | bash -s -- --check
# Standard update (or fresh install)
curl -sSL https://get.hy2.sh | bash -s --
# Force reinstallation regardless of current version
curl -sSL https://get.hy2.sh | bash -s -- -f
The script places the binary at /usr/local/bin/hysteria by default.
Understanding the Update Mechanism
The core update logic resides in app/internal/utils/update.go within the UpdateChecker struct. Understanding this implementation helps diagnose connectivity or version-check failures.
API Endpoint and Request Structure
The checker sends a GET request to https://api.hy2.io/v1/update with query parameters encoding the current version, platform, architecture, channel, and side (server or client):
const updateCheckEndpoint = "https://api.hy2.io/v1/update"
url := fmt.Sprintf("%s?cver=%s&plat=%s&arch=%s&chan=%s&side=%s",
updateCheckEndpoint, uc.CurrentVersion, uc.Platform,
uc.Architecture, uc.Channel, uc.Side)
resp, err := uc.Client.Get(url)
Response Handling
The API returns a JSON UpdateResponse containing:
update: Boolean indicating if a newer version existslver: Latest version string (e.g., "v2.6.0")url: Direct download URL for the new binaryurgent: Boolean flag marking critical security updates
Transport Differences
- Server checks use a standard
http.Clientinstantiated viaNewServerUpdateChecker - Client checks route HTTP requests through the active Hysteria connection using
NewClientUpdateChecker, ensuring the update check traffic is indistinguishable from regular data and cannot be blocked by simple SNI filters
Programmatic Update Checks
You can integrate update checking into custom Go applications using the UpdateChecker utilities. This is useful for building management dashboards or monitoring tools that track version drift across deployments.
import (
"fmt"
"github.com/apernet/hysteria/app/internal/utils"
"github.com/apernet/hysteria/core/v2/client"
)
func checkForUpdate(hyClient client.Client) {
// Create checker for client side (tunnelled through hyClient)
checker := utils.NewClientUpdateChecker(
"v2.5.1", "linux", "amd64", "release", hyClient,
)
resp, err := checker.Check()
if err != nil {
panic(err)
}
if resp.HasUpdate {
fmt.Printf("New version %s available: %s\n",
resp.LatestVersion, resp.URL)
} else {
fmt.Println("You are on the latest version.")
}
}
Summary
- Use
hysteria check-updatefor immediate manual checks via the Cobra command inapp/cmd/update.go - Automatic background checks run every 24 hours via
checkUpdateRoutineunless disabled with the--disable-update-checkflag - The install script at
scripts/install_server.shhandles complete server upgrades usingget_latest_versionandvercmplogic - Server and client instances use different transport methods: plain HTTP for servers, tunneled connections for clients to avoid censorship
- All mechanisms query
https://api.hy2.io/v1/updateand return structuredUpdateResponsedata containing version, URL, and urgency indicators
Frequently Asked Questions
How often does Hysteria check for updates automatically?
Hysteria checks for updates once every 24 hours when the automatic background ticker is enabled. This interval is hardcoded as updateCheckInterval in app/cmd/update.go. The check runs in a separate goroutine started by either runCheckUpdateServer or runCheckUpdateClient after the main process initializes, ensuring the binary stays current without user interaction.
What is the difference between server and client update checking?
Server update checks use a standard HTTP client that connects directly to the update API via NewServerUpdateChecker, while client checks route the request through the active Hysteria connection using NewClientUpdateChecker. This tunneling approach prevents censors from detecting update checks through SNI fingerprinting or blocking the update API endpoint separately from the proxy traffic.
Can I update Hysteria without stopping the service?
The install script (scripts/install_server.sh) downloads the new binary to a temporary location and replaces the executable at /usr/local/bin/hysteria, but you must restart the service to load the new binary into memory. For zero-downtime updates, deploy the new binary alongside the running instance, swap the files, and trigger a graceful restart via your process manager or init system.
Why does the install script report the latest version is already installed when I want to force an update?
The install script compares versions using the vercmp function and skips the download_hysteria step if the installed version matches the latest release. To force a reinstallation regardless of the current version, use the -f or --force flag when running the script, which bypasses the version comparison and executes the download and installation routine immediately.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →