Java 27 went GA on September 15, 2026, and it is the most operationally consequential Java release in years — not because of language features, but because of defaults. G1 is now the garbage collector on every machine, every object header just shrank by a third, every TLS 1.3 handshake now prefers a quantum-resistant key exchange, and Intel Macs just fell off Oracle's maintenance list. None of it requires a code change. All of it lands on the platform team that ships the runtime.
If you run a self-hosted PaaS with a Java buildpack, here is the entire release reduced to the only question that matters — what do I have to do?
| # | Change | Who it hits | Action | Urgency |
|---|---|---|---|---|
| 1 | G1 is the default GC everywhere (JEP 523) | Every Java container under ~1.8 GB or on 1 CPU | Re-validate default memory sizing; keep -XX:+UseSerialGC as an escape hatch for the tiniest heaps | This sprint |
| 2 | Compact object headers on by default (JEP 534) | Every 64-bit workload | Expect 10–20% less heap; observe before shrinking limits | This sprint |
| 3 | Hybrid post-quantum TLS 1.3 (JEP 527) | Services terminating TLS in-JVM | Verify ingress/LB negotiates X25519MLKEM768; nothing to code | This quarter |
| 4 | macOS/x64 maintenance ends with 27 | macOS build hosts, CI runners, dev laptops | Audit the build fleet for Intel Macs; plan the ARM64 move | This quarter |
| 5 | Still a 6-month feature release, not LTS | Your runtime support matrix | Decide the LTS-default / latest-available policy before tenants ask | Now |
The rest of this post is the evidence behind that table: what each change does, the numbers that matter, and the representative cases — including the ones where the new default is not a free win.
The nine JEPs in sixty seconds: an operator's cut
JDK 27 ships nine JEPs: four final, four in preview, one in incubator. As a platform operator you can ignore more than half of them. Lazy Constants (JEP 531, third preview), Primitive Types in Patterns (JEP 532, fifth preview), Structured Concurrency (JEP 533, seventh preview), PEM Encodings (JEP 538, third preview), and the Vector API (JEP 537, twelfth incubator) are language and API futures — interesting, but nothing your buildpack needs to do. JFR In-Process Data Redaction (JEP 536) is final and genuinely useful for observability pipelines handling PII, but it is opt-in.
That leaves three final JEPs that change behavior for existing applications with zero code modifications — G1 everywhere, compact headers, and post-quantum TLS — plus one non-JEP event, the Intel Mac exit, that changes what your build fleet can run on. Those four are the post.
One framing note first: Java 25 is the current LTS. Java 27 is the second feature release after it, delivered on Oracle's unpausing six-month cadence, with JDK 28 early access already open and macOS/x64 deprecation paperwork (JEP 541) queued up in it. Everything below should be read through that lens: you are not being asked to migrate the world to 27, you are being asked to decide what your platform does about 27.
Memory math: G1 everywhere plus smaller headers
This is the section to read carefully, because it changes the two numbers every Java buildpack bakes into container defaults: which collector runs, and how big the heap needs to be.
G1 is now the default in all environments (JEP 523). Since Java 9, G1 has been the default — except on machines the JVM classified as non-server-class, roughly a single CPU or less than 1,792 MB of RAM, which silently got the Serial collector instead. That exception described exactly the shape of a lean container, so a large share of small cloud workloads have been running stop-the-world Serial GC without anyone choosing it.
As of 27, the exception is gone: no -XX flag means G1, on one vCPU and 512 MB alike. Years of G1 improvements closed the throughput and footprint gap that originally justified the fallback, and the Serial collector stays available via -XX:+UseSerialGC with no removal planned.
Object headers shrink from 96 to 64 bits by default (JEP 534). Every object on a 64-bit heap carried a 12-byte header; now it carries 8. Four bytes per object sounds trivial until you multiply it by the millions of small objects in a typical Spring Boot service.
The reported numbers: 10–20% less heap for typical small-object workloads, with SPECjbb2015 runs showing around 22% less heap and 8% less CPU. Amazon and SAP already run compact headers in production — SAP made them the default in its SapMachine fork — so this default arrives pre-hardened at serious scale.
Now the representative-case honesty this topic demands. First, the 22% is a benchmark, not a promise: HotSpot aligns every object to an 8-byte boundary, so the 4-byte saving only materializes when the smaller header crosses an alignment boundary. Object-heavy services win big; services with a few large arrays barely notice. Plan around the 10–20% range, not the headline.
Second, G1 is not free on the tiniest heaps: it carries more native (off-heap) bookkeeping than Serial, so a 256 MB container that fit comfortably under Serial RSS accounting can get tighter under G1 even as its Java heap shrinks. The net is still positive for almost everything above half a gigabyte, but "almost" is why you re-validate instead of assuming.
The concrete buildpack guidance: if your Java memory calculator sizes the heap as a fraction of the container limit, compact headers just bought every tenant 10–20% of headroom inside the same limit. Do not spend it on day one by shrinking default limits — let tenants observe a release cycle of lower heap pressure first, then tighten. And document the -XX:+UseSerialGC escape hatch for the sub-512 MB crowd before they file the ticket asking why RSS went up.
Post-quantum TLS is now the default handshake
JEP 527 adds hybrid post-quantum key exchange to TLS 1.3, and it is the release's headline security change. The threat model is "harvest now, decrypt later": adversaries record encrypted traffic today and decrypt it retroactively once quantum hardware matures, so the defense has to deploy before the threat fully arrives. The mechanism is a hybrid handshake combining classical ECDHE with ML-KEM-768, the NIST-standardized quantum-resistant algorithm (FIPS 203, formerly Kyber) — secure as long as either half holds.
Concretely, three new named groups exist — X25519MLKEM768, SecP256r1MLKEM768, SecP384r1MLKEM1024 — with X25519MLKEM768 placed first in the JDK's default preference order. Standard JSSE clients and servers get hybrid negotiation with no code changes.
That sentence is doing a lot of work, so here are its two honest footnotes. First, negotiation requires both peers to support the hybrid group; against an older peer the handshake falls back to a classical group and nothing is quantum-resistant. Your in-JVM services only get the protection on paths where the other end — ingress controller, load balancer, peer service — also speaks it.
Second, hybrid handshakes carry more bytes (a ML-KEM-768 public key and ciphertext ride along in the ClientHello/ServerHello), so middleboxes with fixed-size handshake assumptions are the classic breakage vector. The ecosystem has been shaking these out since Chrome and Cloudflare started hybrid experiments, but your own edge is your own edge.
For a self-hosted PaaS, the action list is short and genuinely this-quarter rather than this-week. Confirm your ingress and managed load-balancer path negotiates a hybrid group against a JDK 27 client — an openssl s_client with -groups X25519MLKEM768 against your edge settles it in one command. Then document which tenant-to-platform paths are hybrid once both ends upgrade, and otherwise do nothing: no flag to set, no tenant migration to run. This is the rare security upgrade whose rollout plan is "verify, then let the defaults work."
The Intel Mac exit: audit your build fleet, not your runtime
Buried under the JEP headlines is the change with the hardest deadline. Oracle engineers have stopped maintaining the macOS/x64 port as of JDK 27, and JEP 541 proposes formally deprecating it for removal starting in JDK 28. Building the JDK for Intel Macs now requires passing --enable-deprecated-ports, which downgrades the configure failure to a warning — with explicitly no guarantee the port builds, much less works. Apple is walking the same road from the other end, with macOS 27 expected to drop Intel support and take Rosetta 2 with it.
Scope this correctly and the blast radius is small: it touches macOS build and development machines, not runtime containers, which are Linux and never cared about this port. But "small" is not "zero," and the failure mode is silent staleness — an Intel builder that keeps producing artifacts on an unmaintained JDK while everyone assumes the toolchain is current. The audit checklist:
- Inventory CI runners, shared build hosts, and self-hosted GitHub Actions runners for macOS/x64 — including the 2019 Mac Pro in a cupboard everyone forgot.
- Check developer laptop policy: anyone still shipping from an Intel Mac needs a JDK vendor story (some vendors will carry the port longer than Oracle) or a migration date.
- Pin and date-stamp: if any Intel builder must survive past 27, record which JDK it is frozen on and who owns the exception.
Do this before JDK 28 formalizes the deprecation, while it is still a planning exercise and not a broken build.
Who owns runtime currency when the cadence never pauses
Step back from the individual changes and Java 27 poses the structural question every self-hosted Java platform eventually faces: Oracle ships every six months and never pauses — 26 in March, 27 in September, 28 already in early access — while your tenants sensibly want to deploy once and think about runtimes never. Somebody has to own the gap between those two clocks, and on a PaaS that somebody is you.
Three data points shape the policy. First, the ecosystem lags GA by design: Paketo's Java buildpacks picked up Java 26 over the summer (Azul Zulu's buildpack added 26, BP_JVM_VERSION=26 style selection followed), and Java 27 provider support will trail September 15 by weeks, not days. Do not promise day-one 27 on the day of the announcement.
Second, the patch treadmill may be accelerating: Oracle is reportedly moving critical security updates toward a monthly cadence alongside the existing quarterly cycle. That would turn "stay current" from four rebuilds a year into twelve for anyone tracking latest. Third, the LTS exists precisely to bound this: Java 25 carries long-term support, and most tenants should default to it.
The policy that falls out is boring, which is the point. Default new builds to the current LTS. Make the latest feature release available once your buildpack providers support it. Rebuild base images on the security cadence rather than the feature cadence. And publish the matrix so tenants never have to ask which Java they are getting. JDK 28's early-access horizon — Project Valhalla and JSON support taking shape — is your preview of what the next policy review will argue about, not something to act on today.
Java 27 is the release where the platform stops asking developers to opt into good defaults and just turns them on: G1 everywhere, 8-byte headers, quantum-resistant handshakes. For developers that means a free upgrade. For the team that ships the runtime — the buildpack versions, the memory calculator, the base images, the build fleet — it means a very concrete TODO list, and this post just handed it to you: re-validate sizing, verify the TLS edge, audit the Intel stragglers, and publish the currency policy. The defaults do the rest.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Star the repo on GitHub or deploy your first app today.



