Skip to content

Platform Capabilities & Constraints

The Salesforce platform is a shared multi-tenant environment. Every architectural decision must account for governor limits, shared resource constraints, and the boundaries between what the platform can and cannot do. The CTA who understands these constraints builds solutions that scale; the one who ignores them builds solutions that break.

Multi-Tenant Architecture

Salesforce runs on a shared infrastructure model where all customers (tenants) share the same compute, storage, and network resources. Governor limits exist to prevent any single tenant from monopolizing shared resources.

flowchart TD
    subgraph Tenants["Customer Orgs (Tenants)"]
        T1["Tenant A<br/>(OrgID: 00D1)"]
        T2["Tenant B<br/>(OrgID: 00D2)"]
        T3["Tenant C<br/>(OrgID: 00D3)"]
    end

    subgraph Kernel["Multitenant Kernel (Application Runtime)"]
        MDE["Metadata Engine<br/>Reads UDD at runtime"]
        QO["Query Optimizer<br/>Adds OrgID to every query"]
        GOV["Governor Limit<br/>Enforcement"]
        CACHE["Metadata Cache<br/>Per-org optimization"]
    end

    subgraph Data["Shared Database Layer"]
        UDD["Universal Data Dictionary<br/>(metadata tables)"]
        DT["Data Tables<br/>(all tenants, OrgID-partitioned)"]
        IDX["Custom Indexes<br/>(per-tenant)"]
    end

    subgraph Infra["Infrastructure (Hyperforce)"]
        AZ1["Availability Zone 1"]
        AZ2["Availability Zone 2"]
    end

    T1 --> MDE
    T2 --> MDE
    T3 --> MDE

    MDE --> QO
    QO --> GOV
    GOV --> CACHE

    CACHE --> UDD
    CACHE --> DT
    DT --> IDX

    Data --> AZ1
    Data --> AZ2

    style Tenants fill:#264653,color:#fff
    style Kernel fill:#2d6a4f,color:#fff
    style Data fill:#457b9d,color:#fff
    style Infra fill:#e9c46a,color:#000

The kernel reads tenant-specific metadata from the Universal Data Dictionary (UDD) at runtime to dynamically construct each tenant’s application, business logic, and APIs. Every database query is automatically scoped by OrgID, ensuring strict tenant isolation at the data layer. Custom objects, fields, triggers, and validation rules are all stored as metadata — not compiled code — which is why Salesforce can deploy platform upgrades without affecting tenant customizations.

Multi-Tenancy Implications

AspectImplication for Architects
Shared databaseCannot run arbitrary SQL; must use SOQL/SOSL within limits
Shared computeCPU time limits per transaction; no long-running processes
Shared networkAPI call limits per 24-hour period; callout time limits
No raw file systemCannot write to disk; must use ContentDocument or external storage
No custom OS processesCannot run background daemons; must use platform async frameworks
Metadata-drivenCustom objects, fields, and configuration stored as metadata; schema changes are API calls
Automatic upgradesThree releases per year; cannot defer; must test in advance

The architect’s mindset

Multi-tenancy is not a limitation to work around — it is the foundation that provides automatic scaling, zero-downtime upgrades, and enterprise security at commodity pricing. The CTA should embrace it and only go off-platform when the platform genuinely cannot serve the requirement.

Governor Limits Reference

Per-Transaction Limits (Synchronous)

ResourceLimitNotes
SOQL queries100Per Apex transaction
Records retrieved (SOQL)50,000Per transaction
SOSL searches20Per transaction
Records retrieved (SOSL)2,000Per transaction
DML statements150Per transaction
Records processed (DML)10,000Per transaction
Callouts100Per transaction
Callout timeout120 seconds (total)Max 120s per callout; 120s total
CPU time10,000 msPer transaction
Heap size6 MBPer synchronous transaction
Future calls50Per transaction
Queueable jobs50Per transaction
Email invocations10Per transaction
Push notification calls10Per transaction
EventBus.publish150Per transaction

Per-Transaction Limits (Asynchronous)

ResourceLimitNotes
SOQL queries200Double the synchronous limit
Records retrieved (SOQL)50,000Same as synchronous
CPU time60,000 ms6x the synchronous limit
Heap size12 MBDouble the synchronous limit

Per-24-Hour Limits

ResourceLimitNotes
API calls100,000+Base + per-user allocation (varies by edition)
Async Apex executions250,000 or 200 x licensesWhichever is greater
Batch Apex jobs100 queued or activeAt any one time
Future calls250,000 or 200 x licensesWhichever is greater
Platform Events publishedBased on entitlementVaries; default 100K/day for most editions
Outbound emails5,000 external recipients/day (single + mass combined)Per-blast limit: 500 (EE), 1,000 (UE/PE). Daily cap shared across single and mass email
Scheduled Apex jobs100Concurrent scheduled jobs

Data and Storage Limits

ResourceLimitNotes
Custom objects200-2,000Varies by edition
Custom fields per objectUp to 500Varies by edition and field type — consult ‘Custom Fields Allowed Per Object’ help article for precise limits
Data storage10 GB base + per-userSee [[01-system-architecture/org-strategy
File storage10 GB base + per-userSee [[01-system-architecture/document-management
Record size~8 KB per recordAggregate of all field values
SOQL query length100,000 charactersIncluding WHERE, ORDER BY
Formula field size5,000 characters compiledComplex formulas may exceed this

Synchronous vs Asynchronous Limits — Visual Comparison

flowchart LR
    subgraph SYNC["Synchronous Context"]
        direction TB
        S1["SOQL Queries: 100"]
        S2["CPU Time: 10,000 ms"]
        S3["Heap Size: 6 MB"]
        S4["DML Statements: 150"]
        S5["Callouts: 100"]
    end

    subgraph ASYNC["Asynchronous Context"]
        direction TB
        A1["SOQL Queries: 200 (2x)"]
        A2["CPU Time: 60,000 ms (6x)"]
        A3["Heap Size: 12 MB (2x)"]
        A4["DML Statements: 150 (same)"]
        A5["Callouts: 100 (same)"]
    end

    SYNC -->|"Exceeds limits?"| DEC{"Move to async?"}
    DEC -->|"Yes"| ASYNC
    DEC -->|"Still exceeds"| OFF["Off-Platform<br/>Processing"]

    style SYNC fill:#9d0208,color:#fff
    style ASYNC fill:#2d6a4f,color:#fff
    style OFF fill:#e9c46a,color:#000

The async escalation path

When a synchronous transaction hits governor limits, the first response should be to evaluate async processing. Async gives 2x SOQL, 6x CPU time, and 2x heap. If async limits are still insufficient, that is the signal to move off-platform. This escalation path — sync, then async, then off-platform — is a pattern CTA judges expect to see.

Limits you will hit

The limits CTAs most frequently encounter in real-world scenarios: (1) 100 SOQL per synchronous transaction — poor code design or AppExchange packages that query in loops, (2) 10,000 DML records — bulk data operations, (3) API calls per 24 hours — integration-heavy architectures, (4) CPU time — complex Flow automation chains.

On-Platform vs Off-Platform Decision Framework

The most fundamental system architecture question: should this capability run on the Salesforce platform or somewhere else?

Decision Matrix

FactorOn-PlatformOff-Platform
Data ownershipData is primarily Salesforce dataData lives in external systems
User contextUsers are already in SalesforceUsers are not Salesforce users
Transaction complexityWithin governor limitsExceeds governor limits
Processing timeUnder 10 seconds (sync) or 60 seconds (async)Long-running processes (minutes to hours)
Custom UILightning components are sufficientComplex UI beyond Lightning capabilities
Device integrationStandard browser/mobileIoT, sensors, specialized hardware
Compute requirementsLight computationHeavy computation, ML model training
Real-time streamingPlatform Events (limited)Kafka, Kinesis, or custom streaming
Data volumeUnder LDV thresholdsBillions of records, data lake/warehouse
RegulatoryStandard complianceSpecialized compliance (PCI DSS, HIPAA BAA)

On-Platform vs Off-Platform Architecture

flowchart TD
    subgraph ONP["On-Platform (Salesforce)"]
        direction TB
        DEC["Declarative<br/>Flows, Validation Rules,<br/>Formulas, Page Layouts"]
        CODE["Custom Code<br/>Apex, LWC, SOQL,<br/>Visualforce"]
        ASYNC2["Async Processing<br/>Batch, Queueable,<br/>Future, Scheduled"]
        PE["Event-Driven<br/>Platform Events, CDC,<br/>Outbound Messages"]
    end

    subgraph OFFP["Off-Platform"]
        direction TB
        MULE["MuleSoft / Integration<br/>Complex orchestration,<br/>API management"]
        HEROKU["Heroku / Functions<br/>Custom compute,<br/>worker processes"]
        CLOUD["AWS / GCP / Azure<br/>Heavy compute, ML,<br/>data pipelines"]
        CUSTOM["Custom Web App<br/>Complex UI,<br/>non-SF users"]
    end

    SF["Salesforce Platform"] --> ONP
    SF <-->|"APIs"| OFFP

    style ONP fill:#2d6a4f,color:#fff
    style OFFP fill:#457b9d,color:#fff
    style SF fill:#264653,color:#fff

Decision Flowchart

flowchart TD
    A[New Capability] --> B{Does it primarily<br/>serve Salesforce users?}

    B -->|Yes| C{Within governor<br/>limits?}
    B -->|No| D[Off-Platform<br/>Consider integration back]

    C -->|Yes| E{Standard platform<br/>features sufficient?}
    C -->|No| F{Can async processing<br/>solve the constraint?}

    E -->|Yes| G[On-Platform<br/>Declarative]
    E -->|No| H{Can Apex/LWC<br/>solve it?}

    F -->|Yes| I[On-Platform<br/>Async Apex]
    F -->|No| D

    H -->|Yes| J[On-Platform<br/>Custom Code]
    H -->|No| K{Is it a UI<br/>requirement?}

    K -->|Yes, complex UI| L[Off-Platform UI +<br/>Salesforce API]
    K -->|No, processing| D

    style G fill:#2d6a4f,color:#fff
    style I fill:#2d6a4f,color:#fff
    style J fill:#457b9d,color:#fff
    style D fill:#9d0208,color:#fff
    style L fill:#9d0208,color:#fff

Asynchronous Apex Patterns

When synchronous processing hits governor limits, async patterns provide higher limits and background processing.

Async Pattern Comparison

PatternMax Execution TimeUse CaseChainingCalloutsState
Future Methods60 secondsSimple fire-and-forgetNoYes (100)No (primitives only)
Queueable Apex60 secondsComplex async with stateYes (default depth 5, configurable via AsyncOptions and MaximumQueueableStackDepth — Spring ‘25+)Yes (100)Yes (serializable)
Batch Apex60 seconds per batchLarge data processingYes (via finish)Yes (per execute)Limited (Database.Stateful)
Schedulable ApexN/A (calls other async)Time-based schedulingVia Queueable/BatchVia called methodN/A

When to Use Each Pattern

flowchart TD
    A[Need Async Processing] --> B{Data volume?}

    B -->|Small: single record<br/>or small batch| C{Need state<br/>or chaining?}
    B -->|Large: thousands<br/>to millions| D[Batch Apex]

    C -->|No, simple fire-and-forget| E[Future Method]
    C -->|Yes, need to track<br/>progress or chain| F[Queueable Apex]

    D --> G{Need scheduled<br/>execution?}
    F --> G

    G -->|Yes| H[Schedulable Apex<br/>to invoke Batch/Queueable]
    G -->|No| I[Execute directly]

    style E fill:#2d6a4f,color:#fff
    style F fill:#457b9d,color:#fff
    style D fill:#9d0208,color:#fff
    style H fill:#e9c46a,color:#000

Batch Apex Design Considerations

ConsiderationRecommendation
Scope sizeStart with 200; adjust based on processing complexity
Error handlingImplement Database.Stateful to track errors across batches
Retry logicBuild retry capability for failed batches
MonitoringUse AsyncApexJob for status; consider custom monitoring object
TestingTest with 200+ records; test start, execute, finish independently
ChainingChain to follow-up batch in finish method for multi-step processing
Governor limitsEach execute invocation gets its own governor limit context

Queueable over Future

Queueable Apex is the modern replacement for Future methods. It supports passing complex objects (not just primitives), chaining, and monitoring through AsyncApexJob. Default to Queueable unless you have a specific reason to use Future (such as calling from a trigger where simplicity is preferred).

Platform Events and Change Data Capture

Platform Events

Platform Events are a pub/sub messaging system built into the Salesforce platform, based on Apache Kafka under the hood.

FeatureDetail
PublishApex, Flow, API, Process Builder
SubscribeApex triggers, Flow, Lightning components, external systems (CometD/gRPC)
DeliveryAt-least-once (high-volume) or at-most-once
Retention72 hours (standard), configurable with add-on
VolumeBased on entitlement (typically 100K+/day)
ReplayReplayId for event replay from a point in time
Transaction boundaryPublished events are committed independently of the DML transaction

Change Data Capture (CDC)

CDC publishes events when Salesforce records are created, updated, deleted, or undeleted.

FeatureDetail
Events generatedCreate, Update, Delete, Undelete
ConfigurationSelect objects to track in Setup
PayloadChanged fields only (delta), with header metadata
SubscriptionSame as Platform Events (CometD, Apex triggers, gRPC)
Use caseNear-real-time data synchronization to external systems
Gap eventsPublished when events are missed (e.g., during maintenance)

When to Use Platform Events vs CDC

ScenarioPlatform EventsCDC
Custom business eventsYesNo (CDC is record-change only)
Record change notificationsCan build manuallyAutomatic
Integration data syncManual event designAutomatic field-level changes
Audit trailCustom designAutomatic change tracking
Custom event payloadsFull controlSalesforce-defined schema

Big Objects

Big Objects are designed for storing and accessing massive datasets (billions of records) on the Salesforce platform without consuming standard data storage.

Big Object Characteristics

FeatureDetail
StorageSeparate from standard data storage
Record capacityBillions of records
QueryStandard SOQL on indexed fields (Async SOQL retired as of Summer ‘25); limited filtering (composite key only)
DMLinsertImmediate (async bulk insert)
RelationshipsLookup to standard/custom objects
ReportingNot available in standard reports
AutomationCannot trigger workflows, flows, or Apex triggers
Use casesAudit logs, historical data, IoT telemetry, transactional archives

Big Object limitations

Big Objects are not a drop-in replacement for standard objects. You cannot use them in standard reports, dashboards, list views, or most declarative tools. They require SOQL queries on the composite key, which means you must know what you are querying for — they do not support ad-hoc querying. Design the composite key carefully based on access patterns.

When Big Objects Make Sense

  • Archiving historical records (old cases, audit logs, transaction history)
  • Storing IoT or telemetry data that arrives at high volume
  • Compliance data that must be retained for years but rarely queried
  • Pre-computed analytics data for dashboards

Custom Metadata Types vs Custom Settings

Both store configuration data, but they serve different purposes and have different deployment characteristics.

FeatureCustom Metadata TypesCustom Settings (Hierarchy)Custom Settings (List)
DeployableYes (metadata API, change sets)No (data, must be loaded per env)No (data, must be loaded per env)
PackageableYesNoNo
SOQL queriesNo (uses getInstance, no SOQL limit)No (uses getInstance, no SOQL limit)No (uses getInstance, no SOQL limit)
Apex test visibilityAvailable without SeeAllDataRequires SeeAllData or setup in testRequires SeeAllData or setup in test
Per-user/profile valuesNoYes (hierarchy)No
VolumeLow (configuration)Low (configuration)Low-Medium
Use caseApp configuration, mapping tables, feature flagsPer-user/profile settings, feature togglesLookup/reference data

Default to Custom Metadata Types

For CTA exam scenarios, Custom Metadata Types should be your default recommendation for configuration data. The key advantage is deployability — they move through change sets, sandboxes, and packaging like metadata, not data. Custom Settings require manual data loading in each environment, which is error-prone and breaks CI/CD.

Platform Feature Matrix

A quick reference for which platform capabilities are available for common architectural patterns.

CapabilityDeclarativeApexAPIExternal
Record CRUDFlows, Process BuilderFull CRUDREST/SOAPVia API
Complex logicFlow decisionsFull programmingN/AFull programming
Scheduled executionScheduled FlowsSchedulable ApexN/ACron jobs
Bulk processingBulk Data LoadBatch ApexBulk APIETL tools
External calloutsFlow HTTP calloutApex HTTPN/ADirect
Email sendingEmail AlertsApex MessagingAPIExternal email service
File processingLimitedContentVersion ApexContent APIExternal processing
PDF generationLimitedVisualforce renderAsN/AExternal service
Complex calculationsFormulas (limited)Apex MathN/AExternal compute
ML / AIEinstein (managed)Einstein APIEinstein APICustom ML

Sources