Nginx 1.31.5 ships with built-in JSON parser, Control API, and predicate locations
The mainline branch just got a serious injection of new features. Nginx 1.31.5 dropped today, tagged by core developer Roman Arutyunyan on GitHub. It's a feature release, not a security patch, but it introduces four major architectural changes that push the reverse proxy further toward a programmable platform.
Fourteen days. That's the gap between 1.31.4 and 1.31.5. The even-numbered stable line remains the safe choice for production, but the odd-numbered 1.31.x branch is where the experimental work lands.
What's actually new in 1.31.5
The headline feature is a Control API. You can now launch nginx with -l 127.0.0.1:1234 to expose an HTTP/1 REST interface over a Unix socket or IP address. A quick curl 127.0.0.1:1234/1/control/processes returns a JSON array of running worker processes, and /1/control/config dumps your currently parsed configuration. It even supports live reloads. Ava Hahn at F5 Networks authored the bulk of it, with co-authors from F5 and the nginx team.
Predicate locations are arguably the most impactful change if you route traffic heavily. Location names starting with $ are now evaluated at runtime. If a map directive resolves to a non-empty string that isn't '0', the location matches. It opens the door for declarative, variable-driven routing without chaining if and return blocks together.
Then there's ngx_http_json_module. The JSON parser pulls values directly out of nginx variables and exposes them as fresh variables. json_set $user_name $arg_data user.name; does the work that previously required Lua scripting or external filter modules. The parser caches results per request, so multiple directives pulling from the same source expression only trigger one parse. Roman Semenov at F5 handled the implementation.
The new client_body_early_read directive lets you pull the request body after headers but before location selection. You can pass it a boolean expression tied to map directives, making content-type-based routing and early payload validation straightforward. It accepts predicates too, which is a nice touch.
Security, stability, and the bigger picture
The official change log lists the four new features and six bugfixes without hiding them behind marketing copy. 'Control API', 'Predicate locations', 'JSON parser module', and 'client_body_early_read' are named plainly, followed by the security and stability fixes. A use-after-free in HTTP/2 proxy buffering, an FD exhaustion issue during worker shutdown, and a QUIC CRYPTO frame rejection to prevent protocol-level attacks round out the patch list. There's also a slice filter overflow guard and an end marker fix for the memcached module.
The 1.31.x series has been aggressively addressing CVEs all year, with external researchers like Mufeed VH and Leo Lin flagging heap overflows and use-after-free conditions that made it into 1.31.0 through 1.31.3. As Arutyunyan noted in the release commit, the feature window ran from August 11 to August 28. The team packed four architectural additions and six bugfixes into a fourteen-day cycle.
For production deployments, stick with the stable even-numbered branch. The mainline series is perfect for testing out new routing and parsing capabilities, but you'll want to give these features a proper soak cycle before trusting them with live traffic.
Head here to download the source code from GitHub
