All posts

Build vs. buy: the honest timeline of rolling your own audit log

Stefan · April 19, 2026 · 8 min read

Why “we'll just write a table and a few endpoints” becomes a six-month project you wish you'd bought.


Week 1

Someone asks for an audit trail. “Easy.” You add middleware. Every action gets logged to a Postgres table — user_id, action, created_at, metadata JSONB. You ship it Friday afternoon. Compliance removes the line item from the SOC 2 roadmap. Your PM is happy.

You think: this is going to be nothing.

Month 2

The table has twelve million rows. Your listing query — WHERE user_id = ? ORDER BY created_at DESC LIMIT 50 — is slow. You add the obvious index on (user_id, created_at). It helps for a week. Then someone asks to filter by metadata->>'role' = 'admin' and the planner ignores the index. You add a partial index. Then a functional one. Your DBA finds you at standup to ask what exactly you're doing.

Month 3

Legal returns with a question you didn't expect: “If a customer asks us to prove nothing was tampered with, what do we show them?” You say “the timestamps.” They say “what if someone changed the timestamps?” You say “the database has access logs.” They say “what if someone had access?”

You spend a weekend reading about hash chaining. You add a previous_hash column derived from sha256(previous_hash || row_content). On paper it works. In practice, two concurrent inserts race on the previous hash. You add an advisory lock per customer. Writes serialize. Your P99 triples. Nobody notices yet because you haven't sold to anyone big.

Month 4

You sell to someone big. Their CTO wants to embed your activity log inside their own product — a “who accessed what” tab for their end users. Now you need per-tenant filtering. You add a tenant_id column. Every query gets a WHERE tenant_id = ?. Your indexes balloon. The JSONB metadata you were storing freely suddenly needs structure so tenants can search it.

You add search. Postgres full-text is fine, then not fine. You add Elasticsearch. Now you have a sync job. The sync job falls behind during backfills. Customers see stale data. Support closes three tickets as “working as designed.”

Month 5

Someone files a GDPR deletion request. “Delete all my data.” You look at your audit log. Your audit log contains immutable records of the customer's activity, by design. Your log system exists specifically to prevent deletion. Legal and you have a two-hour call about which right wins.

You compromise: soft-delete the PII fields, keep the hash, break the hash chain, document the exception for auditors. Your hash chain now has asterisks. Nobody calls this a partial victory.

Month 6

An auditor arrives. They ask for:

  1. Evidence of SOC 2 CC7.2 — system monitoring.
  2. Evidence of CC7.3 — anomaly evaluation.
  3. Retention policy showing logs are kept at least seven years.
  4. Proof that only authorized personnel can read production logs.

You have (1). You have (2) if you squint and wave your hands. You do not have (3) because you never set a retention policy and your storage cost is already ballooning. For (4), your ops team has been running queries against the audit log for “investigation purposes” and there's no record of who did what.

The auditor is nice about it. Your engineering manager is not.


What you built vs. what you shipped

After six months of part-time work by one engineer, you have:

  • An audit log table.
  • A hash chain that breaks under concurrency and on GDPR deletions.
  • A search layer with a sync gap.
  • A retention policy you mean to implement.
  • A dashboard for internal use that was never supposed to be customer-facing but somehow is.
  • A compliance story that works if the auditor doesn't ask follow-up questions.

You have not shipped:

  • Per-log cryptographic integrity that survives concurrent writes.
  • Independent verification — customers can't prove anything without trusting your API.
  • Idempotent write semantics, so retries don't duplicate events.
  • A tamper-evident tip hash that customers can pin externally.
  • Export formats that auditors will accept without rework.

The math nobody puts on the slide

One engineer, 25% of their time, for six months:

  • ~$18,000 in salary-equivalent labor if you're generous.
  • ~$50,000 in real opportunity cost once you count context switching, code review, deployment incidents, and the senior engineer who had to help.

Then, ongoing:

  • ~$15,000 / year in maintenance — CVE patches on Elasticsearch, DB index rebalances, monitoring, on-call minutes.
  • Linear DB cost growth with log volume.
  • Paid auditor hours, every year, explaining the partial implementation.

That's about $65,000 in year one and $20,000+ per year after. For a system your product doesn't differentiate on.

The actual question

It isn't should we build or buy audit logging? It's is audit logging the thing our product should be distinctive at?

If you're building a compliance platform, a SIEM, a security product where the log is the product — absolutely build. The engineering cost is a feature, not a tax.

If you're building a B2B SaaS and audit logging is a line item on your SOC 2 roadmap — buy. A service costs a few hundred dollars a month. Whatever you would ship with the same six months of engineering time is worth more than that.

Four questions before you build

  1. Has anyone on the team shipped a correct hash-chained audit log in production, at scale, with retention and multi-tenancy? If yes, fine. If no, you're learning on the job.
  2. When that person leaves, who owns it?
  3. What happens the first time a customer asks for independent cryptographic verification?
  4. What does a 10-minute question from an auditor currently cost you — in engineering hours and in contracts stalled?

Three “I don't know”s and you're buying.

A gentler version of this take

I did this myself. Three times, at different companies, over 10 years. Each time I thought it would be simple. Each time I was wrong in a new and specific way — concurrency one year, GDPR the next, “the auditor wants a CSV” the year after.

Evelmo is the audit log I wish I'd bought instead.

You'll know if you should build. Most of you shouldn't.