Problem
src/routes/proxy.rs:66 creates a new reqwest::Client on every proxied request:
let client = reqwest::Client::new();
reqwest::Client owns its connection pool. Constructing one per request means the pool is thrown away after a single use, so HTTP keep-alive to upstream services never takes effect and every proxied request pays a fresh TCP (and TLS, if applicable) handshake. For an API gateway this is on the hot path and shows up directly in p99 latency.
This is the most clear-cut performance issue in the proxy hot path today and is worth fixing even at the MVP stage.
Proposed fix
- Build a single
reqwest::Client at startup in main.rs.
- Wrap it in
Arc<reqwest::Client> (or rely on Client's internal Arc and clone it directly — Client::clone is cheap).
- Pass it through
create_router and into the proxy handler via Axum State, alongside the existing PgPool.
- Use the shared client in
proxy() instead of reqwest::Client::new().
Notes
- No behavior change expected for callers; this is a pure performance fix.
- Consider setting reasonable defaults on the shared client (timeouts, pool idle settings) in a follow-up — out of scope for this issue.
Problem
src/routes/proxy.rs:66creates a newreqwest::Clienton every proxied request:reqwest::Clientowns its connection pool. Constructing one per request means the pool is thrown away after a single use, so HTTP keep-alive to upstream services never takes effect and every proxied request pays a fresh TCP (and TLS, if applicable) handshake. For an API gateway this is on the hot path and shows up directly in p99 latency.This is the most clear-cut performance issue in the proxy hot path today and is worth fixing even at the MVP stage.
Proposed fix
reqwest::Clientat startup inmain.rs.Arc<reqwest::Client>(or rely onClient's internalArcand clone it directly —Client::cloneis cheap).create_routerand into the proxy handler via AxumState, alongside the existingPgPool.proxy()instead ofreqwest::Client::new().Notes