Ir al contenido
Empezar gratis en Cloud

HitKeep Data Retention and Parquet Archiving

Esta página aún no está disponible en tu idioma.

You decide how long your analytics data lives — not a cloud vendor’s pricing tier. HitKeep’s retention system follows one rule: data you choose to prune is archived to Parquet first, in an open format you own, before it’s removed from the live database.

Retention factHitKeep behavior
Raw retentionConfigurable globally and per site
Archive formatParquet
Archive triggerRows are archived before pruning from the live database
Backup formatDuckDB EXPORT DATABASE, including schema.sql and Parquet table files
Storage targetLocal path or S3-compatible path when configured
Broader runtime factsSee Facts and Limits
Terminal window
# Keep raw hits and events for 365 days; archive older data to /var/lib/hitkeep/archive
export HITKEEP_DATA_RETENTION_DAYS=365
export HITKEEP_ARCHIVE_PATH=/var/lib/hitkeep/archive
./hitkeep

Or as startup flags:

Terminal window
./hitkeep --data-retention-days=365 --archive-path=/var/lib/hitkeep/archive

See the Configuration Reference for all options.

The retention worker runs once daily. For each site with a configured retention policy it will:

  1. Count expired native traffic, events, Web Vitals, AI fetches, QR opens, imported facts, Search Console facts, and rollups in the site’s tenant catalog.
  2. Export those rows to a compressed Parquet file in the archive directory before touching the live database.
  3. Prune the archived records and expired dirty-rollup buckets from the tenant database.
  4. Leave activity maintenance independent. Activity-hourly rows follow their maintenance policy rather than analytics retention.
Daily retention workerThe retention worker loads site policies, skips sites without expired rows, or exports expired analytics to Parquet before deleting hot rows and pruning dirty buckets.NOYESWRITEDAILYLoad site retention policiesRows older than cutoff?NOSkip siteYESExport expired rowsCOPY … TO PARQUETARCHIVEArchive directorycold Parquet tierPRUNEDelete archived rowstenant DuckDB catalogCLEANUPPrune dirty bucketsLEGENDINPUTDECISIONENDFOCALSTORESERVICE

The result is two data tiers:

TierLocationWhat’s thereQuery speed
Hottenants/{tenant_id}/hitkeep.dbRecent native, imported, Search Console, and rollup data within the retention windowInstant
ColdArchive directoryOlder analytics rows exported to ParquetFast (file scan)

Archived hit rows keep the same derived IP metadata columns as live hit exports: region, city, provider, ASN, and ASN organization. Raw visitor IP addresses are not added to retention archives.

Dashboard trend history follows the configured retention window; expired rollups are archived and pruned with their source data.

Different sites have different requirements. Override the default retention window per site via the API:

Terminal window
curl -X PUT https://your-hitkeep.example/api/sites/{site_id}/retention \
-H "Content-Type: application/json" \
-b "hk_token=YOUR_SESSION_COOKIE" \
-d '{"days": 90}'

A high-traffic site may need only 90 days of raw data. A site subject to statutory record-keeping requirements may need seven years. You set the policy; HitKeep enforces it.

The retention worker and backup worker can write to local disk or any S3-compatible object store. Both share the same S3 credential configuration.

Archive and backup destinationsLeader-only retention and backup workers each write to either a configured local filesystem path or an S3-compatible destination.ARCHIVERetention workerHITKEEP_ARCHIVE_PATHBACKUPBackup workerHITKEEP_BACKUP_PATHLOCALLocal archive path/var/lib/hitkeep/archiveLOCALLocal backup path/var/lib/hitkeep/backupsS3S3 archive paths3://bucket/archiveS3S3 backup paths3://bucket/backupsLEGENDFOCALSERVICESTOREEXTERNAL

Instead of writing Parquet files to a local directory, HitKeep can archive directly to any S3-compatible object store. Set HITKEEP_ARCHIVE_PATH to an s3:// URL and configure credentials.

Terminal window
export HITKEEP_ARCHIVE_PATH=s3://my-analytics-bucket/hitkeep/archive
export HITKEEP_S3_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export HITKEEP_S3_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
export HITKEEP_S3_REGION=eu-west-1
./hitkeep

On EC2, ECS, or Lambda with an attached IAM role, no explicit keys are needed. HitKeep falls back to the AWS SDK default credential chain automatically.

Terminal window
export HITKEEP_ARCHIVE_PATH=s3://my-analytics-bucket/hitkeep/archive
export HITKEEP_S3_REGION=eu-west-1
./hitkeep
# Logs: "S3 archive enabled" mode="credential chain" region="eu-west-1"
Terminal window
export HITKEEP_ARCHIVE_PATH=s3://hitkeep-archive/data
export HITKEEP_S3_ACCESS_KEY_ID=minioadmin
export HITKEEP_S3_SECRET_ACCESS_KEY=minioadmin
export HITKEEP_S3_ENDPOINT=localhost:9000
export HITKEEP_S3_URL_STYLE=path
export HITKEEP_S3_USE_SSL=false
export HITKEEP_S3_REGION=us-east-1
./hitkeep
Terminal window
export HITKEEP_ARCHIVE_PATH=s3://my-r2-bucket/hitkeep/archive
export HITKEEP_S3_ACCESS_KEY_ID=your-r2-access-key
export HITKEEP_S3_SECRET_ACCESS_KEY=your-r2-secret-key
export HITKEEP_S3_ENDPOINT=your-account-id.r2.cloudflarestorage.com
export HITKEEP_S3_REGION=auto
./hitkeep

See the Configuration Reference for the full list of S3 settings.

Archived Parquet files are standard open-format files queryable with any compatible tool — no HitKeep license required.

Query hot and cold analytics togetherDuckDB or another Parquet-capable tool reads the live database and archived site Parquet files, then combines both sources with UNION ALL.QUERYDuckDB or Parquet toolSELECT … FROMLIVEHot DuckDB tierATTACH 'hitkeep.db'ARCHIVECold Parquet tierread_parquet('…')OUTPUTCombined result setUNION ALLLEGENDINPUTSTOREFOCAL
Terminal window
# DuckDB CLI — count page views per month from the archive
duckdb -c "
SELECT date_trunc('month', timestamp) AS month, count(*) AS hits
FROM read_parquet('/var/lib/hitkeep/archive/site_*.parquet')
GROUP BY 1 ORDER BY 1;
"
Terminal window
# Merge hot and cold data in a single query
duckdb -c "
ATTACH 'hitkeep.db' AS hot;
SELECT timestamp::date AS day, count(*) AS hits
FROM (
SELECT timestamp FROM hot.hits WHERE site_id = 'your-site-id'
UNION ALL
SELECT timestamp FROM read_parquet('/var/lib/hitkeep/archive/site_your-site-id_*.parquet')
)
GROUP BY 1 ORDER BY 1;
"

The archive naming convention is site_{site_id}_{unix_timestamp}.parquet. Each archival run writes one file per site that had data past the cutoff.

HitKeep includes a built-in backup worker that periodically exports all live databases to Parquet snapshots using DuckDB’s EXPORT DATABASE. This covers both the shared hitkeep.db and any per-tenant databases.

For a dedicated operational guide, see Backups and Restore and S3 Backups.

Backup worker lifecycleAt startup HitKeep checks the backup path, waits before the first enabled cycle, checkpoints and exports shared and tenant databases, applies destination-specific retention, and repeats on the configured interval.NOYESNEXT CYCLESTARTHitKeep startsBackup path set?NOBackups disabledno-opYESWait 30 secondslet databases settleCYCLECheckpoint databasesshared + active tenantsDUCKDBExport snapshots{path}/{scope}/{timestamp}CLEANUPApply retention policylocal prune or S3 lifecycleREPEATWait backup intervalthen run againLEGENDINPUTDECISIONENDSERVICEFOCAL
Terminal window
# Local backups — every 60 minutes, keep 24 snapshots
export HITKEEP_BACKUP_PATH=/var/lib/hitkeep/backups
./hitkeep
# Logs: "Local backup enabled" path="/var/lib/hitkeep/backups" interval_min=60 retention=24
Terminal window
# S3 backups — every 30 minutes, keep 48 snapshots
export HITKEEP_BACKUP_PATH=s3://my-bucket/hitkeep/backups
export HITKEEP_BACKUP_INTERVAL=30
export HITKEEP_BACKUP_RETENTION=48
./hitkeep

The worker runs on the leader node only. The first backup is taken 30 seconds after startup, then at the configured interval.

Each backup is a timestamped directory containing the output of DuckDB’s EXPORT DATABASE (a schema.sql file plus Parquet data files for each table).

Backup snapshot layoutEach backup root contains timestamped shared-control-plane exports and timestamped exports grouped beneath each tenant identifier.SOURCELive DuckDB databasescontrol plane + tenant filesROOT{backup-path}/EXPORT DATABASESCOPEshared/control-plane snapshotsSCOPEtenants/grouped by tenant IDSNAPSHOT{timestamp}/schema.sql + *.parquetSNAPSHOT{tenant-id-1}/{timestamp}/schema.sql + *.parquetSNAPSHOT{tenant-id-2}/{timestamp}/schema.sql + *.parquetLEGENDINPUTFOCALSERVICESTORE

Or as a directory tree:

{backup-path}/
├── shared/
│ ├── 2026-03-02T120000Z/ ← schema.sql + *.parquet
│ └── 2026-03-02T130000Z/
└── tenants/
└── {tenant-id}/
├── 2026-03-02T120000Z/
└── 2026-03-02T130000Z/

For local backups, snapshots beyond the retention count are automatically deleted (oldest first). For S3 backups, configure S3 lifecycle policies on your bucket to manage snapshot retention.

Use the hitkeep recover restore-backup command to import a snapshot into fresh databases. HitKeep must be stopped before running a restore (DuckDB allows only one writer at a time).

Restore a backup safelyThe restore command selects a local or explicit S3 snapshot, shows the target summary, requires confirmation, protects existing databases, imports shared and tenant snapshots into fresh files, and then allows normal startup.NOYESCLIrestore-backup command-from … [-snapshot …]Choose snapshot sourcelatest local or explicit S3 timestampREVIEWPrint restore summarysource · target · tenantsConfirmed?-yes or interactive approvalNOAbort without changesYESProtect existing databasesrename to .pre-restore.{ts}CONTROLImport shared snapshotfresh DuckDB + checkpointANALYTICSImport tenant snapshotsdiscover tenants/*DONERestore completestart HitKeep normallyLEGENDINPUTDECISIONSERVICEENDFOCALSTORE
Terminal window
# Restore the latest local snapshot
./hitkeep recover restore-backup \
-from /var/lib/hitkeep/backups \
-yes
Terminal window
# Restore a specific snapshot
./hitkeep recover restore-backup \
-from /var/lib/hitkeep/backups \
-snapshot 2026-03-02T120000Z \
-db /var/lib/hitkeep/data/hitkeep.db \
-data-path /var/lib/hitkeep/data \
-yes
Terminal window
# Restore from S3 (snapshot timestamp required)
./hitkeep recover restore-backup \
-from s3://my-bucket/hitkeep/backups \
-snapshot 2026-03-02T120000Z \
-yes

The restore process:

  1. Finds the requested snapshot (or the latest one for local sources).
  2. Renames existing database files as a safety net (.pre-restore.{timestamp}).
  3. Imports the snapshot into temporary DuckDB files, checkpoints them, and only then promotes them into place.
  4. Discovers and restores any tenant databases from the backup.

On the next normal hitkeep startup, the migration system will apply any schema changes if HitKeep has been upgraded since the backup was taken.

See the Configuration Reference for all backup settings.

For users who prefer external tooling, the complete HitKeep data footprint is:

  • Live data tree: the full data-path directory, including the shared control plane and any tenant-local databases
  • Archive: the configured archive directory (Parquet files)

A reliable backup is a periodic file copy of both:

Terminal window
# Example: nightly sync to S3-compatible storage with rclone
rclone sync /var/lib/hitkeep/data/ remote:my-bucket/hitkeep/data/
rclone sync /var/lib/hitkeep/archive/ remote:my-bucket/hitkeep/archive/
Terminal window
# Or with rsync to a remote host
rsync -az /var/lib/hitkeep/ backup-host:/backups/hitkeep/

Because HitKeep stores its live state on the local filesystem, you can also use filesystem-level snapshots (LVM, ZFS, APFS) for point-in-time consistency — but snapshot the full data-path, not just the root database file.

The following diagram shows how data moves through HitKeep — from ingestion to hot storage, through retention archiving to cold storage, and how backups and restores fit into the picture.

Complete HitKeep data lifecycleIngest resolves analytics into live tenant databases; leader-only lifecycle workers create retention archives and full backup snapshots, which can use local or S3-compatible storage, while restore recreates live databases from snapshots.RETENTIONBACKUPIMPORTINGESTBrowser, server, and AI ingestHTTP + embedded NSQROUTETenant Store Managersite → tenantHOTLive DuckDB data planescontrol + tenant databasesWORKERSLeader-only lifecycle workersretention · backup · rollupCOLDRetention archivesper-site Parquet exportsBACKUPBackup snapshotsfull database exportsDESTINATIONLocal or S3-compatible storagefilesystem · S3 · MinIO · R2RECOVERYrestore-backupIMPORT DATABASERESTOREDRecreated live databasescheckpointed before promotionLEGENDINPUTFOCALSTORESERVICEEXTERNALOPTIONAL

The key insight: retention archives and database backups serve different purposes. Retention exports are per-site, incremental Parquet files for long-term analytical querying. Database backups are full point-in-time snapshots for disaster recovery. Both can target local disk or S3.

HitKeep Cloud manages retention policies, automated Parquet archiving, and encrypted off-site backups in your chosen managed region (EU Frankfurt or US Virginia). Start with HitKeep Cloud →