1. Apex Heap Limits Finally Get Some Breathing Room
If you’ve ever shipped code that sailed through every sandbox test and then blew up in production with a System.LimitException: Apex heap size too large, you know exactly the feeling I’m talking about. It’s rarely your fault — sandboxes just don’t carry the data volume production does, so heap problems have a habit of hiding until it’s too late to catch them comfortably.
Winter ’27 bumps the ceiling in a real way, not a token gesture:
- Synchronous transactions go from 6MB to 10MB — that’s 66% more room.
- Asynchronous transactions more than double, from 12MB to 25MB.
Salesforce also snuck in an “Enforce the Summer ’26 Apex heap limit” setting, which is basically a training-wheels option; it lets you keep coding against the old, smaller limit inside a Winter ’27 sandbox so nothing weird happens when you push to production. Worth knowing: the new limits apply everywhere regardless of that setting; it’s really just there to smooth the transition.
If your org runs big batch jobs or heavy synchronous transformations, don’t just take my word for it — run Limits.getLimitHeapSize() before and after the upgrade and see where you actually land.
2. You No Longer Have to Recompile Everything
Anyone who’s worked in a large, mature org knows this pain personally: you fix one broken trigger, and suddenly you’re staring at a full recompile of every Apex class in the org, twiddling your thumbs for however long that takes this time. Winter ’27 lets you skip that and recompile only the invalid classes and triggers. It’s not a headline feature, but if you’ve sat through one of those full recompiles recently, you already know how good this is going to feel.
3. Apex Integration Tests Can Now Hit Real Endpoints (Developer Preview)
Mock callouts are fine, up to a point. They tell you your code handles a response shaped a certain way — they don’t tell you your code handles what the service is actually sending back today. And services change their response formats more often than anyone would like to admit.
Winter ’27’s new Apex Integration Tests framework lets you test against the real thing. Here’s roughly how it works:
- Turn on the
ApexIntegrationTests feature in your scratch org’s definition file.
- Add
@IntegrationTest to the test class and to each method you want to run this way.
- Use
@BeforeClass to set up shared data, and @TearDown to clean up after yourself.
That last part isn’t optional housekeeping; it’s the whole deal. Integration tests don’t get automatic rollback like normal Apex tests do, because you can’t roll back a real HTTP callout. So you’re on the hook for your own test data lifecycle. Annoying, sure, but a small price for actually knowing your code works against a live endpoint instead of a fictional one.
Two limits worth knowing before you get excited: only one integration test can run at a time, and it has to run asynchronously. No synchronous integration tests yet.
4. ApexGuru Starts Hunting Down Duplicate Code
Here’s a scenario every developer has lived through: someone needs a bit of logic, can’t find where it already lives (because org search is what it is), and just writes it again. Do that enough times across enough years and enough developers, and you end up with four slightly different versions of the same discount calculation scattered across the org, none of which get updated together when the business rule changes.
ApexGuru now flags duplicate and near-duplicate Apex code so this stops sneaking up on you. It also works inside agentic IDEs like Cursor, VS Code, and Agentforce Vibes, so you’re not relying on remembering to check a dashboard somewhere; it can just tell you while you’re writing.
Quick caveat: the release notes and the ApexGuru FAQ don’t fully agree on which editions get this included at no extra cost. I’d confirm with Salesforce directly for your org rather than assume either document is the final word.
5. The Apex Symbol API Gives AI Tools Something to Actually Ground Themselves In
Out of everything in this release, this is the one I think matters most long-term, even though it’s the least demo-friendly.
Here’s the problem it solves: AI coding tools working with Apex have never had a clean, reliable source for type information. Everyone’s been duct-taping together custom parsers, guessing at relationships between types, or working off metadata that’s incomplete at best. That’s a big reason AI-generated Apex has been so inconsistent — the tools were often working half-blind.
The Apex Symbol API (still in beta) fixes that. It’s a Tooling API REST resource that returns proper, compiler-grade detail on Apex types, and it pulls together what used to be scattered across the /completions endpoint and the SymbolTable object into one place one that stays current automatically as Apex evolves.
What that actually buys you: sharper code completion in your IDE, better grounding for AI agents writing Apex, and setup or support agents that can answer questions about your org’s code without making things up. If you’re evaluating any AI tooling for Salesforce work, this is worth understanding — it’s the difference between a tool that guesses and one that knows.
6. A Claude Code Plugin Built Specifically for Salesforce
General AI coding assistants are great right up until they hit something Salesforce-specific — and then they tend to guess with total confidence, which is somehow worse than just admitting they don’t know. Anyone who’s tried using an off-the-shelf assistant for Apex or LWC has probably watched it write syntactically perfect code that’s completely wrong for how the platform actually runs.
Winter ’27 ships a Salesforce Development plugin for Claude Code that recognises your Salesforce DX project and pulls in real org context through hosted MCP servers metadata, object structure, config, the stuff that actually matters. That context is what separates code that looks right from right code.
It’s also just handy for non-developers on your team. Someone doesn’t need to interrupt a developer to ask what a piece of automation does; they can get a decent answer themselves, which frees up developers for the problems that genuinely need a human.
The Smaller Stuff That Still Matters
7. FORMULA() Lets You Compare Fields Right Inside SOQL (Beta)
Small change, genuinely annoying workaround eliminated. Comparing two fields in a WHERE clause used to mean building a dedicated formula field just for the query, or pulling more records than you needed and filtering them in Apex afterwards.
Now you can just write it directly:
SELECT Id, Name FROM Opportunity WHERE FORMULA('Amount_To_Pay__c - Amount_Paid__c') > 0
One line, no extra field, no extra logic. It needs API version 68.0 or later; it’s beta only, and it’s not available in production yet — but it’s a clear signal of where SOQL is headed.
8. REST API URIs Can Just Say “latest” Now
This is the kind of fix that makes you go “finally” out loud at your desk. Instead of hardcoding a version number in your REST API endpoint, you can just use the word latest:
https://<MyDomainName>.my.salesforce.com/services/data/latest/sobjects/Account
…instead of the old way, where you’d have to keep this updated by hand:
https://<MyDomainName>.my.salesforce.com/services/data/v66.0/sobjects/Account
If you’re maintaining integrations that need a version bump three times a year just to stay current, that’s one less recurring chore. Though if your org has strict change control, you’ll want to think through whether “always latest” fits your process, or whether pinning a version is still the safer call for anything critical.
9. Namespace Collisions in Managed Package Queries Get Fixed
A quieter one, mostly relevant if you build managed packages. Dynamic SOQL in a managed package has always carried a small but real risk: if a subscriber org happens to have a custom field with the same API name as one in your package, the query can get confused about which field it’s actually pointing to.
Winter ’27 adds an explicitNamespace property on the Database.QueryOptions object, so you can pin a query to your package’s namespace and remove that ambiguity entirely. If you’re an ISV, this closes an edge case that’s been quietly fragile for a while.
10. Complex Template Expressions in LWC Are Officially GA
This one’s been in beta since Spring ’26, and it’s now generally available. What it actually gets you: fewer getters that exist purely to format a value or stitch together a CSS class string, and, the bigger win, honestly, no more workaround for loops.
You know the drill: a getter has no idea which item in a loop it’s being called for, so historically you’d pre-process your data in JavaScript and attach display values to each record before the template ever saw it. Now you can just bind the raw data and let the template handle the formatting itself.
Two things to remember: it needs component API version 66.0 or higher (set that in your .js-meta.xml), so you’re opting in per component rather than getting it org-wide automatically. And nothing about how it works has changed since beta; this release is just the “okay, it’s official now” stamp.
11. Third-Party Web Components Are Also GA in LWC
Also graduating out of beta: dropping third-party web components straight into an LWC template with lwc: external, no rewrite required.
Before this landed, your options were rough. An iframe, which broke styling more often than not. Loading something as a static resource and then becoming responsible for maintaining it forever. Or just biting the bullet and rebuilding the whole thing natively in LWC. None of those was fun. LWC is built on open web standards, so this was really just Salesforce flipping a switch that should’ve existed sooner — and now it does, unchanged from beta.