See Your Server's Health in 30 Seconds

Run one command. We'll show you CPU, memory, disk, and risks — live on this page. No signup.
Security warning: Never run scripts you don’t trust!
That's why we show you the code first: Read it. Then run it — or modify it.

How It Works

  1. Run the command — one line, no install
  2. Your server connects — appears live here
  3. See real metrics — for 15 minutes
  4. Decide what to do — walk away or sign up

What You Might Find

  • ⚠️ SSH open to the internet — bot magnet
  • 💾 Disk at 90%+ — outage risk
  • ⚡ CPU or memory spikes — hidden issues
  • 🔐 SSL cert about to expire
  • 🧩 Outdated software — security risk

Read the Script


#!/bin/bash
################################################################################
#                                 CleverUptime                                 #
#                            Monitoring Script v2.2                            #
#                                  2025-08-23                                  #
#                                                                              #
#                           https://cleveruptime.com                           #
#                                                                              #
#   This script collects data from your server so you can monitor it in        #
#   CleverUptime.                                                              #
#                                                                              #
#   WARNING: NEVER RUN A SCRIPT YOU DON'T UNDERSTAND.                          #
#   That's why we explain EVERY LINE below — even if you're new to Linux.      #
#                                                                              #
#   You can:                                                                   #
#     - Read every command and learn what it does                              #
#     - Comment out lines you don't want to send                               #
#     - Modify values (like server name)                                       #
#     - Learn how real server monitoring works                                 #
#                                                                              #
#   Nothing is sent without your permission.                                   #
#   No hidden code. No surprises.                                              #
#                                                                              #
#   Want to learn more about this script?                                      #
#   Visit: https://cleveruptime.com/the-script                                 ä
#   We'll explain every single line of code with links to documentation.       #
################################################################################


################################################################################
#                             STEP 1: CONFIGURATION                            #
#                                                                              #
#   These values control how your server appears in CleverUptime.              #
#   You can change them — or leave them as they are.                           #
#                                                                              #
#   IMPORTANT: UPLOAD_KEY is like a password. Keep it secret!                  #
################################################################################

# This is your private key. It tells CleverUptime: "This data is from me."
# It's like a password for your server. Never share it.
UPLOAD_KEY="123"

# This script version helps us make sure everything works correctly.
# Please do not change it.
SCRIPT_VERSION="2.2"

# This is where the data is sent. Do not change.
URL="https://upload.cleveruptime.net/"

# How often to send data (in seconds)
# - Free plan: every 300 seconds (5 minutes)
# - Pro/Business: every 60 seconds (1 minute)
# DO NOT SET BELOW 60! Otherwise your account may be blocked.
SLEEP_INTERVAL="60"

# Optional: Give your server a custom ID (e.g. "web01")
SERVER_ID="my_custom_server_id"

# Optional: A friendly name (e.g. "Main Web Server")
SERVER_NAME="my_custom_server_name "

# Optional: Add a description
DESCRIPTION="my_custom_server_description"

# Optional: Group servers (e.g. "blog", "api")
PROJECT="my_cool_project"

# Optional: Add tags to filter later (comma-separated)
TAGS="keywords_describing_my_server"

# Optional: Add location (helps with monitoring)
# If not set, we'll guess from your IP.
CONTINENT="where_my_server_is_located"
COUNTRY="where_my_server_is_located"
ZONE="available_zone_of_my_server"
CITY="city"
HOSTER="company_hosting_my_server"
DATACENTER="datacenter_of_my_server"
RACK="Rack_of_my_server"


################################################################################
#                   STEP 2: CHECK IF WE CAN RUN THIS SCRIPT                    #
#                                                                              #
#   Before doing anything, we check:                                           #
#     - Are required tools installed? (curl, gzip)                             #
#     - Are we running as root? (needed to read some system files)             #
#                                                                              #
#   If not, we stop and explain what to do.                                    #
################################################################################

# Check if 'gzip' is installed
# gzip compresses the data so it uploads faster
if ! command -v gzip &> /dev/null; then
    echo "ERROR: gzip is not installed." >&2
    echo "It's used to compress data before sending." >&2
    echo "Install it with: sudo apt install gzip" >&2
    exit 1
fi

# Check if 'curl' is installed
# curl sends the data to CleverUptime
if ! command -v curl &> /dev/null; then
    echo "ERROR: curl is not installed." >&2
    echo "It's used to send data to the internet." >&2
    echo "Install it with: sudo apt install curl" >&2
    exit 1
fi

# Check if script is run as root (administrator)
# Many system files can only be read by root
if [ "$EUID" -ne 0 ]; then
    echo "ERROR: This script needs root permissions." >&2
    echo "It reads system files like /proc/meminfo and /etc/passwd." >&2
    echo "Run it with: sudo ./cleveruptime.sh" >&2
    exit 1
fi


################################################################################
#                  STEP 3: GET UNIQUE SERVER IDENTIFIERS                       #
#                                                                              #
#   CleverUptime uses these to recognize your server.                          #
#   They are read from your system and should NEVER change.                    #
#                                                                              #
#   - HOSTNAME: your server's name (e.g. 'web01')                              #
#   - PRODUCT_UUID: hardware ID (on physical servers)                          #
#   - MACHINE_ID: system ID (on VMs and containers)                            #
#                                                                              #
#   These help us track your server even if the IP changes.                    #
################################################################################

# Read the server's hostname (e.g. "my-server")
HOSTNAME=$(cat /proc/sys/kernel/hostname)

# Read hardware ID (only on physical servers)
# If not available (e.g. in Docker), we'll use "n/a"
PRODUCT_UUID=$(cat /sys/class/dmi/id/product_uuid 2>/dev/null || echo "n/a")

# Read system ID (unique to this Linux install)
# Found in /etc/machine-id
MACHINE_ID=$(cat /etc/machine-id 2>/dev/null || echo "n/a")


################################################################################
#            STEP 4: THE MAIN LOOP — RUN FOREVER, SEND DATA REGULARLY          #
#                                                                              #
#   The script runs in a loop:                                                 #
#     1. Collect data                                                          #
#     2. Send it to CleverUptime                                               #
#     3. Wait a while                                                          #
#     4. Repeat                                                                #
#                                                                              #
#   This is how monitoring tools work: continuous, automatic checks.           #
#                                                                              #
#   'while true' means "do this forever"                                       #
#   You can stop it anytime with: Ctrl + C                                     #
################################################################################

while true; do
    # Record when this cycle started (for performance tracking)
    startTime=$(date +"%s%3N")

    # Show a message in the terminal
    echo -n "$(date -u +'%Y-%m-%d %H:%M:%S') Running CleverUptime..."

    # Now we do four things in a chain:
    #
    #   1. Collect all system data inside { ... }
    #   2. Compress it with gzip (faster upload)
    #   3. Send it with curl
    #   4. Capture the HTTP status code (200 = success)
    #
    # Let's break it down step by step.
    #
    # You can learn more about this script in detail at:
    #   https://cleveruptime.com/the-script
    #
    status=$(
        # Start of data collection block
        {
            # Force all commands to use English output
            # Why? So we can parse the output correctly later
            export LC_ALL=C

            # This marker helps CleverUptime split the output into sections
            # Example: "***CleverUptime_proc:cpuinfo" marks the start of CPU data
            MARKER="***CleverUptime_"

            # === REQUIRED: Identification ===
            # These lines tell CleverUptime who you are (do not change anything here)
            echo "${MARKER}general:uploadKey";     echo "${UPLOAD_KEY}"
            echo "${MARKER}general:scriptVersion"; echo "${SCRIPT_VERSION}"
            echo "${MARKER}general:hostname";      echo "${HOSTNAME}"
            echo "${MARKER}general:productUuid";   echo "${PRODUCT_UUID}"
            echo "${MARKER}general:machineId";     echo "${MACHINE_ID}"

            # === OPTIONAL: Custom Metadata ===
            # You can use these to organize your servers
            echo "${MARKER}general:serverId";     echo "${SERVER_ID}"
            echo "${MARKER}general:serverName";   echo "${SERVER_NAME}"
            echo "${MARKER}general:description";  echo "${DESCRIPTION}"
            echo "${MARKER}general:project";      echo "${PROJECT}"
            echo "${MARKER}general:tags";         echo "${TAGS}"
            echo "${MARKER}general:continent";    echo "${CONTINENT}"
            echo "${MARKER}general:country";      echo "${COUNTRY}"
            echo "${MARKER}general:zone";         echo "${ZONE}"
            echo "${MARKER}general:city";         echo "${CITY}"
            echo "${MARKER}general:hoster";       echo "${HOSTER}"
            echo "${MARKER}general:datacenter";   echo "${DATACENTER}"
            echo "${MARKER}general:rack";         echo "${RACK}"

            # === Time & Timezone ===
            # We record start time to measure performance and calculate metrics like Bytes/sec
            echo "${MARKER}time:start";           timeout 5 date -u +"%Y-%m-%dT%H:%M:%S.%3NZ"
            echo "${MARKER}time:timezone";        timeout 5 date +"%Z"

            # === /proc — Performance Data ===
            # These files contain live system metrics
            # They are updated regularly by the Linux kernel
            echo "${MARKER}proc:version";         timeout 5 cat /proc/version
            echo "${MARKER}proc:uptime";          timeout 5 cat /proc/uptime
            echo "${MARKER}proc:cpuinfo";         timeout 5 cat /proc/cpuinfo
            echo "${MARKER}proc:stat";            timeout 5 cat /proc/stat
            echo "${MARKER}proc:loadavg";         timeout 5 cat /proc/loadavg
            echo "${MARKER}proc:meminfo";         timeout 5 cat /proc/meminfo
            echo "${MARKER}proc:sys:vm:swappiness"; timeout 5 cat /proc/sys/vm/swappiness
            echo "${MARKER}proc:partitions";      timeout 5 cat /proc/partitions
            echo "${MARKER}proc:diskstats";       timeout 5 cat /proc/diskstats
            echo "${MARKER}proc:mdstat";          timeout 5 cat /proc/mdstat
            echo "${MARKER}proc:swaps";           timeout 5 cat /proc/swaps
            echo "${MARKER}proc:mounts";          timeout 5 cat /proc/mounts
            echo "${MARKER}proc:net:dev";         timeout 5 cat /proc/net/dev
            echo "${MARKER}proc:pressure:cpu";    timeout 5 cat /proc/pressure/cpu
            echo "${MARKER}proc:pressure:io";     timeout 5 cat /proc/pressure/io
            echo "${MARKER}proc:pressure:memory"; timeout 5 cat /proc/pressure/memory

            # === /sys/class/dmi — Hardware Info ===
            # Only available on physical servers
            # Not present in Docker or some VMs
            echo "${MARKER}dmi:id:boardSerial";   timeout 5 cat /sys/class/dmi/id/board_serial
            echo "${MARKER}dmi:id:chassisSerial"; timeout 5 cat /sys/class/dmi/id/chassis_serial
            echo "${MARKER}dmi:id:chassisVendor"; timeout 5 cat /sys/class/dmi/id/chassis_vendor
            echo "${MARKER}dmi:id:productFamily"; timeout 5 cat /sys/class/dmi/id/product_family
            echo "${MARKER}dmi:id:productName";   timeout 5 cat /sys/class/dmi/id/product_name
            echo "${MARKER}dmi:id:sysVendor";     timeout 5 cat /sys/class/dmi/id/sys_vendor

            # === /etc — System Config Files ===
            # These help us understand your OS and users
            # Note: Passwords are NOT stored in /etc/passwd — they're in /etc/shadow
            echo "${MARKER}etc:passwd";           timeout 5 cat /etc/passwd
            echo "${MARKER}etc:group";            timeout 5 cat /etc/group
            echo "${MARKER}etc:osRelease";        timeout 5 cat /etc/os-release
            echo "${MARKER}etc:resolv.conf";      timeout 5 cat /etc/resolv.conf

            # === Commands — Running Processes & Network ===
            # You can comment out any line if you don't want to send that data
            echo "${MARKER}command:ps";           timeout 5 ps aux
            echo "${MARKER}command:who";          timeout 5 who
            echo "${MARKER}command:ip:address";   timeout 5 ip address
            echo "${MARKER}command:ss";           timeout 5 ss -lntup
            echo "${MARKER}command:df";           timeout 5 df -l --output
            echo "${MARKER}command:apt";          timeout 5 apt list --installed
            echo "${MARKER}command:wg";           timeout 5 wg

            # === SMART Data — Disk Health ===
            # Reads health info from hard drives and SSDs
            # Requires 'smartmontools' to be installed
            # Only runs if the disk exists
            for d in /dev/sd[a-z] /dev/nvme[0-9]n1; do
                if [ -e "${d}" ]; then
                    echo "${MARKER}command:smartctl:${d}"; timeout 10 /usr/sbin/smartctl -a "${d}"; echo "exit status: $?"
                fi
            done

            # === Application Checks ===
            # Optional: Monitor services you use
            # Comment out if not installed
            echo "${MARKER}docker:ps";            timeout 5 docker ps -a
            echo "${MARKER}apache:serverNames";   timeout 5 grep -h -E 'ServerAlias|ServerName' /etc/apache2/sites-enabled/*
            echo "${MARKER}mysql:processlist";    timeout 5 mysql -u root -N -e "SET STATEMENT MAX_STATEMENT_TIME = 5 FOR SHOW PROCESSLIST"
            echo "${MARKER}mysql:databases";      timeout 5 mysql -u root -N -e "SET STATEMENT MAX_STATEMENT_TIME = 5 FOR SHOW DATABASES"
            echo "${MARKER}mysql:globalStatus";   timeout 5 mysql -u root -N -e "SET STATEMENT MAX_STATEMENT_TIME = 5 FOR SELECT * FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME IN ('COM_SELECT','COM_INSERT','QUERIES','ROWS_READ')"
            echo "${MARKER}mysql:tables";         timeout 5 mysql -u root -N -e "SET STATEMENT MAX_STATEMENT_TIME = 5 FOR SELECT * FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('mysql','information_schema','performance_schema')"
            echo "${MARKER}mysql:partitions";     timeout 5 mysql -u root -N -e "SET STATEMENT MAX_STATEMENT_TIME = 5 FOR SELECT * FROM information_schema.PARTITIONS WHERE PARTITION_NAME IS NOT NULL"
            echo "${MARKER}ceph:status";          timeout 5 ceph status

            # === Custom Data (Example) ===
            # You can add your own commands here
            echo "${MARKER}custom:myOwnData";     timeout 5 echo "You can add your own data here."
            echo "${MARKER}custom:someOtherData"; timeout 5 echo "Just return a single line of text."

            # === Conditional Data (Example) ===
            # Only collect data on specific servers
            if [[ "${HOSTNAME}" =~ "myHostName" ]]; then
                echo "${MARKER}custom:myHostData"; timeout 5 echo "Only collected on myHostName."
            fi

            # === End timestamp ===
            # Marks the end of this cycle
            echo "${MARKER}time:end";             timeout 5 date -u +"%Y-%m-%dT%H:%M:%S.%3NZ"

        } 2>/dev/null \
          | gzip --fast \
          | curl -X POST \
               --silent \
               --fail \
               --max-time 5 \
               -H "Content-Encoding: gzip" \
               --output /dev/null \
               --write-out "%{http_code}" \
               --data-binary @- \
               "${URL}"
    )
    #  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    #
    # Let's break down what happens in the pipeline above:
    #
    #   { ... }                 : Groups all commands so their output is combined
    #       2>/dev/null         : Hides error messages (like "permission denied")
    #       | gzip --fast       : Compresses the data (smaller, faster upload)
    #       | curl ...          : Sends the compressed data to CleverUptime
    #
    # Why use { } and a pipe?
    #   - We want to collect ALL output from the commands above
    #   - Then compress it
    #   - Then send it in one request
    #   This is efficient and secure.
    #
    # curl flags explained:
    #
    #   -X POST                 : Sends data as a POST request (standard for APIs)
    #   --silent                : No progress bar (cleaner output)
    #   --fail                  : Return error code if HTTP fails (e.g. 404)
    #   --max-time 5            : Give up after 5 seconds (don't hang forever)
    #   -H "Content-Encoding: gzip"  : Tells server the data is compressed
    #   --output /dev/null      : Don't print the server's response
    #   --write-out "%{http_code}" : Instead, return only the HTTP status code
    #   --data-binary @-        : Read compressed data from stdin (the pipe)
    #   "${URL}"                : Where to send it
    #
    # This is safe and transparent:
    #   - You can see every command that runs
    #   - No data is sent without your permission
    #   - You can comment out any line
    #
    # Want to learn more?
    #   Visit: https://cleveruptime.com/the-script
    #


    # Measure how long this cycle took
    endTime=$(date +"%s%3N")
    duration=$((endTime - startTime))

    # Print result
    echo "HTTP status code ${status} (execution time ${duration} ms)"

    # Handle errors
    case "${status}" in
        "200") true ;;  # All good
        "400")
            echo "ERROR: Bad Request. Check scriptVersion, hostname, productUuid, machineId." >&2
            exit 1
            ;;
        "401")
            echo "ERROR: Unauthorized. Check your upload key." >&2
            exit 1
            ;;
        "403")
            echo "ERROR: Forbidden. Upload key may be invalid or revoked." >&2
            exit 1
            ;;
        "429")
            echo "WARNING: Too Many Requests. Increasing interval." >&2
            sleep "${SLEEP_INTERVAL}"
            ;;
        *)
            echo "WARNING: Unexpected HTTP status: ${status}. Retrying..." >&2
            sleep 5
            ;;
    esac

    # Wait before next run
    sleep "${SLEEP_INTERVAL}"

done

                    

Want to learn what each line does? See the full breakdown with links to our knowledge base.


What It Does

  • Reads system files like /proc/loadavg
  • Collects CPU, memory, disk data
  • Sends it securely to CleverUptime

What It Doesn’t Do

  • Steal private data from your server
  • Install agents or background services
  • Modify your system or store data long-term
Privacy & Responsibility

Data is stored for 15 minutes — then deleted. No IP logging. No spam.
Only run on servers you own or have permission to monitor.


Run This Command

curl -s "https://cleveruptime.com/script?uploadKey={UPLOAD_KEY}&project=HealthCheckDemo" | sudo bash

This downloads and runs the script with superuser access — only do this if you trust the source and understand what it does.

The upload key is unique and valid for 15 minutes. It links your server to this preview.

Prefer to download it? Get script with key pre-filled

Tip: Review the script. Comment out anything you don’t want. Just make sure the key matches and you run it within 15 minutes — or you won’t see any data.


Your Server Will Appear Here

Live preview time remaining: 00:15:00

After 15 minutes, the preview ends and all data is discarded. Reload this page to start over.

Why Trust Us?

We're developers too. We've broken servers. Lost data. CleverUptime is the tool we wished we had: simple, honest, helpful.

This isn’t a fake demo. It’s the real dashboard — for 15 minutes. No tricks. No signup required.

See exampleRead our story

Want This for All Your Servers?

Sign up free. One server is free — forever.