Target stack: Ubuntu 24.04 LTS, parca server + parca-agent (eBPF-based whole-system profiler), both as systemd services, fronted by Caddy for TLS.
Parca (by Polar Signals) has two parts:
parca— the server: stores profiles and serves the web UI/API.parca-agent— an eBPF-based agent that profiles every process on the host with (near) zero code changes required in your applications.
You typically run one parca server and one parca-agent per node you want profiled. On a single VPS, both run locally.
1. Prerequisites
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl wget tar ufw linux-headers-$(uname -r)parca-agent needs a kernel with BTF (BPF Type Format) support and the matching headers — Ubuntu 24.04's default kernel has this built in, so the headers package above is mostly a safety net.
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable2. Install the Parca server
cd /tmp
PARCA_VERSION="0.22.1" # check https://github.com/parca-dev/parca/releases for latest
wget "https://github.com/parca-dev/parca/releases/download/v${PARCA_VERSION}/parca_${PARCA_VERSION}_Linux_x86_64.tar.gz"
tar -xzf "parca_${PARCA_VERSION}_Linux_x86_64.tar.gz"
sudo mv parca /usr/local/bin/parca
sudo chmod +x /usr/local/bin/parca
parca --versionCreate a system user and data directory:
sudo groupadd --system parca
sudo useradd --system --gid parca --no-create-home \
--shell /usr/sbin/nologin parca
sudo mkdir -p /etc/parca /var/lib/parca
sudo chown -R parca:parca /var/lib/parcaConfig file:
sudo tee /etc/parca/parca.yaml > /dev/null <<'EOF'
object_storage:
bucket:
type: "FILESYSTEM"
config:
directory: "/var/lib/parca"
EOF
sudo chown -R parca:parca /etc/parcaSystemd unit:
sudo tee /etc/systemd/system/parca.service > /dev/null <<'EOF'
[Unit]
Description=Parca continuous profiling server
After=network.target
[Service]
Type=simple
User=parca
Group=parca
ExecStart=/usr/local/bin/parca \
--config-path=/etc/parca/parca.yaml \
--http-address=127.0.0.1:7070 \
--storage-active-memory=536870912
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now parca
sudo systemctl status parca--storage-active-memory (bytes) caps the in-memory buffer before flushing to disk — 512 MiB above is a reasonable starting point for a small VPS; tune based on available RAM.
3. Install parca-agent (eBPF profiler)
parca-agent needs CAP_SYS_ADMIN/CAP_BPF privileges, so it runs as root (unlike the server).
cd /tmp
AGENT_VERSION="0.36.1" # check https://github.com/parca-dev/parca-agent/releases for latest
wget "https://github.com/parca-dev/parca-agent/releases/download/v${AGENT_VERSION}/parca-agent_${AGENT_VERSION}_Linux_x86_64.tar.gz"
tar -xzf "parca-agent_${AGENT_VERSION}_Linux_x86_64.tar.gz"
sudo mv parca-agent /usr/local/bin/parca-agent
sudo chmod +x /usr/local/bin/parca-agent
parca-agent --versionSystemd unit:
sudo tee /etc/systemd/system/parca-agent.service > /dev/null <<'EOF'
[Unit]
Description=Parca Agent (eBPF continuous profiler)
After=network.target parca.service
Requires=parca.service
[Service]
Type=simple
ExecStart=/usr/local/bin/parca-agent \
--node=$(hostname) \
--remote-store-address=127.0.0.1:7070 \
--remote-store-insecure \
--http-address=127.0.0.1:7071
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now parca-agent
sudo systemctl status parca-agentCheck that it's picking up processes:
sudo journalctl -u parca-agent -fYou should see log lines about discovered processes/cgroups being profiled.
4. Front the server UI with Caddy (TLS + auth)
Install Caddy if not already present:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install -y caddy/etc/caddy/Caddyfile:
parca.example.com {
basicauth {
admin $2a$14$hashedpasswordhere
}
reverse_proxy 127.0.0.1:7070
}Generate the password hash first:
caddy hash-passwordReload:
sudo systemctl reload caddyParca has no built-in auth, and the eBPF agent means this box is already profiling every process on the host — treat the
/etc/parcaand/var/lib/parcadata as sensitive, since profiles can reveal function/symbol names and call paths from your applications. Keep the UI behind auth as shown above.
5. Verify
curl -s http://127.0.0.1:7070/metrics | headOpen https://parca.example.com in a browser. Under Targets, you should see your host, and the Profiles view will let you query CPU flame graphs for any process the agent discovered — no code changes needed.
6. Profiling remote/other nodes (optional)
If you later add more VPS instances, install just parca-agent on each, pointing --remote-store-address at this server's public address (put it behind TLS via Caddy and use --remote-store-address=parca.example.com:443 without --remote-store-insecure, adding --remote-store-bearer-token if you gate ingestion with a token/reverse-proxy auth rule).
7. Updates and maintenance
- Data lives in
/var/lib/parca— back this up if you need historical profiles preserved (Parca's local retention defaults are relatively short-lived by design; it's meant for continuous/recent profiling rather than long-term archival). - To upgrade either binary: download the new release, stop the relevant service, replace the binary, restart:
shell
sudo systemctl stop parca-agent sudo mv /tmp/parca-agent /usr/local/bin/parca-agent sudo systemctl start parca-agent
