Skip to main content
Version: v4

Transaction Logging

Harper provides two complementary mechanisms for recording a history of data changes on a table: the audit log and the transaction log. Both are available at the table level and serve different use cases.

FeatureAudit LogTransaction Log
StorageStandard Harper table (per-table)Clustering streams (per-table)
Requires clusteringNoYes
Available sincev4.1.0v4.1.0
Stores original record valuesYesNo
Query by usernameYesNo
Query by primary keyYesNo
Used for real-time messagingYes (required)No

Audit Log

Available since: v4.1.0

The audit log is a data store that tracks every transaction across all tables in a database. Harper automatically creates and maintains a single audit log per database. The audit log captures the operation type, the user who made the change, the timestamp, and both the new and original record values.

The audit log is enabled by default. To disable it, set logging.auditLog to false in harperdb-config.yaml and restart Harper.

The audit log is required for real-time messaging (WebSocket and MQTT subscriptions) and replication. Do not disable it if real-time features or replication are in use.

Audit Log Operations

read_audit_log

Queries the audit log for a specific table. Supports filtering by timestamp, username, or primary key value.

By timestamp:

{
"operation": "read_audit_log",
"schema": "dev",
"table": "dog",
"search_type": "timestamp",
"search_values": [1660585740558]
}

Timestamp behavior:

search_valuesResult
[]All records for the table
[timestamp]All records after the provided timestamp
[from, to]Records between the two timestamps

By username:

{
"operation": "read_audit_log",
"schema": "dev",
"table": "dog",
"search_type": "username",
"search_values": ["admin"]
}

By primary key:

{
"operation": "read_audit_log",
"schema": "dev",
"table": "dog",
"search_type": "hash_value",
"search_values": [318]
}

Response example:

{
"operation": "update",
"user_name": "HDB_ADMIN",
"timestamp": 1607035559122.277,
"hash_values": [1, 2],
"records": [
{
"id": 1,
"breed": "Muttzilla",
"age": 6,
"__updatedtime__": 1607035559122
}
],
"original_records": [
{
"__createdtime__": 1607035556801,
"__updatedtime__": 1607035556801,
"age": 5,
"breed": "Mutt",
"id": 1,
"name": "Harper"
}
]
}

The original_records field contains the record state before the operation was applied.

delete_audit_logs_before

Deletes audit log entries older than the specified timestamp.

Changed in: v4.3.0 — Audit log cleanup improved to reduce resource consumption during scheduled cleanups

Changed in: v4.5.0 — Storage reclamation: Harper automatically evicts older audit log entries when free storage drops below a configurable threshold

{
"operation": "delete_audit_logs_before",
"schema": "dev",
"table": "dog",
"timestamp": 1598290282817
}

Enabling Audit Log Per Table

You can enable or disable the audit log for individual tables using the @table directive's audit argument in your schema:

type Dog @table(audit: true) {
id: Long @primaryKey
name: String
}

This overrides the logging.auditLog global configuration for that specific table.

  • Logging — Application and system logging (separate from transaction/audit logging)
  • Replication — Clustering setup required for transaction logs
  • Logging Configuration — Global audit log configuration (logging.auditLog)
  • Operations API — Sending operations to Harper