Architecture Review: Audit and Compliance Platform
An append-only audit log architecture for capturing system actions: user operations, data access events, configuration changes, and financial operations: with cryptographic integrity chaining, immutable storage, and dual-path query serving. PostgreSQL stores the authoritative append-only event log in time-partitioned tables; ClickHouse serves historical aggregate queries and retention analytics; Kafka streams audit events in real time to SIEM integrations and security dashboards; Redis caches hot audit query results for compliance-facing read paths. No record is ever updated or deleted: only inserts are permitted. Each record includes a hash of the previous record, forming a tamper-evident chain verifiable without external tooling.
Evidence Confidence
Moderate
strong
Executive Summary
Audit and Compliance Platform: moderate operational readiness (80% evidence confidence). 0 architectural strengths identified, 5 operational risks to manage. Primary concern: WAL Saturation. Requires Advanced operational maturity.
Readiness Rationale
Overall moderate readiness across 8 dimensions. Limited: team maturity. Strong: migration, observability, failure recovery.
Key Concerns
- !WAL Saturation
- !Write Amplification Cascade
Key Strengths
- +Architecture is well-defined for the financial ledger problem profile
8
Assessments
2
Tradeoffs
6
Sections
11
Recommendations
Readiness Assessments
8Architectural Tradeoffs
2Recommendations
11Monitor: WAL Saturation
risk_monitoringPostgreSQL WAL (Write-Ahead Log) generation rate exceeds wal_buffers flush capacity or downstream replica/WAL archive bandwidth, causing write transactions to stall waiting for WAL flush and replication lag to grow unboundedly.
Affects 1 node. (Write-Heavy Transactional)
Monitor: Write Amplification Cascade
risk_monitoringEach logical application write triggers multiple physical writes through index maintenance, WAL generation, MVCC versioning, and replication, causing actual disk IOPS to exceed the provisioned I/O ceiling while the logical write rate appears modest.
Affects 0 nodes
Implement: Monitor generic risk probe signals
observabilitySeed 'WAL Saturation Risk Probe' identifies 2 metrics relevant to wal_saturation.
Metrics to instrument: error_rate, p95_latency_ms
Application-level audit log in mutable table with update/delete allowed → Append-only partitioned audit log with cryptographic integrity chain
migration_planningTrigger: Compliance audit finding that audit records were modified after write; regulatory requirement (SOC 2 Type II, SOX, HIPAA) for tamper-evident audit log; inability to reconstruct historical actor activity from mutable state. Migrate from 'Application-level audit log in mutable table with update/delete allowed' to 'Append-only partitioned audit log with cryptographic integrity chain'. Bootstrap pre-migration state as a sealed genesis block per partition. Run the new append-only path in parallel with the mutable path for 30 days, comparing record counts. Decommission the mutable path only after chain integrity is verified across all source systems.
Existing mutable audit records cannot be retrofitted with a cryptographic chain; the chain starts from the migration cutover date: pre-migration records must be bootstrapped as a sealed historical block; Application code that previously used UPDATE or DELETE to correct audit records must be refactored; correction events must be new append-only records, not retroactive modifications
PostgreSQL full-text queries for compliance reports → ClickHouse for aggregate compliance analytics with CDC-based replication
migration_planningTrigger: Compliance report generation taking > 5 minutes against PostgreSQL; month-end audit export queries competing with write path and causing ingestion latency spikes; need for fast aggregate queries across 12+ months of audit history. Migrate from 'PostgreSQL full-text queries for compliance reports' to 'ClickHouse for aggregate compliance analytics with CDC-based replication'. Validate ClickHouse query latency against representative compliance workloads (actor access reports, resource access timelines, change diff exports) before cutting over report generation. Target p99 < 2s for the most common compliance query patterns.
ClickHouse CDC consumer lag means compliance reports have a staleness window; this must be disclosed to auditors and reflected in the compliance tooling; Initial ClickHouse population from PostgreSQL must complete before CDC takes over: initial sync ordering must preserve the chain sequence across all partitions
Prepare runbook for: Burst Traffic Cold Cache Stampede
simulation_preparednessSimulation demonstrates critical degradation of redis, postgresql
Without a runbook, recovery from this failure mode will be ad-hoc
Prepare runbook for: Connection Pool Exhaustion with Horizontal User Scale
simulation_preparednessSimulation demonstrates critical degradation of postgresql
Without a runbook, recovery from this failure mode will be ad-hoc
Plan evolution: OLTP Analytics Queries → OLTP + OLAP Separation
evolution_planningEvolution from Unified OLTP + Analytics on PostgreSQL → Separated OLTP (PostgreSQL) + OLAP (ClickHouse/Snowflake)
Migration complexity: medium. Rollback: always.
Plan evolution: Single Cache Layer → Distributed Cache
evolution_planningEvolution from Single Redis Node / Sentinel Cluster → Distributed Redis Cluster (Consistent Hash Ring)
Migration complexity: medium. Rollback: complex.
Monitor threshold: Tier 1: Integrity Chain Write Serialization
scaling_monitoringSignal: PostgreSQL write p99 > 20ms with low connection count; pg_stat_activity showing transactions serialized on the same partition's chain-tip read; ingestion throughput plateauing well below hardware limits; auto_explain showing sequential scan on audit_events for "SELECT hash FROM audit_events ORDER BY id DESC LIMIT 1"
Bottleneck: Per-partition chain-tip read before each insert serializing concurrent audit writers. Evolution: Introduce partition-level chain sequence tables: a single row per partition tracking the current chain tip with an advisory lock, eliminating the full table read. Alternatively, shard the integrity chain by source system or tenant, accepting per-shard chains rather than a single global chain. Use PostgreSQL INSERT ... RETURNING with sequence-assigned IDs to eliminate the pre-insert read entirely, deferring chain hash computation to an async integrity sealer that appends hashes in order without blocking the write path.
Monitor threshold: Tier 2: Actor Query Full-Partition Scan
scaling_monitoringSignal: Compliance investigator queries returning in > 30s; PostgreSQL showing high sequential scan counts on audit_events partitions; investigator-facing API p99 > 10s; pg_stat_statements showing actor_id-scoped queries without partition pruning in the query plan
Bottleneck: Missing secondary index table for actor_id and resource_id lookup paths across time-partitioned audit data. Evolution: Build a secondary index table audit_events_by_actor(actor_id, event_time, event_id) populated synchronously on insert. Accept the additional write per event as the cost of O(log n) actor-scoped queries. Alternatively, route actor-scoped queries to ClickHouse where columnar storage makes actor_id filters efficient without a secondary B-tree index.
Scaling Pressure Signals
8PostgreSQL write p99 > 20ms with low connection count; pg_stat_activity showing transactions serialized on the same partition's chain-tip read; ingestion throughput plateauing well below hardware limits; auto_explain showing sequential scan on audit_events for "SELECT hash FROM audit_events ORDER BY id DESC LIMIT 1"
Threshold
Tier 1: Integrity Chain Write Serialization
Likely Bottleneck
Per-partition chain-tip read before each insert serializing concurrent audit writers
Recommended Evolution
Introduce partition-level chain sequence tables: a single row per partition tracking the current chain tip with an advisory lock, eliminating the full table read. Alternatively, shard the integrity chain by source system or tenant, accepting per-shard chains rather than a single global chain. Use PostgreSQL INSERT ... RETURNING with sequence-assigned IDs to eliminate the pre-insert read entirely, deferring chain hash computation to an async integrity sealer that appends hashes in order without blocking the write path.
Compliance investigator queries returning in > 30s; PostgreSQL showing high sequential scan counts on audit_events partitions; investigator-facing API p99 > 10s; pg_stat_statements showing actor_id-scoped queries without partition pruning in the query plan
Threshold
Tier 2: Actor Query Full-Partition Scan
Likely Bottleneck
Missing secondary index table for actor_id and resource_id lookup paths across time-partitioned audit data
Recommended Evolution
Build a secondary index table audit_events_by_actor(actor_id, event_time, event_id) populated synchronously on insert. Accept the additional write per event as the cost of O(log n) actor-scoped queries. Alternatively, route actor-scoped queries to ClickHouse where columnar storage makes actor_id filters efficient without a secondary B-tree index.
PostgreSQL data volume growing > 100GB/month; disk utilization > 70%; VACUUM taking > 10 minutes on large audit partitions; oldest compliance query range spanning partitions that cannot be dropped without regulatory risk
Threshold
Tier 3: Partition Archive and Storage Pressure
Likely Bottleneck
Unbounded append-only storage without archival pipeline to object storage
Recommended Evolution
Implement time-partitioned archival: partitions older than the hot-query window (typically 90 days for operational queries, 1 year for compliance queries) are exported to Parquet on S3, validated against the cryptographic chain, and then detached. ClickHouse external tables can query S3 Parquet directly for historical range queries. PostgreSQL retains only the hot window.
A single high-volume tenant (e.g., a financial services customer generating 500k+ events/hour) causing write contention that affects audit ingestion latency for other tenants; per-tenant query SLAs diverging; partition layout making tenant-scoped data export impractical
Threshold
Tier 4: Multi-Tenant Write Path Isolation
Likely Bottleneck
Shared PostgreSQL write path and shared partitioning scheme unable to isolate high-volume tenants
Recommended Evolution
Introduce tenant-scoped write sharding: high-volume tenants get dedicated partition groups with their own chain sequences and their own ClickHouse materialization table. Low-volume tenants share a pooled partition group. This enables per-tenant storage tiering, export, and independent integrity chain management.
PostgreSQL write p99 > 20ms with low connection count; pg_stat_activity showing transactions serialized on the same partition's chain-tip read; ingestion throughput plateauing well below hardware limits; auto_explain showing sequential scan on audit_events for "SELECT hash FROM audit_events ORDER BY id DESC LIMIT 1"
Threshold
Escalation trigger: Per-partition chain-tip read before each insert serializing concurrent audit writers
Likely Bottleneck
Tier 1: Integrity Chain Write Serialization
Recommended Evolution
Monitor: error_rate, p95_latency_ms, replication_lag_seconds
Compliance investigator queries returning in > 30s; PostgreSQL showing high sequential scan counts on audit_events partitions; investigator-facing API p99 > 10s; pg_stat_statements showing actor_id-scoped queries without partition pruning in the query plan
Threshold
Escalation trigger: Missing secondary index table for actor_id and resource_id lookup paths across time-partitioned audit data
Likely Bottleneck
Tier 2: Actor Query Full-Partition Scan
Recommended Evolution
Monitor: error_rate, p95_latency_ms, replication_lag_seconds
PostgreSQL data volume growing > 100GB/month; disk utilization > 70%; VACUUM taking > 10 minutes on large audit partitions; oldest compliance query range spanning partitions that cannot be dropped without regulatory risk
Threshold
Escalation trigger: Unbounded append-only storage without archival pipeline to object storage
Likely Bottleneck
Tier 3: Partition Archive and Storage Pressure
Recommended Evolution
Monitor: error_rate, p95_latency_ms, replication_lag_seconds
A single high-volume tenant (e.g., a financial services customer generating 500k+ events/hour) causing write contention that affects audit ingestion latency for other tenants; per-tenant query SLAs diverging; partition layout making tenant-scoped data export impractical
Threshold
Escalation trigger: Shared PostgreSQL write path and shared partitioning scheme unable to isolate high-volume tenants
Likely Bottleneck
Tier 4: Multi-Tenant Write Path Isolation
Recommended Evolution
Monitor: error_rate, p95_latency_ms, replication_lag_seconds
Migration Readiness
12Migration Stages
3Application-level audit log in mutable table with update/delete allowed → Append-only partitioned audit log with cryptographic integrity chain
infoMigration trigger: Compliance audit finding that audit records were modified after write; regulatory requirement (SOC 2 Type II, SOX, HIPAA) for tamper-evident audit log; inability to reconstruct historical actor activity from mutable state
PostgreSQL full-text queries for compliance reports → ClickHouse for aggregate compliance analytics with CDC-based replication
infoMigration trigger: Compliance report generation taking > 5 minutes against PostgreSQL; month-end audit export queries competing with write path and causing ingestion latency spikes; need for fast aggregate queries across 12+ months of audit history
Single Kafka topic for all audit events → Per-source or per-severity topic partitioning with dedicated SIEM consumers
infoMigration trigger: SIEM consumer lag causing it to fall behind retention window during high-volume security events; high-priority security events (authentication failures, privilege escalations) mixed with low-priority operational events causing SIEM triage latency
Risks
9Existing mutable audit records cannot be retrofitted with a
warningExisting mutable audit records cannot be retrofitted with a cryptographic chain; the chain starts from the migration cutover date: pre-migration records must be bootstrapped as a sealed historical block
Application code that previously used UPDATE or DELETE to co
warningApplication code that previously used UPDATE or DELETE to correct audit records must be refactored; correction events must be new append-only records, not retroactive modifications
ClickHouse CDC consumer lag means compliance reports have a
warningClickHouse CDC consumer lag means compliance reports have a staleness window; this must be disclosed to auditors and reflected in the compliance tooling
Initial ClickHouse population from PostgreSQL must complete
warningInitial ClickHouse population from PostgreSQL must complete before CDC takes over: initial sync ordering must preserve the chain sequence across all partitions
Re-partitioning Kafka topics requires consumer group reset a
warningRe-partitioning Kafka topics requires consumer group reset and potential re-processing of historical events by downstream SIEM
Topic proliferation increases Kafka broker partition count;
warningTopic proliferation increases Kafka broker partition count; each topic requires retention policy management
Projection lag creates a read-after-write window where users
criticalProjection lag creates a read-after-write window where users see stale data after their own writes. Mitigation: Route immediate post-write reads to the write store (session-scoped write token); accept eventual consistency only for non-user-initiated reads
↗ direct-db-to-cqrs
Projection rebuild after schema change can take hours or day
criticalProjection rebuild after schema change can take hours or days on large datasets. Mitigation: Design blue/green projection deployment: build new projection in parallel before switching traffic; test rebuild time in staging
↗ direct-db-to-cqrs
Cross-service workflows that previously used database transa
criticalCross-service workflows that previously used database transactions now require Saga orchestration. Mitigation: Design idempotent event handlers; implement compensating transactions for every multi-step workflow; test failure injection in staging
↗ modular-monolith-to-event-driven
Review Sections
6Referenced Intelligence