{"slug": "nginx-forwards-the-new-http-query-method-but-refuses-to-cache-it", "title": "Nginx forwards the new HTTP QUERY method but refuses to cache it", "summary": "A test of the new HTTP QUERY method introduced in RFC 10008 found that Nginx proxies QUERY requests to a backend but treats them as uncacheable by default, producing four distinct backend hits for four identical requests, according to a write-up by a developer who hosted a QUERY-only search API on a Frankfurt VPS. In the same test, eight AI models all generated working Python clients using urllib.request.Request with method='QUERY' when the method was named explicitly, but every model defaulted to POST when the endpoint was described only as a JSON search API. The author recommends manually configuring proxy caching logic to recognize QUERY or continuing to use GET with encoded query strings until tooling catches up.", "body_md": "# Nginx forwards the new HTTP QUERY method but refuses to cache it\n\nRFC 10008 finally introduced the QUERY method, which is essentially a GET request that can carry a body. It is designed to be safe and idempotent, meaning it should be cacheable as long as the request body is included in the cache key. This solves the age-old problem of complex search queries that are too large for a URL but shouldn't be POSTs because they aren't modifying data.\n\nI spent a morning testing if the actual infrastructure around us supports this. I built a search API that only accepts QUERY requests—anything else returns a 405 Method Not Allowed—and hosted it on a small VPS in Frankfurt to see how it behaved behind Nginx.\n\n## Testing the API with LLMs\n\nI wanted to see if AI models could actually implement a client for this without being explicitly told to use the QUERY method. I set up the API to search an RFC index of about 9,800 entries. If you send a GET or POST, the server rejects it with an `Allow: QUERY` header.\n\nI tried two different prompting strategies across eight different models. First, I explicitly told them the endpoint required the QUERY method from RFC 10008. Every single model succeeded. They all generated Python code using `urllib.request.Request(url, data=body, method='QUERY')`, which works because Python's standard library doesn't validate the method string.\n\nThe logs showed a clean sweep of successful hits:\n\n```\nQUERY /rfcs/llama-4-maverick QUERY /rfcs/deepseek-v4-pro\nQUERY /rfcs/mistral-3-14b QUERY /rfcs/gemma-4-31b-it\nQUERY /rfcs/glm-5-3-flash QUERY /rfcs/openai-gpt-oss-120b\nQUERY /rfcs/openai-gpt-oss-20b QUERY /rfcs/minimax-m2-5\n```\n\nHowever, when I removed the explicit mention of the QUERY method and just described the API as a JSON search endpoint, every single model defaulted to POST. None of them attempted an OPTIONS request to check supported methods first.\n\n## The Nginx caching failure\n\nThe real discovery happened when I looked at the proxy layer. While Nginx happily proxies the QUERY method to the backend, it treats it as uncacheable by default.\n\nI ran a test where I sent four identical QUERY requests. In a world where RFC 10008 is respected, the first request should hit the backend and the subsequent three should be served from the Nginx cache. Instead, I saw four distinct hits on my backend logs. For comparison, when I ran the same test with POST requests (which are generally not cached), I saw the same behavior—but when I used a standard GET, the cache worked as expected.\n\nYou can verify this yourself with a simple curl command:\n\n```\nprintf '%s' '{\"title_contains\":\"QUERY\",\"limit\":1}' \\\n | curl -s -X QUERY --data-binary @- -H 'Content-Type: application/json' http://your-proxy-ip/rfcs\n```\n\nIf you check your Nginx access logs, you will see the QUERY request passing through, but it will never trigger a `HIT` in the cache status.\n\n## When to use QUERY instead of POST\n\nIf you are building a read-only API with complex filters, the temptation is to use POST because URLs have length limits and encoding nightmares. But using POST tells the rest of the internet \"do not cache this.\"\n\nUsing QUERY is the correct architectural choice for high-performance search endpoints, but as my test shows, you can't rely on Nginx (or current LLM-generated clients) to \"just work\" with it yet. You'll likely need to manually configure your proxy's caching logic to recognize the method or stick to GET with heavily encoded query strings until the tooling catches up.\n\n[Next ToolJet MCP can build a shipment control tower for about $0.17 using the Luna medium →](/en/threads/9158/)\n\n## All Replies （3）\n\nSo excited to finally see a privacy-first approach. I'm curious if this integrates with Obsidian or just Notion?\n\nFinally stopped fighting with config files. Does Cloudflare handle the 502s better or is it just hiding the mess?\n\nStoked to see this! I want to try this tonight with my current setup. Does this work with Nginx 1.25?", "url": "https://wpnews.pro/news/nginx-forwards-the-new-http-query-method-but-refuses-to-cache-it", "canonical_source": "https://promptcube3.com/en/threads/9174/", "published_at": "2026-09-10 20:49:19+00:00", "updated_at": "2026-09-10 21:13:14.583009+00:00", "lang": "en", "topics": ["ai-research", "developer-tools", "ai-tools"], "entities": ["Nginx", "RFC 10008", "QUERY method", "Python", "urllib.request.Request", "Frankfurt VPS", "POST", "GET"], "alternates": {"html": "https://wpnews.pro/news/nginx-forwards-the-new-http-query-method-but-refuses-to-cache-it", "markdown": "https://wpnews.pro/news/nginx-forwards-the-new-http-query-method-but-refuses-to-cache-it.md", "text": "https://wpnews.pro/news/nginx-forwards-the-new-http-query-method-but-refuses-to-cache-it.txt", "jsonld": "https://wpnews.pro/news/nginx-forwards-the-new-http-query-method-but-refuses-to-cache-it.jsonld"}}