Some fun stuff you can do - RTT analysis, just using SQL :-) :
-- RTT Analysis using TCP timestamp echo
-- Measures actual network RTT by tracking when our ts_val gets echoed back
-- For client-side captures: dst_port in (80,443) = outbound, src_port in (80,443) = inbound
WITH outbound AS (
-- Packets TO server (dst_port is well-known)
SELECT
t.frame_number,
f.timestamp as send_ts,
t.dst_port as server_port,
t.ts_val,
i.src_ip as local_ip,
t.src_port as local_port,
i.dst_ip as remote_ip
FROM tcp t
JOIN ipv4 i ON t.frame_number = i.frame_number
JOIN frames f ON t.frame_number = f.frame_number
WHERE t.ts_val IS NOT NULL
AND t.dst_port IN (80, 443, 8080, 8443)
),
inbound AS (
-- Packets FROM server (src_port is well-known)
SELECT
t.frame_number,
f.timestamp as recv_ts,
t.src_port as server_port,
t.ts_ecr,
i.dst_ip as local_ip,
t.dst_port as local_port,
i.src_ip as remote_ip
FROM tcp t
JOIN ipv4 i ON t.frame_number = i.frame_number
JOIN frames f ON t.frame_number = f.frame_number
WHERE t.ts_ecr IS NOT NULL
AND t.ts_ecr > 0
AND t.src_port IN (80, 443, 8080, 8443)
),
-- Match: find when our ts_val was echoed back by the server
rtt_samples AS (
SELECT
o.frame_number as send_frame,
MIN(i.frame_number) as recv_frame,
o.server_port,
o.send_ts,
MIN(i.recv_ts) as recv_ts
FROM outbound o
JOIN inbound i
ON o.local_ip = i.local_ip
AND o.local_port = i.local_port
AND o.remote_ip = i.remote_ip
AND o.server_port = i.server_port
AND i.ts_ecr = o.ts_val
AND i.frame_number > o.frame_number
GROUP BY o.frame_number, o.server_port, o.send_ts
),
rtt_values AS (
SELECT
server_port,
EXTRACT(EPOCH FROM (recv_ts - send_ts)) * 1000.0 as rtt_ms
FROM rtt_samples
WHERE recv_ts > send_ts
)
SELECT
server_port,
hdr_count(hdr_histogram(rtt_ms)) as samples,
ROUND(hdr_min(hdr_histogram(rtt_ms)), 2) as min_ms,
ROUND(hdr_percentile(hdr_histogram(rtt_ms), 0.50), 2) as p50_ms,
ROUND(hdr_percentile(hdr_histogram(rtt_ms), 0.75), 2) as p75_ms,
ROUND(hdr_percentile(hdr_histogram(rtt_ms), 0.95), 2) as p95_ms,
ROUND(hdr_percentile(hdr_histogram(rtt_ms), 0.99), 2) as p99_ms,
ROUND(hdr_max(hdr_histogram(rtt_ms)), 2) as max_ms,
ROUND(hdr_mean(hdr_histogram(rtt_ms)), 2) as mean_ms
FROM rtt_values
WHERE rtt_ms > 0 AND rtt_ms < 30000
GROUP BY server_port
ORDER BY samples DESC;
Results from my local machine to a speedtest server:
Some fun stuff you can do - RTT analysis, just using SQL :-) :
Results from my local machine to a speedtest server: