Salesforce Winter '27 (API version 68.0) changes core runtime constraints that have shaped enterprise architecture for over a decade. The release raises heap memory thresholds, adds native live integration testing, and introduces explicit namespace resolution for dynamic queries.
Adopting these features takes clear operational boundaries: how the memory increases interact with governor ceilings that did not move, how unmocked test suites affect automated pipelines, and why unversioned API aliases are a risk for enterprise integrations, as covered in Salesforce Ben's release write-up.
Managing memory ceilings and query guardrails
Winter '27 increases the synchronous Apex heap limit from 6 MB to 10 MB and the asynchronous heap limit from 12 MB to 25 MB. The higher ceiling removes memory failures when parsing large JSON responses from external systems or building complex in-memory document structures.
public with sharing class DocumentPayloadProcessor {
public static void parseAndStage(Id outboundPayloadId) {
ContentVersion fileData = [SELECT VersionData FROM ContentVersion WHERE Id = :outboundPayloadId LIMIT 1];
// Inspect available execution capacity at runtime
Integer currentLimit = Limits.getLimitHeapSize();
System.debug(LoggingLevel.INFO, 'Active Heap Ceiling (bytes): ' + currentLimit);
// Large JSON payload transformations now have headroom up to 10 MB synchronously
Map<String, Object> parsedStructure = (Map<String, Object>) JSON.deserializeUntyped(fileData.VersionData.toString());
processPayloadNodes(parsedStructure);
}
private static void processPayloadNodes(Map<String, Object> nodes) {
// Transform and persist records
}
}
I have seen this memory increase tempt teams into pulling entire object histories into memory instead of writing selective queries, which crashes transactions against the 50,000 query row limit. The heap expanded; record limits and CPU time limits did not. The table below compares runtime boundaries across execution contexts.
| Runtime Metric | Legacy Sync Limit | Winter '27 Sync (v68.0) | Legacy Async Limit | Winter '27 Async (v68.0) |
|---|---|---|---|---|
| Max Heap Allocation | 6 MB | 10 MB | 12 MB | 25 MB |
| Max SOQL Query Rows | 50,000 | 50,000 | 50,000 | 50,000 |
| Max CPU Execution Time | 10,000 ms | 10,000 ms | 60,000 ms | 60,000 ms |
| SOQL Query Timeout | 120 seconds | 120 seconds | 120 seconds | 120 seconds |
Isolating scratch-only live integration tests
Winter '27 adds native integration testing under Developer Preview through the @IntegrationTest annotation. Standard test executions isolate transactions with HttpCalloutMock and then roll back. An @IntegrationTest class makes live network calls to external endpoints and commits database changes across steps.
To enable this in your project configuration, add the feature flag to project-scratch-def.json:
{
"orgName": "Integration-Testing-Scratch",
"edition": "Developer",
"features": ["ApexIntegrationTests"],
"settings": {
"lightningExperienceSettings": {
"enableS1DesktopEnabled": true
}
}
}
Because automated database rollbacks are disabled during live integration tests, you must explicitly manage data setup and teardown phases using @BeforeClass and @TearDown.
@IntegrationTest
public with sharing class PaymentGatewayIntegrationTest {
private static String stagingExternalRefId;
@BeforeClass
public static void setupSharedState() {
Payment_Audit__c audit = new Payment_Audit__c(
Status__c = 'Pending',
Idempotency_Key__c = 'TEST-KEY-' + Datetime.now().getTime()
);
insert audit;
stagingExternalRefId = audit.Idempotency_Key__c;
IntegrationTest.commitTestOnly();
}
@IntegrationTest
public static void verifyLiveChargeSettlement() {
PaymentClient client = new PaymentClient();
// Makes a live outbound HTTP callout to the target endpoint
HttpResponse res = client.executePayment(stagingExternalRefId, 500.00);
System.assertEquals(200, res.getStatusCode(), 'Expected live gateway acknowledgment');
}
@TearDown
public static void cleanPersistentState() {
List<Payment_Audit__c> staleRecords = [
SELECT Id FROM Payment_Audit__c WHERE Idempotency_Key__c = :stagingExternalRefId
];
if (!staleRecords.isEmpty()) {
delete staleRecords;
IntegrationTest.commitTestOnly();
}
}
}
These tests run only through asynchronous execution (runTestsAsynchronous), cannot execute in sandboxes or production orgs, and generate no coverage toward the 75% deployment requirement. CI/CD automation has to split pipeline runs into distinct stages:
- Run standard
@IsTestsuites on pull requests using mocked boundaries for fast feedback and package coverage verification. - Spin up dedicated scratch orgs with
ApexIntegrationTestsenabled in a nightly or staging pipeline. - Execute
@IntegrationTestsuites sequentially withsf apex run testto verify live third-party contracts, so that only one test runs per org at a time.
Resolving dynamic SOQL namespace collisions
For managed package authors (ISVs), a subscriber org that defines a custom field sharing an API name with a packaged field can alter dynamic SOQL query behavior. Winter '27 resolves the ambiguity with an explicit namespace parameter, available through Database.QueryOptions and the SET OPTIONS clause.
public with sharing class PackageDataSelector {
public static List<SObject> queryRecordsWithNamespaceIsolation(Id parentRecordId, String packageNamespace) {
// Prevent subscriber-defined fields from shadowing packaged fields
String queryString =
'SELECT Id, Billing_Status__c ' +
'FROM Invoice__c ' +
'WHERE Account__c = :parentRecordId ' +
'SET OPTIONS explicitNamespace = :packageNamespace';
return Database.query(queryString);
}
}
When dynamic queries evaluate field tokens at runtime, passing explicitNamespace binds the query engine directly to the package schema and ignores subscriber custom fields that share the same suffix.
Modernising the front-end tier with LWC
Lightning Web Components in API version 68.0 promote complex template expressions and the lwc:external directive to General Availability (GA). Complex template expressions allow inline data formatting and conditions inside template markup, without boilerplate getters in the JavaScript class.
<!-- accountBalanceCard.html -->
<template>
<lightning-card title="Billing Summary">
<div class="slds-p-around_medium">
<p>Outstanding: {account.totalBalance - account.creditedAmount}</p>
<p class={account.isDelinquent && account.riskScore > 75 ? 'slds-text-color_error' : 'slds-text-color_default'}>
Status: {account.isDelinquent ? 'Action Required' : 'Current'}
</p>
</div>
</lightning-card>
</template>
The lwc:external directive enables standard custom elements inside LWC templates without wrapping them in an iframe or loading them through static resources.
<!-- chartingContainer.html -->
<template>
<div class="chart-wrapper">
<third-party-gauge-chart
lwc:external
max-value="100"
current-value={metricScore}>
</third-party-gauge-chart>
</div>
</template>
This directive requires Lightning Web Security (LWS) to be active. In orgs still running legacy Lightning Locker, external custom elements fail to mount correctly.
API governance and recompilation
Winter '27 introduces an unversioned URI parameter (/services/data/latest/) for REST API calls, documented in the Salesforce release schedule notes. An unversioned endpoint simplifies development in test environments, but avoid /latest/ in production middleware such as MuleSoft, Boomi, or event-driven integrations.
Unpinned endpoints expose integrations to silent schema breaking changes, stricter type enforcement, or altered standard endpoint behaviors during tri-annual major release upgrades. Production integration patterns should always use explicit, pinned versions such as /services/data/v68.0/, updated through structured regression testing.
For developer tooling and IDE support, the Apex Symbol API enters Beta as a Tooling API REST resource. It exposes compiler-resolved metadata for types, methods, and signatures, which gives internal developer tooling and schema linters accurate context.
The platform also supports recompiling only invalid Apex classes and triggers. That cuts build and deployment validation times in large orgs, because updating individual classes no longer forces a full-codebase recompilation.
What to watch for
- Live test data residue. Exceptions thrown inside
@IntegrationTestmethods before the@TearDownmethod runs leave dirty records in your scratch org. Design cleanup steps defensively so they handle partial test executions. - CI concurrency bottlenecks. Scratch orgs allow only one concurrent
@IntegrationTestexecution at a time. CI runners that try to execute parallel suites against a single scratch org fail with concurrency errors. - LWS dependencies for external components. Verify that Lightning Web Security is enabled in setup before deploying templates that contain the
lwc:externaldirective. - Inline logic sprawl. Complex expressions in LWC templates should handle display formatting only. Keep business rules, validations, and state mutations inside the JavaScript class.
- Dynamic SOQL upgrades. Review package codebases that use dynamic SOQL and add
explicitNamespacewherever subscriber-defined schema could shadow packaged fields.
Leave a Comment