Engineering / PostgreSQL benchmark study
Reliable evidence.
Measured honestly.
Inside Gentlity: Benchmarking Reliable AI Agent Evidence Ingestion with PostgreSQL
Before asking how fast evidence can arrive, we asked whether we could account for every event. A look inside our first PostgreSQL-backed ingestion baseline.
An agent can finish its task while the evidence of that task fails to arrive. A timed-out request might already have committed. A replay might duplicate a fact. A valid credential might be used against the wrong tenant. Before an ingestion rate is useful, those distinctions need to survive the entire path to storage.
For Gentlity, that makes correctness part of the benchmark, not a preface to it. We started with a small control run, then measured one deliberately modest workload: four synthetic tenants, five events per second, and a local PostgreSQL database. Here is what we observed, how we checked it, and where the evidence stops.
What an ingestion acknowledgement means
Gentlity connects agent evidence to reliability measurement and operational decisions. The ingestion path accepts run lifecycle events, evaluation outcomes and measurement-health observations. A receipt gives the platform a stable identity for a delivered event; a canonical digest lets it distinguish the same content arriving again from different content using the same identity.
In the tested integration, a machine credential establishes tenant authority. The application validates the request and registered deployment identity, builds the canonical digest, and persists the receipt and typed evidence in a PostgreSQL transaction. A new committed event receives HTTP 201; an identical committed replay receives HTTP 200. This is an application contract backed by database checks, not a claim that any HTTP success alone proves correctness.
- 01SDK + raw HTTP
Native v2 agent runs and a v1 compatibility workload.
- 02Authenticated API
Machine credential establishes tenant authority; request schema is validated.
- 03Canonical evidence
Source admission and deployment binding; canonical digest and identity checks.
- 04PostgreSQL commit
Receipt and typed evidence in the canonical transaction; ACK follows commit.
A separate verification process reads the committed receipt and checks digest, organization and deployment. This additional work is included in database observations. Logical flow only: no production deployment topology, queue or replica is implied.
The benchmark adds its own independent read after each acknowledgement. It checks the stored receipt, canonical digest, organization, deployment and acknowledged run identity. That check improves our ability to detect a broken experiment, but it also adds database work. We keep that overhead visible throughout the results. See evidence note 3.
The experiment we actually ran
We ran two separate experiments. Evidence ingestion correctness validation asked whether the system preserved each fact and handled repeated or conflicting requests safely. The PostgreSQL ingestion performance baseline measured one selected workload. The experiments used different PostgreSQL versions; they were not a version comparison, and neither searched for saturation.
| Detail | Correctness validation | Performance baseline |
|---|---|---|
| PostgreSQL | 16.15 | 17.11 |
| Hardware / OS | Local Mac; not a version comparison | Apple M5 Pro, 24 GiB RAM, 15 logical CPUs; macOS 26.5.1 arm64 |
| Workload | 12 synthetic events and three controls | Four synthetic tenants; 1,080 SDK-v2 events and 120 raw-v1 lifecycle records |
| Timing | Small correctness check | 60s warm-up, 180s measurement, 60s cooldown |
| Delivery | Real authenticated local HTTP | Real authenticated local HTTP through a benchmark-owned SDK transport bridge |
| Planned rate | Bounded low-load control | 5 unique events/s; maximum 6 HTTP attempts/s |
| Request concurrency | Maximum 2 configured | Maximum 16 configured; highest observed HTTP inflight was 1 |
| Persistence checks | Receipts, digests, replay and tenant/conflict controls | Each ACK checked against PostgreSQL; final exact receipt-set and digest/binding reconciliation |
The performance baseline ran on an Apple M5 Pro Mac with 24 GiB RAM and 15 logical CPUs, macOS 26.5.1 on arm64, and Python 3.11.17. PostgreSQL was a dedicated native local cluster; the API and database used loopback networking. The machine also had development activity, so this was not a dedicated-host capacity test. No customer data, cloud service or paid model calls were involved.
The SDK portion preserved whole four-event runs: start, a passing evaluation, completion and a healthy measurement report. The raw-v1 portion supplied compatibility lifecycle records. Actual encoded payloads were 371–619 bytes, below the planning reference near 2 KiB; the plan permitted smaller valid payloads. Those sizes matter when comparing any later experiment.
Safety limits included a 1,200-event cap, 1,440-attempt cap, three attempts per identity, 2 GiB scratch ceiling and combined sampled RSS strictly below 6 GiB, together with disk, CPU, connection and memory-pressure guards. The test had a 15-minute deadline and automatic cleanup of its isolated database. These were sampled soft limits, not native OS resource quotas. See evidence note 2.
Evidence ingestion correctness validation
The successful correctness validation acknowledged and verified persistence for 12 events in 15 HTTP attempts on PostgreSQL 16.15. Canonical digests matched. The three additional requests tested replay, tenant isolation and conflicting content.
- Identical replay
- HTTP 200Duplicate ACK, existing fact
- Foreign tenant credential
- HTTP 404Tenant-hidden response
- Changed-content identity
- HTTP 409Conflict, original digest preserved
Evidence Integrity and Tenant Isolation
Beyond measuring ingestion performance, we validated several important reliability guarantees. Duplicate submissions were handled without creating additional records, cross-tenant access was correctly restricted, and conflicting evidence submissions were rejected without altering previously stored data.
All 12 test events remained consistent throughout these checks, confirming the expected behavior of evidence persistence, isolation, and integrity controls under the tested conditions.
Sampled scratch and total RSS peaks for the successful correctness run were 51.17 MiB and 259.23 MiB respectively. These are sampled observations, not guarantees about instantaneous resource peaks. They also belong to the correctness run, not the PostgreSQL 17.11 performance result. See evidence note 1.
PostgreSQL ingestion performance baseline
The 180-second measurement window offered 900 events and received 900 committed acknowledgements: 5.00 events per second. Every one of those event identities was included in the final persistence verification. Across the full experiment, including warm-up, 1,200 events were acknowledged and verified. Cooldown introduced no new arrivals or attempts.
A steady offered rate. A deliberate stop.
Committed ACK completions per second · 10-second bins
Configured rate describes the workload the generator intends to offer. Achieved throughput counts observed completions in a defined interval. Here they agreed over the measurement window. Ten-second completion bins alternated between 5.1 and 4.9 events/s, reflecting the preserved scheduling of whole SDK runs; that is not a changing capacity estimate.
Averaging across the intentionally idle cooldown would answer a different question. We report the 180-second measurement window separately rather than use the full controller duration as a throughput denominator.
Reading the latency distribution
For the 900 measurement-window requests, nearest-rank HTTP latency was 16.83 ms at p50, 19.23 ms at p95 and 26.43 ms at p99. The zero-based chart below shows those observed percentiles, not a prediction for larger loads.
The measured distribution, in milliseconds.
Nearest-rank percentiles · Local PostgreSQL baseline · 900 requests
- p50
- 16.83 ms
- p95
- 19.23 ms
- p99
- 26.43 ms
This is client-observed HTTP transport time. It is not database-only query latency, transaction duration, authentication-stage time or SDK enqueue-to-acknowledgement time. The persistence verification query runs after the HTTP response and is excluded from this latency, while still contributing database and driver work during the experiment.
Across all 1,200 requests, the ledger recorded zero HTTP errors, timeouts or retries. That is the observed outcome of this run, not an error-rate guarantee or confidence bound for production. With observed HTTP concurrency of one, the experiment also says little about contention at the configured concurrency ceiling. See evidence note 2.
Close the accounting before interpreting the speed
A successful request log is only one part of the record. The benchmark compared the final receipt-ID set with its expected events, then checked every stored canonical digest and tenant/deployment binding before deleting the disposable cluster.
Visualization of recorded results, with identifying details removed. Not a runtime screenshot.
{
"workload": "Local PostgreSQL ingestion",
"scope": "full run, including warm-up",
"postgres": "17.11",
"offered": 1200,
"acknowledged": 1200,
"persisted": 1200,
"http_statuses": {
"201": 1200
},
"errors": 0,
"timeouts": 0,
"retries": 0
}The checks found no missing or extra receipt and no digest or binding mismatch. The performance run verified the positive bindings of all four tenants; it did not repeat the correctness run's foreign-credential, replay or changed-content controls. We keep those results separate. Neither test performed a crash-recovery, restart or failover drill.
The retained evidence contains request ledgers and successful persistence checks, not a database dump or a fresh database inspection after cleanup. That is the scope of the persistence claim.
Resource observations are context, not headroom
The performance run's full-run sampled scratch maximum was 53.46 MiB, combined resident memory (RSS) maximum 277.05 MiB, and maximum sampled database connection count four. These include startup and warm-up activity. RSS sums can double-count shared PostgreSQL pages, and sampling can miss transient peaks.
Read the database counter details
Inside the measurement window, the first and last PostgreSQL samples spanned 178.574 seconds. Their WAL counter delta was 2,861,662 bytes and database-size delta was 1,444,700 bytes. Those endpoints do not cover exactly 180 seconds, and PostgreSQL counters may lag. We do not turn them into a per-event storage cost or a production cost model.
The same sampled window recorded 3,788 commits and 2,676 rollbacks. The rollback counter is not a failed-ingestion count: all HTTP requests returned 201 and all receipts verified. Monitoring and verification queries and session cleanup contribute transaction work; individual rollback causes were not attributed. Likewise, the sampled audit-row delta is not a final audit-table reconciliation.
No short lock waits were observed in the samples, but that does not prove contention was absent. Pool checkout delays, authentication-stage timing, application-only CPU, active-versus-idle connections, final typed-table counts and checkpoint attribution remain unmeasured. See evidence note 3.
What we learned, and what comes next
We strengthened our benchmark tooling with pre-submission contract validation to ensure test data conforms to the ingestion API before performance measurements begin. Offered, attempted, acknowledged and persisted events answer different questions, and all four need to reconcile.
The measured lesson is deliberately smaller: this selected local workload sustained five acknowledged events per second with the latency distribution shown above, while the final receipt checks held. We did not measure maximum PostgreSQL throughput, enterprise capacity, customer counts or a production SLO. We do not extrapolate this rate into a daily-volume promise.
Future work should quantify verification overhead, repeat matched workloads, and then investigate lock contention, retry/audit amplification, connection pressure, WAL growth and tenant-skewed historical queries in future test scenarios. Those workloads have not been measured in this study.
Reliability engineering benefits from a result whose boundaries are as clear as its headline. For this baseline, the useful artifact is a reproducible workload, a closed receipt ledger and a measured local observation—not an untested scalability claim.
Evidence notes
- Correctness validation. Derived from the preserved successful correctness validation result and execution report: PostgreSQL 16.15, 12 persisted events, 15 attempts, the three control responses and sampled resource maxima.
- Performance baseline. Based on the recorded HTTP request measurements. Quantiles were independently recalculated from the 900 requests sent during seconds 60–240; acknowledgement throughput uses response-completion times in that same window. The full-run count includes warm-up; cooldown adds no events. Experiment date: 16 October 2026, not a publication date.
- Implementation and resources. Checked against the integrated ingestion route, evidence service, verification process and raw resource samples. Commit precedes acknowledgement; verification queries add work. Architecture is a logical representation of the tested path, not a production topology. The measurement extract below includes the chart values without credentials or identifying tenant data.
The sanitized measurement extract provides the chart values without credentials or tenant IDs. To place this work in context, explore Gentlity's product, open-source SDK and our introduction to Agent Reliability Engineering.