Skip to content

aws: use HTTP/1.1 for the S3 HTTP client to restore GCS throughput - #6914

Open
sealab2066 wants to merge 3 commits into
quickwit-oss:mainfrom
sealab2066:s3-http1-default
Open

sealab2066 wants to merge 3 commits into
quickwit-oss:mainfrom
sealab2066:s3-http1-default

Conversation

@sealab2066

Copy link
Copy Markdown

Description

Closes #6883.

Since #5777, the AWS SDK HTTP client offers h2 via ALPN. Google Cloud Storage accepts it, so every object storage request of a node goes through a single TCP connection limited to 100 concurrent streams. Searchers then cap at ~1.5-4 Gbit/s and wait on storage. 0.8 used HTTP/1.1 only for this reason (#1584).

aws-smithy-http-client has no option to restrict ALPN, neither in 1.2 (v0.9.1) nor in 1.5 (main). This PR adds an HTTP/1.1-only client in quickwit-aws (hyper-util legacy client + hyper-rustls with enable_http1() only), used by default:

  • keeps the caching DNS resolver from aws: use caching DNS resolver for S3 HTTP client to reduce lookup churn #6584
  • keeps HTTP_PROXY/HTTPS_PROXY/NO_PROXY support: CONNECT tunnel for HTTPS, forward proxy for HTTP
  • applies the connect and read timeouts from the SDK settings
  • maps connection failures to ConnectorError::io, so retries behave as before
  • QW_S3_ENABLE_HTTP2=true switches back to the current client

AWS S3 does not negotiate h2, so nothing changes for AWS users. If aws-smithy-http-client gets an HTTP/1.1-only option later, this client can go away.

How was this PR tested?

  • cargo +nightly fmt --all -- --check
  • bash scripts/check_license_headers.sh, bash scripts/check_log_format.sh
  • cargo clippy --workspace --all-features --tests
  • cargo test -p quickwit-aws: two new tests, one for HTTP/1.1 requests and one for a connection error reported as I/O
  • Load test against GCS (S3 API, flavor: gcs): one metastore + searcher node on a c3-standard-44, no split cache, 61 splits of ~10M docs. Unique search queries over a 12h window, 120s per stage:
concurrency main (84f9324) this PR this PR, QW_S3_ENABLE_HTTP2=true
10 1.2 qps, 1.7 Gbit/s 12.7 qps, 17.4 Gbit/s 1.0 qps, 1.5 Gbit/s
50 1.3 qps, 1.7 Gbit/s 13.6 qps, 18.4 Gbit/s 1.1 qps, 1.5 Gbit/s
100 1.2 qps, 1.6 Gbit/s 13.7 qps, 18.6 Gbit/s 1.2 qps, 1.6 Gbit/s

Connections to GCS at concurrency 50: main 1, this PR ~320, this PR with QW_S3_ENABLE_HTTP2=true 1. The same commit on v0.9.1 gets 16-17 qps, about the same as v0.9.1 with .enable_http2() removed from aws-smithy-http-client. More numbers in #6883.

🤖 Generated with Claude Code

@sealab2066
sealab2066 requested a review from a team as a code owner October 20, 2026 10:44
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-20T12:18:06.365447Z 2ed0747 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Since quickwit-oss#5777, the AWS SDK HTTP client offers h2 via ALPN. Google Cloud Storage
accepts it, so all the object storage requests of a node go through a single
TCP connection limited to 100 concurrent streams, which caps searcher
download throughput.

The client now only offers HTTP/1.1 by default, keeping the caching DNS
resolver and the HTTP_PROXY/HTTPS_PROXY/NO_PROXY support.
QW_S3_ENABLE_HTTP2=true restores the previous client.

Closes quickwit-oss#6883

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d5805b833b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +161 to +164
let response_result = if let Some(read_timeout) = read_timeout_opt {
tokio::time::timeout(read_timeout, response_future)
.await
.map_err(|elapsed| ConnectorError::timeout(elapsed.into()))?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Enforce read timeouts on each socket read

When an S3 upload takes longer than read_timeout while continuing to make progress (for example, a large split on a slower link), this wraps the entire Client::request future, which does not complete until S3 returns the final response headers, so a healthy upload is canceled and retried at that duration. It also stops timing once GET headers arrive, leaving response-body reads unprotected; HttpConnectorSettings::read_timeout needs to be installed on the underlying stream/per-read rather than used as a whole-request deadline.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This keeps the semantics of the current client on purpose. In aws-smithy-http-client, HttpReadTimeout wraps the whole client.call(request) future (client.rs, timeout.rs), so read_timeout already bounds the time until the response headers, uploads included, and does not cover the body reads. The HTTP/1.1 client applies the same deadline at the same place. Changing what read_timeout means would affect both clients and is out of scope for this PR.

Comment thread quickwit/quickwit-aws/src/http1.rs Outdated
The connect timeout of the HTTP/1.1 client only covered the TCP connect,
so a server or proxy that accepted the connection and stalled during the
CONNECT request or the TLS handshake was not bounded by it. The timeout
now wraps the whole connector, like the default AWS SDK client, and is
reported as a timeout error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sealab2066

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4b5dad3878

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread quickwit/quickwit-aws/src/http1.rs Outdated
Without a pool timer, hyper-util does not evict idle connections on its
own, so the connections opened during a burst stayed open until the
server closed them. The default AWS SDK client sets the same timer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sealab2066

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

Reviewed commit: 2ed074703e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Since 0.9, the S3 client negotiates HTTP/2 with GCS: one TCP connection per node, ~10x lower search throughput

1 participant