QUERY: a new kind of web request for big questions
Long searches break web addresses, and the usual workaround switches off caching. A new web standard fixes both. Here is what it changes for your shop or app.
What this means for you
- Long searches and order lists stop failing. The question travels in the body of the request, where the size limits are far higher.
- Customer details stay out of web addresses, so they do not end up in logs, browser history and bookmarks.
- Repeated questions can be answered from a cache once your hosting supports it, which takes load off your server.
Try it
A wholesale customer pastes their order list into your shop to check what is in stock. Drag the slider to make the list longer and watch what happens to the request on its way to your server.
- IIS, query string679 of 2,048Passes
- Apache, request line703 of 8,190Passes
- CloudFront, address690 of 8,192Passes
Every server on the list accepts this address.
Somewhere past 120 items, the first server says no.
A question written on the outside
Most websites and apps ask their questions with a GET request, the same kind your browser sends to open a page. The question goes into the web address itself, after the question mark: /api/stock?sku=KO-10000-BLK&sku=…. That part of the address is called the Query stringThe part of a web address after the question mark, such as ?colour=red&size=10, that carries the details of a search..
For a short search that works well. But every server, proxy and CDNA content delivery network: servers around the world that sit in front of your site, keep copies of its answers and hand them out quickly. between your customer and your shop sets its own limit on how long an address may be, and nobody can know them all in advance. When a question grows past one of them, the request is turned away before your shop ever sees it.
A short search arrives whole
A long one is cut off on the way
Addresses also travel further than most people expect. They end up in server logs, analytics tools, browser history and bookmarks. A search for a customer by name, or the list of what a business is ordering, is written on the outside for every system on the way to keep.
The limits
HTTP itself only recommends that software supports addresses of at least 8,000 octets (RFC 9110, section 4.1). The defaults in the demo come from the vendors' documentation: IIS request filtering allows a 2,048 byte query string and answers with 404.15 beyond it, Apache's LimitRequestLine defaults to 8,190 bytes for the whole request line, and CloudFront accepts URLs up to 8,192 bytes. RFC 10008 names the real problem: a request "can pass through many uncoordinated systems", so the smallest limit on the path wins, and you rarely know which one that is.
Why not use an envelope?
The usual way around this is to send the question in the body of the request, like a letter in an envelope. Developers do that with a POST request, the kind a web form sends when someone places an order or signs up.
The catch is what POST tells every system on the way: this request may change something. So a CacheA store of recent answers kept close to the visitor, so the same question can be answered again without asking your server. will not keep the answer, and nothing sends the request again on its own after a dropped connection, in case your customer ends up with the same order twice. A question that only reads stock levels gets treated like an order.
There is a third trick, a GET request with a body. The HTTP standard says such a body has no defined meaning, so servers and proxies may ignore it or refuse the request, and browsers will not send one at all.
GET: the question in the address
- No: Question kept out of logs
- Yes: Answer can be cached
- Yes: Safe to send again
POST: hidden, but treated as a change
- Yes: Question kept out of logs
- No: Answer can be cached
- No: Safe to send again
QUERY: hidden and marked as safe
- Yes: Question kept out of logs
- Yes: Answer can be cached
- Yes: Safe to send again
What the standards say
RFC 9110 (section 9.3.1) says content in a GET request "has no generally defined semantics" and "might lead some implementations to reject the request". The Fetch standard goes further: the Request constructor throws a TypeError when a GET or HEAD request has a body, so fetch() cannot send one.
POST is neither safe nor idempotent in the IANA method registry. Clients and intermediaries therefore do not retry it automatically, and shared caches rarely store its responses: CloudFront, for one, documents that only GET responses are cached and responses to POST or PUT are not.
What QUERY changes
QUERY is a new HTTP methodThe verb at the start of every web request that says what it wants: GET to fetch something, POST to send something, and now QUERY to ask a question., published as a standard in June 2026. It sends the question in the body, like POST, and makes the same promise GET makes: asking changes nothing on the server.
That promise is the whole point. Because QUERY is marked safe and IdempotentA request that has the same effect whether it is sent once or five times, so software can safely send it again after a dropped connection., a cache may keep the answer and hand it out the next time the same question comes in, and software may send the request again after a dropped connection without risk. The address stays short, /api/stock, and the order list stays out of logs and history.
First time: your server answers
Same question again: the cache answers
Under the hood
RFC 10008 registers QUERY as safe and idempotent. The request content and its Content-Type define the query. A server that does not support the format answers 415 and can list what it accepts in the new Accept-Query response header, a structured field such as Accept-Query: application/json.
Responses are cacheable, but the cache key must include the request content and its metadata, so two different order lists never share an answer. Caches may strip differences that do not change the meaning before building the key, and the RFC warns that normalising too eagerly produces wrong hits.
A server can also hand out addresses for repeating the work with a plain GET: Location points to a resource that runs the same query again, Content-Location to the results just produced, and a 303 says the query can be answered by a normal GET on the given URI. Redirects keep the method: unlike POST, a QUERY that meets a 301 or 302 is sent again as a QUERY, never turned into a GET.
QUERY is not a CORS-safelisted method, so a cross-origin QUERY from a browser always starts with a preflight request.
The code
A stock check with QUERY
The request carries the list as JSON; the address stays fixed:
QUERY /api/stock HTTP/1.1
Host: shop.example
Content-Type: application/json
Accept: application/json
{ "skus": ["KO-10000-BLK", "KO-10037-RED"], "warehouse": "BNE" }On Node.js 22.2 or newer the built-in server accepts the method. Reject formats you do not support and say which one you do:
import { createServer } from 'node:http'
createServer(async (req, res) => {
if (req.method !== 'QUERY' || req.url !== '/api/stock') {
res.writeHead(404).end()
return
}
const type = req.headers['content-type']?.split(';')[0].trim()
if (type !== 'application/json') {
res.writeHead(415, { 'Accept-Query': 'application/json' }).end()
return
}
let body = ''
for await (const chunk of req) body += chunk
let skus
try {
;({ skus } = JSON.parse(body))
} catch {
res.writeHead(400).end()
return
}
// stockFor() is your own lookup; it only reads.
const stock = await stockFor(skus)
res.writeHead(200, {
'Content-Type': 'application/json',
'Cache-Control': 'max-age=60',
})
res.end(JSON.stringify(stock))
}).listen(3000)In the browser, fetch() sends it today. Write the method in capitals: fetch only normalises the case of the six classic methods.
const response = await fetch('/api/stock', {
method: 'QUERY',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ skus, warehouse: 'BNE' }),
})Can you use it yet?
The standard is finished and the tools are catching up. Node.js and Rust handle QUERY requests today, and .NET and Java's Spring have it in previews of their next releases. Browsers can send QUERY from a script, but they do not cache the answers yet, and neither do most CDNs.
So QUERY fixes the length and privacy problem as soon as your server supports it. The caching benefit follows as browsers and hosting catch up. Before switching, check that every firewall and proxy in front of your server lets the new method through: some, like IIS, can be set to refuse methods they do not know.
Support in November 2026
| Tool | QUERY |
|---|---|
| Node.js | node:http accepts it from 22.2.0 |
| Rust, http crate | Method::QUERY from 1.5.0 |
| .NET | HttpMethod.Query and ASP.NET Core support in the .NET 11 previews |
| Spring Framework | From 7.1.0-M2, with Accept-Query; CORS and caching left for later |
| OpenAPI | 3.2 describes QUERY operations |
| Browsers | fetch() sends it, with a preflight across origins; responses are not cached yet |
| nginx | Pull request open; it would not key the proxy cache on the body |
Until caches key on the body, a QUERY passing through nginx, a CDN or a browser cache is forwarded, not served from the cache. Keep your existing endpoint while clients move over, and check request filtering: IIS can deny any method that is not on its list.
Questions too big for your API?
We build and look after the APIs behind shops and apps, and we can tell you whether QUERY fits yours and what your hosting needs first.
Sources
- RFC 10008: The HTTP QUERY MethodRFC Editor, checked
- Hypertext Transfer Protocol (HTTP) Method RegistryIANA, checked
- POST request methodMDN Web Docs, checked
- Request Limits <requestLimits>Microsoft Learn, checked
- Apache Core Features: LimitRequestLineApache HTTP Server, checked
- QuotasAmazon CloudFront Developer Guide, checked
- RFC 9110: HTTP SemanticsRFC Editor, checked
- Fetch StandardWHATWG, checked
- Integrating the HTTP QUERY method (RFC 10008): method normalization, CORS, and cachingGitHub, whatwg/fetch, checked
- Support for 'QUERY' methodGitHub, nodejs/node, checked
- http changelog, 1.5.0GitHub, hyperium/http, checked
- Support HTTP QUERYGitHub, dotnet/aspnetcore, checked
- Add RFC 10008 (QUERY HTTP method) supportGitHub, spring-projects/spring-framework, checked
- HTTP MethodsOpenAPI Documentation, checked
- HTTP: added QUERY method supportGitHub, nginx/nginx, checked
Words from this article
- Query string
- The part of a web address after the question mark, such as ?colour=red&size=10, that carries the details of a search.
- CDN
- A content delivery network: servers around the world that sit in front of your site, keep copies of its answers and hand them out quickly.
- Cache
- A store of recent answers kept close to the visitor, so the same question can be answered again without asking your server.
- HTTP method
- The verb at the start of every web request that says what it wants: GET to fetch something, POST to send something, and now QUERY to ask a question.
- Idempotent
- A request that has the same effect whether it is sent once or five times, so software can safely send it again after a dropped connection.
- API
- The part of a system that other software talks to, such as the shop app asking your server for prices and stock.
Keep reading
Smooth page changes without rebuilding your website
Your website can feel like an app when visitors click between pages, with no rebuild and no extra loading time. Explained in plain English, with the code for developers.