nerv-audit

nerv-audit

Leader posted 2 min read

We needed an audit trail Envers couldn’t handle — so I built one

“Who changed this record?”
“What was the previous value?”
“When did it happen?”

Simple questions… until you actually need answers in production.


The problem we kept running into

In one of our systems, audit logs weren’t just “nice to have” — they were critical.

We needed:

  • Field-level change tracking
  • Historical queries (point-in-time views)
  • Reliable audit trails across services

So naturally, we tried Hibernate Envers.

At first, it worked.

Until it didn’t.


Where things started breaking

As the system grew, we hit real limitations:

  • Querying audit history became painful
  • Custom audit logic was hard to extend
  • Cross-service audit consistency was messy
  • Performance started becoming a concern

We weren’t just storing audit logs anymore —
we needed to use them as a first-class feature.

That’s where Envers started to feel like a constraint.


The turning point

At some point, we had two options:

  1. Keep patching around the limitations
  2. Build something that actually fits our needs

We chose the second.


What we built

We created nerv-audit — a modular audit framework designed for real-world backend systems.

Instead of treating auditing as a side-effect, we designed it as a core part of the architecture.

Key ideas:

  • Structured audit work units (not just snapshots)
  • Flexible query model for history retrieval
  • Clean separation between capture, storage, and querying
  • Extensible by design

A quick example

Instead of digging through raw audit tables, you can query changes like this:

AuditQuery query = AuditQuery.builder()
    .entity("User")
    .field("email")
    .changed()
    .build();

List<AuditResult> results = auditService.execute(query);

Now you’re not just storing history —
you’re actually asking questions from it.


What I learned building this

A few things became very clear:

  • Audit logs become product features faster than expected
  • If querying is painful, the audit system is incomplete
  • “Just use Envers” works… until scale and complexity kick in
  • Designing audit as a domain, not a utility, changes everything

⚠️ About the project

The project is structured in modules:

  • nerv-audit-core → full engine (commercial)
  • nerv-audit-lite / examples → publicly available

I decided to keep the core commercial, but still share:

  • Public modules
  • Examples
  • Integration ideas

Explore it here

If you’re dealing with similar problems, you might find this useful:

https://github.com/czetsuyatech/nerv-audit


Final thought

Most systems don’t think about audit logs until something breaks.

By then, it’s already too late.

If your system will ever need to answer:

“What changed, and why?”

…it’s worth designing for it early.

2 Comments

1 vote
2
1 vote

More Posts

React Native Quote Audit - USA

kajolshah - Mar 2

The Audit Trail of Things: Using Hashgraph as a Digital Caliper for Provenance

Ken W. Algerverified - Apr 28

Building a Movie Recommendation API with Spring Boot

alejandrotg-codeverified - Apr 28

Let's understand Retries in Spring Boot

Madhu - Oct 17, 2025

Why Email-Only Contact Forms Are Failing in 2026 (And What Developers Should Do Instead)

JayCode - Mar 2
chevron_left

Related Jobs

View all jobs →

Commenters (This Week)

5 comments
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!