Tagbackup documentation

Version 0.0.9

Installation

tagbackup ships as a single compiled binary for Linux, macOS, and Windows. Download the archive for your OS from GitHub Releases. The current version is v0.0.9.

PlatformAsset name
Linux x86_64tagbackup_0.0.9_linux_amd64.tar.gz
Linux ARM64tagbackup_0.0.9_linux_arm64.tar.gz
macOS Inteltagbackup_0.0.9_darwin_amd64.tar.gz
macOS Apple Silicontagbackup_0.0.9_darwin_arm64.tar.gz
Windows x86_64tagbackup_0.0.9_windows_amd64.zip
Windows ARM64tagbackup_0.0.9_windows_arm64.zip

Linux

curl -sfL https://tagbackup.com/install.sh | sh

Or manually: download the archive, extract, and move the binary into your PATH:

ARCH=$(uname -m); case "${ARCH}" in x86_64|amd64) ARCH=amd64 ;; aarch64|arm64) ARCH=arm64 ;; esac
tar -xzf tagbackup_0.0.9_linux_${ARCH}.tar.gz
chmod +x tagbackup
sudo mv tagbackup /usr/local/bin/

macOS

curl -sfL https://tagbackup.com/install.sh | sh

Or manually:

ARCH=$(uname -m); case "${ARCH}" in x86_64|amd64) ARCH=amd64 ;; aarch64|arm64) ARCH=arm64 ;; esac
tar -xzf tagbackup_0.0.9_darwin_${ARCH}.tar.gz
chmod +x tagbackup
sudo mv tagbackup /usr/local/bin/

# If macOS quarantines the binary after a browser download:
xattr -d com.apple.quarantine /usr/local/bin/tagbackup

Windows

Extract the .zip, locate tagbackup.exe, and either run it from that folder or add the folder to your user PATH (Settings → System → About → Advanced system settings → Environment Variables → Path).

Verify checksum (optional)

Each release includes a tagbackup_0.0.9_checksums.txt. On Linux/macOS:

sha256sum -c --ignore-missing <(grep "tagbackup_0.0.9_linux_amd64.tar.gz" tagbackup_0.0.9_checksums.txt)

Quick start

After installing, add a bucket and start pushing files.

# 1. Add a bucket interactively
tagbackup bucket add

# 2. Push a file with tags
tagbackup push dump.sql --bucket=dbbackup --tag=nightly,prod

# 3. List files by tag
tagbackup files --bucket=dbbackup --tag=prod

# 4. Pull the latest matching file
tagbackup pull --bucket=dbbackup --tag=nightly+prod --latest
Run tagbackup --help or tagbackup <command> --help for the exact flag list for any command.

Concepts

Tags

Tags are alphanumeric labels ([a-zA-Z0-9], minimum one character) you assign when pushing a file. They're stored directly in the S3 object key — no separate index, no database.

On push you supply a comma-separated list: --tag=nightly,prod,mydb. Tags are sorted before being written to the key, so a,b and b,a are identical.

Object keys

Keys follow the pattern <prefix><timestamp-ms>-<tags-csv>-<filename>. Example:

nightly/1776831788343-nightly,prod-dump.sql

tagbackup only considers objects matching this pattern — other keys in the bucket are silently ignored.

Bucket aliases

A bucket alias is a short name ([a-zA-Z0-9_]+) you choose that maps to a full S3 connection. You pass it with --bucket=ALIAS on every file command.

tagbackup bucket add

Adds a new bucket alias to your config. By default this is fully interactive — tagbackup will prompt you for each setting.

Prompted settings: alias, S3 bucket name, endpoint URL, region, optional prefix, path-style addressing, TLS options, and credential type (static, profile, or iam).

For unattended provisioning (Ansible, Terraform, Dockerfiles), pass everything as flags:

tagbackup bucket add \
  --alias=dbbackup \
  --bucket=my-company-db-backups \
  --endpoint=https://s3.eu-west-1.amazonaws.com \
  --region=eu-west-1 \
  --credential-type=static \
  --access-key-id=AKIAEXAMPLE \
  --secret-access-key=wJalr...

After a successful save, bucket verify runs automatically. Pass --no-test to skip it.

tagbackup bucket verify

Checks connectivity and permissions against a bucket. Verifies list, write, read, and delete independently, using a small probe object that is cleaned up afterwards.

tagbackup bucket verify
# or target a specific alias:
tagbackup bucket verify --bucket=dbbackup

Example output:

  Connecting to bucket      ✓
  Listing files in bucket   ✓
  Writing file to bucket    ✓
  Reading file from bucket  ✓
  Deleting file from bucket ✓
A failed verify run is non-destructive. It's fine to verify a bucket that only has read or only has write permissions — verify just reports what it finds.

bucket list / edit / delete

CommandWhat it does
bucket listPrint all configured aliases, one per line, sorted
bucket editInteractively pick and edit a bucket's settings (including alias). Prevents alias collisions.
bucket deleteInteractively remove a bucket alias from the local config. Does not touch the remote bucket.

Config file

tagbackup stores all configuration in a single YAML file per user:

  • Linux / macOS: $XDG_CONFIG_HOME/tagbackup/config.yaml (falls back to ~/.config/tagbackup/config.yaml)
  • Windows: %AppData%\tagbackup\config.yaml

The file is created with mode 0600 on first write. Writes are atomic — a partial write never leaves a corrupt config.

version: 1

buckets:
  dbbackup:
    bucket: my-company-db-backups
    endpoint: https://s3.eu-west-1.amazonaws.com
    region: eu-west-1
    prefix: nightly/
    credential_type: static
    access_key_id: AKIAEXAMPLE
    secret_access_key: wJalrXUtnFEMI/K7MDENG/...

Credentials

For each invocation, credentials are resolved in this order. First match wins:

  1. Environment variablesTAGBACKUP_BUCKET_<ALIAS>_ACCESS_KEY_ID and TAGBACKUP_BUCKET_<ALIAS>_SECRET_ACCESS_KEY (alias is uppercased)
  2. AWS shared-credentials profile — when credential_type: profile is set
  3. Inline in config.yaml — when credential_type: static with keys present
  4. AWS SDK default chain — instance roles (EC2), task roles (ECS), IRSA (EKS), etc. Used when credential_type: iam
For cron jobs on servers, prefer IAM roles or environment variables so that static secrets never live in the config file.

tagbackup push

tagbackup push <path> --bucket=ALIAS --tag=TAG1,TAG2

Uploads one file. Tags are comma-separated; order doesn't matter (they're sorted before storage).

To push from stdin, use - as the path and supply --filename=NAME:

pg_dump mydb | tagbackup push - --bucket=db --tag=maindb --filename=dump.sql

Limits: original filename ≤ 255 bytes; full S3 key ≤ 1024 bytes.

tagbackup pull

tagbackup pull --bucket=ALIAS --tag=EXPRESSION [flags]
FlagPurpose
--latestDownload the single newest matching object. Without this flag, an interactive chooser is shown.
--output=PATHDestination path. Omit to use the current directory. Pass - to write to stdout (progress goes to stderr).

Pipe directly into a tool:

tagbackup pull --bucket=db --tag=maindb --latest --output=- | psql mydb

No match → exit code 5. In scripts always combine --latest with --non-interactive.

Without --latest, an interactive chooser lists matches (paged, 20 at a time) with column headers above the prompt:

  TIMESTAMP                 SIZE  FILENAME  TAGS
? Choose a file
  2026-06-13 22:34:01Z    1.2 MiB  dump.sql  [maindb]
> 2026-06-08 22:34:01Z    1.1 MiB  dump.sql  [maindb]

tagbackup files

tagbackup files --bucket=ALIAS --tag=EXPRESSION [--json]

Lists all objects matching the expression. Non-interactive. Without --json, output includes a header row and one line per match (newest first):

TIMESTAMP                 SIZE  FILENAME  TAGS
2026-06-13 22:34:01Z    1.2 MiB  dump.sql  [maindb]
2026-06-08 22:34:01Z    1.1 MiB  dump.sql  [maindb]

With --json, emits one JSON object per line to stdout — no header row — suitable for piping to jq:

tagbackup files --bucket=dbbackup --tag=prod --json | jq -r .key

JSON fields: key, tags (array), size (bytes), timestamp (epoch ms from the key).

tagbackup tags

tagbackup tags --bucket=ALIAS

Lists every tag that appears in at least one object in the bucket — with file count and the date range (oldest / newest) for each tag. Sorted alphabetically. Non-interactive.

TAG          FILES  OLDEST                NEWEST
bpmapi           6  2026-06-08 22:34:01Z  2026-06-13 22:34:01Z
joncombeapi      8  2026-06-07 08:19:23Z  2026-06-13 22:33:01Z

tagbackup delete

tagbackup delete --bucket=ALIAS --tag=EXPRESSION [options]
FlagPurpose
--forceDelete all matches without confirmation
--dry-runShow what would be deleted without deleting
--jsonMachine-readable output (same shape as files --json)
--older-than=DUROnly objects strictly older than DUR (e.g. 30d, 2w, 12h)
--newer-than=DUROnly objects strictly newer than DUR. Mutually exclusive with --older-than.

Typical retention pattern in a cron script:

tagbackup delete --bucket=dbbackup --tag=nightly+prod --older-than=30d --force

tagbackup serve

tagbackup serve [--port=PORT] [--no-open]

Starts a local web server and opens your browser. Use it when you want to browse, upload, download, or delete files visually rather than at the command line. The web UI is embedded in the binary — there is nothing extra to install. Stop the server with Ctrl+C.

  • Browse all configured buckets (one tab per alias; no --bucket flag)
  • Filter files by tag
  • Upload files with tags (drag-and-drop or file picker)
  • Download individual files (download button per row; saved under the original filename)
  • Delete selected files
The server binds to 127.0.0.1 only — it is never exposed on your network. It uses your existing config.yaml and credentials. Bucket configuration is still managed via the CLI (tagbackup bucket add / edit) or by editing the config file directly.

Each file row has a download button that saves that object under its original filename. There is no tag filter or "latest" picker — you download the specific file shown in the row. For tag-based or scripted downloads, use tagbackup pull instead.

FlagPurpose
--port=PORTPort to listen on (default 3000)
--no-openPrint the URL without opening a browser
tagbackup serve
tagbackup serve --port 8080
tagbackup serve --no-open

Global flags

FlagShortPurpose
--config=PATHUse a specific config file
--verbose-vEnable debug output (credential path, SDK retries, skipped keys)
--quiet-qSuppress info messages; errors still print. Mutually exclusive with --verbose.
--non-interactiveExit with a usage error instead of prompting. Required in scripts.
--no-colorDisable colour output
--versionPrint version and exit
--help-hHelp for the current command

Tag expressions

Used with pull, files, and delete for the --tag flag. No spaces allowed. Tag characters are [a-zA-Z0-9] only.

TokenMeaning
a|bOR — either tag
a+bAND — must have all tags
-aNOT — must not have this tag
( … )Grouping — evaluated first

Precedence (highest to lowest): ()-+|

Examples:

prod                 # files tagged prod
db+prod              # files with both db and prod
a|b                  # files with a or b
(-scratch)+release   # has release and does not have scratch
(-a+-b)|c            # (not a and not b) or c

Exit codes

CodeMeaning
0Success
1Unexpected error (I/O error, push file not found, etc.)
2Usage error — bad flags, malformed tag expression, missing required parameter
3Config error — file missing, unreadable, or unknown bucket alias
4S3 / network / auth error
5No matching objects found
130 / 143Process interrupted (SIGINT / SIGTERM)

All errors are formatted as tagbackup: <command>: <message> on stderr, optionally followed by a Hint: line with remediation advice.