Skip to main content

PostgreSQL backup and archive to Parquet on S3. Offload cold data, full snapshots, point-in-time restore.

Project description

Backparq

Table-level PostgreSQL Backup to Parquet on S3.

Backparq exports PostgreSQL tables as Parquet files to S3, enabling fast restores, columnar analytics, and long-term retention at a fraction of the cost of keeping data in your database.

CI Python 3.8+ PyPI License: MIT

Why Backparq?

Problem How Backparq Solves It
Database growing too large Archive old data to S3, optionally delete from PostgreSQL
Need table-level backups Full or incremental snapshots per table, not whole database
Want to query historical data Parquet format works with DuckDB, Athena, Spark, Pandas
Slow restores from pg_dump Restore specific tables and date ranges in minutes
No visibility into backups SHA256 checksums, verification commands, progress bars

Backparq vs WAL-G vs pg_dump

pg_dump WAL-G Backparq
Backup Scope Full database Full database (WAL + base) Per-table, selectable
Backup Format SQL / custom binary WAL segments + base backup Parquet (columnar)
Incremental No Yes (WAL streaming) Yes (by date ranges)
Restore Granularity Entire DB or single table Point-in-time (whole DB) Per-table + date range
Query Backups Directly No No Yes (DuckDB/Athena/Spark)
Storage Efficiency Low (uncompressed SQL) Medium High (columnar + zstd)
S3 Native Via pipe/script Yes Yes
Use Case Migrations, full dumps Continuous DR, PITR Table archival, analytics-ready backups

When to Use Each

  • pg_dump: One-off migrations, development snapshots, schema exports
  • WAL-G: Continuous disaster recovery, point-in-time recovery to any second
  • Backparq: Table-level backups, cold data archival, analytics on historical data

Best practice: Use WAL-G for continuous DR + Backparq for table-level archival and analytics.

Features

  • Two Modes: Backup (full snapshots) or Offload (archive + delete old data)
  • Table Selection: Choose specific tables, not the entire database
  • Date-Range Restore: Restore only the data you need, not everything
  • Columnar Format: Query backups directly with DuckDB, Athena, or Spark
  • Parallel Processing: Concurrent table and chunk processing
  • Streaming Export: Constant memory usage regardless of table size
  • Safety First: SHA256 checksums verified before any deletion
  • Encryption: S3 SSE-S3, SSE-KMS, or client-side Parquet encryption

Installation

# Recommended: use uv
curl -LsSf https://astral.sh/uv/install.sh | sh
uv pip install backparq

# Or pip
pip install backparq

# With DuckDB for querying archives
uv pip install backparq[query]

Quick Start

# 1. Generate config
backparq init

# 2. Test connections
backparq test --config backparq.yaml

# 3. Run backup (preview)
backparq archive --config backparq.yaml --dry-run

# 4. Run backup
backparq archive --config backparq.yaml --stats

Usage

Backup Tables

Create full snapshots of specific tables:

backparq archive --config backup.yaml --stats
# backup.yaml
archive:
  mode: backup           # Full snapshot, no deletion
  tables:
    - public.users
    - public.orders
    - public.transactions

Archive + Delete Old Data

Move data older than 90 days to S3 and reclaim database space:

backparq archive --config offload.yaml --stats
# offload.yaml
archive:
  mode: offload
  cutoff: "-90d"         # Archive data older than 90 days
  perform_delete: true   # Delete after verified S3 upload
  tables:
    - public.events
    - public.audit_logs

Restore

# Restore specific date range
backparq restore --config restore.yaml \
  --start 2024-01-01 --end 2024-03-01

# Restore from a specific backup snapshot
backparq restore --config restore.yaml \
  --backup-id 2024-01-15_120000

# Update existing rows with archived data
backparq restore ... --conflict-mode upsert

Query Archives Directly

# Query with DuckDB (requires backparq[query])
backparq query --config backparq.yaml \
  --sql "SELECT COUNT(*) FROM public_orders WHERE created_at > '2024-01-01'"

Verify & Maintain

backparq check --config backparq.yaml   # List archives
backparq verify --config backparq.yaml  # Verify checksums
backparq prune --config backparq.yaml   # Delete old backups per retention

Configuration

database:
  host: localhost
  name: production_db
  user: postgres
  password: "${PG_PASSWORD}"

s3:
  bucket: my-backups
  prefix: postgres
  region: us-east-1
  sse: "AES256"  # Server-side encryption

archive:
  mode: backup   # or "offload"
  tables:
    - table: public.orders
      primary_key: order_id

See examples/reference.yaml for all options.

Example Configs

File Use Case
examples/backup.yaml Full table snapshots for DR
examples/offload.yaml Archive old data + delete from DB
examples/restore.yaml Restore with date ranges
examples/reference.yaml All configuration options

Security

  • Credentials: IAM roles, environment variables, or AWS credentials file
  • Encryption at rest: S3 SSE-S3, SSE-KMS, or client-side Parquet encryption
  • Encryption in transit: HTTPS to S3
  • Checksums: SHA256 verification before any deletion

See SECURITY.md for vulnerability reporting.

Contributing

uv venv && source .venv/bin/activate
uv pip install -e ".[dev]"
uv run pytest

See CONTRIBUTING.md.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

backparq-0.4.0.tar.gz (49.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

backparq-0.4.0-py3-none-any.whl (51.2 kB view details)

Uploaded Python 3

File details

Details for the file backparq-0.4.0.tar.gz.

File metadata

  • Download URL: backparq-0.4.0.tar.gz
  • Upload date:
  • Size: 49.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for backparq-0.4.0.tar.gz
Algorithm Hash digest
SHA256 a4dca089c8a6598b34222c63dc61271883ea2ef60a34658853b36c0e9f2c7592
MD5 95743d846660e7dc67f7c461d0aa6169
BLAKE2b-256 ced25bd5ec8772a550ea3af415ad8273e8004995cd92786d3ead3281722515a2

See more details on using hashes here.

File details

Details for the file backparq-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: backparq-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 51.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for backparq-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e3a08a029a521d8573ace3bf74cffaa43dfd5312d57c5e72fa20a3cdf639326b
MD5 5d8828c28f3651f9667921796fba66e5
BLAKE2b-256 1385366a5388139c61182030a53d7146a0c5f26e8595358091060d1633e6a3d9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page