Skip to content

Proxy Latency: PostgreSQL

This page shows how much latency the DDM proxy adds to queries on PostgreSQL. The same query was sent both directly to the database and through the proxy in the same run, alternating in every round (interleaved, 500 rounds). The goal was to isolate the latency added by the proxy from network fluctuation and to show where it comes from.

Summary

The proxy adds about 12 ms per query, regardless of the size of the result. Almost all of this comes from routing traffic through the proxy (transport, ~9 ms). Masking the data adds very little (~0–3 ms). Most of a query's total time (70–200 ms) comes from network/VPN latency, not from the proxy.

Component Added latency Note
Transport ~9 ms Extra network hop and relay. The largest component.
Masking ~0–3 ms Small; within the noise level.
Total 10–13 ms Does not grow with the number of rows. About 10–17% of total query time.

Results

Median (p50) time of each endpoint for each row count, and the differences between them. Values are in ms.

Rows Direct Proxy (no masking) Proxy (masking) Transport Masking Total %
100 69.5 80.6 82.2 +10.2 +2.8 +12.0 17%
200 110.6 116.1 109.4 +8.7 −0.3 +10.4 9%
500 77.6 90.2 90.0 +8.5 +1.5 +11.4 15%
1000 118.0 131.9 132.3 +9.2 +3.3 +13.4 11%
2000 (noisy) 200.9 212.7 213.5 +2.5 +8.5 +5.0 3%
  • Transport = proxy without masking − direct
  • Masking = proxy with masking − proxy without masking
  • Total = proxy with masking − direct

2000-row results

At 2000 rows, network congestion of up to 4 seconds on single queries distorted the measurement. Use the 100–1000 row results for decisions.

Findings

The proxy adds a fixed ~12 ms per query. Even when the result grows from 100 to 1000 rows, the overhead stays between 10 and 13 ms. The cost depends on each query passing through the proxy, not on the amount of data transferred.

Most of the cost is transport (~9 ms). This is the extra network node and protocol relay between the client and the database, a natural part of a proxy architecture.

Masking itself is very cheap (~0–3 ms). It is measured within the noise level. The masking rules used were light, and no per-row cost was seen. Turning on the masking engine does not noticeably slow down queries.

The high base latency comes from the network, not the proxy. Even direct queries take 70–200 ms and vary by ±40 ms regardless of row count (VPN/distance). The proxy adds only a fixed ~12 ms on top of this.

Where the Latency Comes From

A query no longer goes from the client directly to the database; it passes through the proxy. The added ~12 ms is the sum of these steps:

1. Extra network hop: client → proxy → database. The query and the response pass through one more node, which adds network latency in each direction. This is the largest part of the cost.

2. Protocol processing: The proxy decodes and rebuilds the database wire protocol, and parses and validates the incoming query.

3. Identity and authorization: Identifying the user, mapping it to the related device, and checking the authorization policy run on each connection/query.

4. Masking engine: Finding and transforming the columns to be masked in the result rows. The cost was low in this run (~0–3 ms) because the rules were light.

5. Buffering and relay: Copying and forwarding data between the two connections (client side and database side).

Small queries

If most of the application's queries return few rows, the proxy's whole cost is this fixed ~12 ms; the per-row cost is negligible. The effect is therefore felt in proportion to the number of queries in workloads that send many small queries.

How the Tests Were Run

The same query was sent to three endpoints and the times were compared:

Endpoint Path What it shows
Direct client → database Base time, no proxy.
Proxy (no masking) client → proxy → database, with a user that has no masking rules Only the cost of routing traffic through the proxy.
Proxy (masking) client → proxy → database, with a user that has masking rules Transport + masking.

The cost is split in two by taking the differences: transport = no masking − direct, masking = masking − no masking.

Interleaved Measurement

Network latency changes over time. Interleaved measurement protects the results from these changes.

  • Block method (not used): All direct queries run first, then all proxy queries. The two groups are measured minutes apart; if the network slows down in between, the difference is wrong.
  • Interleaved method (used in this run): In each round, one query is sent to each of the three endpoints in turn. Because the three measurements are taken seconds apart, slow network changes affect all three equally and cancel out in the difference. This is repeated for 500 rounds, and the median of the per-round differences is reported.

In this run, the base latency varied by ±40 ms regardless of row count. The interleaved method still measured the proxy difference steadily at ~12 ms; with the block method, this difference would have been lost in the network drift.

Test Setup

Setting Value
Method Interleaved (round-robin)
Rounds 500
Warm-up 5
Connection Reused
Threads Single thread
Columns Same column set for the users with and without masking
Network Real network (VPN)
Metric Median (p50) of per-round paired differences

Limitations

  • The metric is p50 (median). It shows the typical case and excludes outliers. p95/p99 were not used for decisions because they are sensitive to network queuing (single congestions of up to 4 seconds at 2000 rows).
  • The measurement was made over a real network/VPN. This is why the base latency is high and noisy. The total overhead (~12 ms) is reliable; the split between transport and masking has an uncertainty of a few ms and varies from run to run. At some points masking is measured near zero or even slightly negative; this is not a real speed-up, but the signal falling below the noise.
  • For cleaner isolation: Running the proxy and the database in a low-latency/local environment removes network noise and measures the fixed cost of small queries more precisely.