URL length limits have constrained HTTP for decades. GET can’t have a body. POST has side effects. Every complex read operation forced a compromise.

RFC 10008 fills that gap.

What is HTTP QUERY

QUERY is a new HTTP method. Published June 2026 as a Proposed Standard.

It combines the best of GET and POST:

  • Safe like GET. No state changes.
  • Idempotent like GET. Retry without fear.
  • Has a request body like POST.
  • Explicitly cacheable. Cache key is URI plus body.
  • Requires a Content-Type header.
  • Introduces Accept-Query for negotiation.

One method. No compromises.

The Problem It Solves

URLs have limits. 8KB recommended maximum. 2KB in practice.

Complex queries don’t fit:

  • GraphQL queries
  • Advanced search filters
  • Analytics dashboards with rich parameters
  • Report generation criteria

The workaround was POST. But POST is not safe. Not idempotent. Not cacheable.

You lost everything HTTP gives you for reads.

There is another problem. Query strings end up in logs. Access logs. Proxy logs. Browser history. Sensitive filter data does not belong there. A request body keeps it out.

How It Looks

Basic request:

QUERY /contacts HTTP/1.1
Host: example.org
Content-Type: application/sql
Accept: application/json

SELECT surname, givenname, email FROM contacts
WHERE domain = "example.net"

With curl:

curl --request QUERY --follow \
  --header "Content-Type: application/json" \
  --data '{"filter": {"status": "active", "region": "eu"}}' \
  https://api.example.org/search

Servers advertise supported query formats with Accept-Query:

Accept-Query: application/json, application/graphql

Method Comparison

Method Safe Idempotent Body Cached Use Case
GET yes yes no yes Simple retrieval
POST no no yes no State changes
QUERY yes yes yes yes Complex retrieval

Distributed Systems: What We Lost Without It

The missing QUERY method shaped distributed systems for twenty years. Not in theory. In production failures and abandoned designs.

Elasticsearch shipped GET with a body. The _search API sends JSON bodies on GET requests. The HTTP spec left GET bodies undefined. Proxies stripped them. Load balancers dropped them. Client libraries refused to send them. Elastic had to support POST as a fallback and document the mess. An entire ecosystem worked around a missing method.

GraphQL gave up on HTTP caching. Every GraphQL query goes over POST. CDNs can’t cache POST. Shared caches can’t cache POST. The ecosystem rebuilt caching from scratch: persisted queries, APQ, client-side normalized caches. Thousands of engineering hours spent reimplementing what HTTP already had. QUERY makes a GraphQL request cacheable at the edge with zero extra infrastructure.

Service meshes can’t retry reads sent as POST. Envoy, Istio, and Linkerd retry idempotent methods automatically. POST is not idempotent, so a failed read-only search query is not retried. The request was safe to retry. The method said otherwise. Teams either disabled the safety and retried POST blindly, or accepted higher error rates on reads. With QUERY, hedging and automatic retries on read paths just work.

Read replicas can’t be routed by method. A clean pattern: safe methods go to replicas, unsafe methods go to primary. POST-based query APIs broke it. Database proxies for Trino, ClickHouse, and InfluxDB can’t tell a read query from a write by looking at the method. Every one of them needed custom routing logic, path conventions, or header hacks. QUERY restores routing by method. The proxy needs no application knowledge.

Batch lookups hit the URL wall. Fetch 5,000 entities by ID from a downstream service. 5,000 UUIDs do not fit in a query string. So teams invented two-step APIs: POST the ID list to create a “query resource”, then GET the result. Extra round trip. Extra state on the server. Extra cleanup job for expired query resources. All of it replaceable by one QUERY request with the IDs in the body.

Federated queries fragmented into RPC. Cross-service search in microservice architectures often abandoned HTTP semantics entirely. Teams moved to gRPC or message queues for reads, not because HTTP was slow, but because HTTP had no method that meant “complex read”. The observability stack, the caching layer, the standard tooling: all lost in the migration.

The pattern repeats. The gap wasn’t exotic. It was the most common operation in distributed systems: a complex read.

Distributed Systems: What Improves Now

  • Edge caching of complex queries. Cache key is URI plus body. CDNs can serve repeated analytical queries without touching origin.
  • Safe cross-region retries. Idempotency is declared by the method, so global load balancers can fail over mid-request.
  • Request hedging on read paths. Send the same QUERY to two replicas, take the fastest answer, cancel the other.
  • Honest observability. Dashboards can finally separate reads from writes by method instead of guessing from paths.
  • Simpler API gateways. Rate limit reads and writes differently without parsing bodies or maintaining path allowlists.

Adoption Status

Published June 2026 as a Proposed Standard.

The authors matter: Julian Reschke (greenbytes), James M. Snell (Cloudflare), Mike Bishop (Akamai). Two of the largest CDNs co-wrote the spec. Edge support is coming.

Framework support is emerging. Axum for Rust already has PRs. Browser fetch() support is in progress. curl works today with --request QUERY --follow.

Practical Considerations

Intermediaries are the risk. Proxies, WAFs, and load balancers must pass the method through. Some middleboxes strip bodies from unknown methods.

If you control the full path from client to server, use QUERY now. If you don’t, POST with explicit cache headers remains the pragmatic choice.

Test the path before you commit.

Key Takeaways

QUERY is GET with a body. Safe, idempotent, cacheable.

The gap it fills is decades old. PROPFIND, REPORT, and SEARCH existed, but none were general-purpose.

Distributed systems paid the highest price for the gap: lost caching, unsafe retries, broken replica routing, two-step query APIs.

Adoption depends on intermediaries. Control your infrastructure, adopt early.

The most common operation in distributed systems finally has its own method.

References: RFC 10008, IETF datatracker.