CQRS in Go — Part 4: PostgreSQL as an event store
Implementing an append-only event store in Go with PostgreSQL: es_events table, subscriptions for projectors, replay from any point. No need for EventStoreDB.
Lessons learned, problems and solutions
Implementing an append-only event store in Go with PostgreSQL: es_events table, subscriptions for projectors, replay from any point. No need for EventStoreDB.
How to make two aggregates cooperate without knowing each other. Cross-aggregate event handlers, saga idempotency, partial failure handling.
The Handle(ctx, state, cmd) (Events, error) signature makes handlers testable without mocks, without DB, without Docker. The secret: zero side effects.
How to structure a CQRS aggregate in Go: value struct, Transition() returning a new state, mandatory Clone() for collections. The shared slice trap.
Idempotent commands with idempotency key, optimistic locking on aggregates, idempotent projections and outbox pattern. The 4 idempotency layers of a production Event Sourcing system.
What idempotency is, why it's crucial (retries, double-click, at-least-once), and how to implement it in Go: HTTP middleware, unique DB constraint, concurrency handling.
Complete security audit of a Debian 12 server after a brute force attack: custom fail2ban, SSH/SFTP chroot, auditd, permissions, automated AI audit, Docker, HTTP headers.
Complete method for diagnosing a slow PostgreSQL query: EXPLAIN ANALYZE, missing indexes (B-tree, GIN, BRIN), stale statistics, pg_stat_statements. From diagnosis to production fix, no fluff.
How to implement a per-IP rate limiter in Go using the token bucket from golang.org/x/time/rate: sync.Mutex, cleanup goroutine to prevent memory leaks, X-Forwarded-For, middleware targeted at POST /api/v1/jobs.
slog, errors.Join, context.WithoutCancel, iter.Seq2, testing/synctest, go tool — what has settled as standard in the best Go projects in 2025.