Scalable Architecture & System Design
📖 Concept
Designing scalable Salesforce solutions is an architect-level competency. This involves data modeling for growth, multi-org strategies, event-driven architecture, and performance at scale.
Architecture decision areas:
Single-Org vs Multi-Org
- Single: Simpler, shared data, one governance structure
- Multi: Data isolation, different compliance needs, M&A
- Hybrid: Salesforce Connect to bridge orgs
Event-Driven Architecture (EDA)
- Decouple components via events
- Platform Events for Salesforce-to-Salesforce
- CDC for external system sync
- Benefits: loose coupling, independent scaling, resilience
Microservices with Salesforce
- Salesforce Functions (compute)
- External services via Named Credentials
- MuleSoft as API gateway
- Heroku for custom compute
Data Architecture at Scale
- Skinny tables for wide objects
- Big Objects for archival
- External Objects for federated queries
- Custom indexes for query performance
Multi-Tenant Design Considerations
- All design must work within governor limits
- Sharing model impacts performance at scale
- Metadata-driven customization over code
- Configuration over customization principle
Architecture review framework:
1. Business requirements → Data volume estimates
2. Security & compliance → OWD, encryption needs
3. Integration landscape → Number of systems, data flow
4. Performance targets → Response times, throughput
5. Scalability plan → Growth projections, limit analysis
💻 Code Example
1// Scalable Architecture Patterns23// 1. Configuration-Driven Architecture4// Use Custom Metadata Types instead of hard-coded values5public class ConfigurableProcessor {67 public static void processRecords(List<SObject> records, String processType) {8 // Read configuration from Custom Metadata9 List<Process_Config__mdt> configs = [10 SELECT Handler_Class__c, Is_Active__c, Execution_Order__c11 FROM Process_Config__mdt12 WHERE Process_Type__c = :processType13 AND Is_Active__c = true14 ORDER BY Execution_Order__c ASC15 ];1617 for (Process_Config__mdt config : configs) {18 // Dynamic handler instantiation19 Type handlerType = Type.forName(config.Handler_Class__c);20 if (handlerType != null) {21 IProcessor handler = (IProcessor) handlerType.newInstance();22 handler.process(records);23 }24 }25 }2627 public interface IProcessor {28 void process(List<SObject> records);29 }30}3132// 2. Feature Flags using Custom Metadata33public class FeatureFlags {3435 private static Map<String, Feature_Flag__mdt> flags;3637 static {38 flags = new Map<String, Feature_Flag__mdt>();39 for (Feature_Flag__mdt flag : [40 SELECT DeveloperName, Is_Enabled__c, Rollout_Percentage__c41 FROM Feature_Flag__mdt42 ]) {43 flags.put(flag.DeveloperName, flag);44 }45 }4647 public static Boolean isEnabled(String featureName) {48 Feature_Flag__mdt flag = flags.get(featureName);49 if (flag == null) return false;5051 if (flag.Rollout_Percentage__c != null && flag.Rollout_Percentage__c < 100) {52 // Percentage-based rollout53 Integer hash = Math.abs(UserInfo.getUserId().hashCode());54 return Math.mod(hash, 100) < flag.Rollout_Percentage__c;55 }5657 return flag.Is_Enabled__c;58 }59}6061// Usage in code:62// if (FeatureFlags.isEnabled('New_Pricing_Engine')) {63// NewPricingEngine.calculate(opp);64// } else {65// LegacyPricing.calculate(opp);66// }6768// 3. Multi-Org Data Architecture69public class CrossOrgDataService {7071 // Using Salesforce Connect / External Objects72 // External_Account__x maps to Account in another org7374 public static List<External_Account__x> getExternalAccounts(String industry) {75 return [76 SELECT ExternalId, Name__c, Industry__c, Revenue__c77 FROM External_Account__x78 WHERE Industry__c = :industry79 LIMIT 10080 ];81 }8283 // Org-to-Org sync via Named Credentials84 @future(callout=true)85 public static void syncToSecondaryOrg(Set<Id> accountIds) {86 List<Account> accounts = [87 SELECT Id, Name, Industry, AnnualRevenue88 FROM Account WHERE Id IN :accountIds89 ];9091 HttpRequest req = new HttpRequest();92 req.setEndpoint('callout:Secondary_Org/services/apexrest/api/accounts');93 req.setMethod('POST');94 req.setHeader('Content-Type', 'application/json');95 req.setBody(JSON.serialize(accounts));9697 HttpResponse res = new Http().send(req);98 if (res.getStatusCode() != 200) {99 System.debug('Sync failed: ' + res.getBody());100 }101 }102}
🏋️ Practice Exercise
Architecture Practice:
- Design a data model for a multi-business-unit org (separate products, shared customers)
- Implement Feature Flags using Custom Metadata Types with percentage-based rollout
- Create a configuration-driven processor that dynamically loads handlers
- Design a multi-org architecture for a company with US and EU data residency requirements
- Build an event-driven architecture connecting 3 Salesforce components via Platform Events
- Design a Large Data Volume strategy for an org projected to reach 10M records in 2 years
- Create an architecture decision document comparing single-org vs multi-org for a merger
- Implement a canary release strategy for Apex code changes
- Design a disaster recovery plan for a mission-critical Salesforce implementation
- Build a technical debt tracking system using Custom Metadata
⚠️ Common Mistakes
Defaulting to multi-org when single-org would work — multi-org adds complexity for data sharing and integration. Start with single-org unless there's a specific reason (compliance, isolation)
Not considering governor limits in architecture decisions — every architectural component shares the same transaction limits when triggered synchronously
Over-customizing when configuration works — Custom Metadata Types, Flow, and declarative tools are often more maintainable than Apex
Not planning for scale from the start — retroactively fixing performance for LDV is much harder than designing for it
Ignoring the 3 releases per year — Salesforce pushes updates 3 times/year. Your architecture must survive automatic platform upgrades
💼 Interview Questions
🎤 Mock Interview
Mock interview is powered by AI for Scalable Architecture & System Design. Login to unlock this feature.