Skip to main content

Command Palette

Search for a command to run...

Asynchronous Apex: The 2AM Laundry Rule

Why Salesforce limits your code, how multi-tenancy works, and what happens when you go async — with an analogy that actually sticks.

Updated
3 min read
P
Software Developer trying to balance work and passion

If you've spent any time writing Apex, you've probably run into a wall — your logic is correct, your tests pass locally in your head, and then Salesforce throws a LimitException at you like you did something wrong.

You didn't. But understanding why it happens changes everything.


The Multi-Tenant Problem

Salesforce runs on a multi-tenant architecture. That's a fancy way of saying: your org, my org, and thousands of other orgs are all running on the same shared infrastructure. To make sure no one hogs all the resources and ruins it for everyone else, Salesforce enforces something called Governor Limits — hard caps on how many queries you can run, how much memory you can use, how long your code can execute, and more.

This is not a bug. It's the system working exactly as designed.


The Hostel Laundry Analogy

Here's the way it clicked for me.

Imagine you're living in a hostel. There's a shared laundry room, and during the day, there's always a line. The rules say each person only gets a fixed slot — you can't hog the machines while twenty other people are waiting. That's synchronous execution: you're in the queue, you get your allocated time, you're done.

Now imagine you wake up at 2 AM. Nobody's in line. No one's waiting after you. You could run two or three loads back to back — the daytime restriction existed because of the crowd, not because of the machine itself.

That 2 AM laundry run is Asynchronous Apex.

When you mark your code as asynchronous, Salesforce doesn't run it immediately. It queues it, waits for a low-load window, and then processes it — peacefully, in the background, with no one waiting behind you. And because the system knows you're not blocking anyone's critical path, it rewards you with higher limits.

"An asynchronous process is a process or function that executes a task in the background without the user having to wait for the task to finish." — Trailhead


The Limits, Side by Side

Here's where the difference becomes concrete. Look at what you gain by going async:

Description Synchronous Asynchronous
Total SOQL Queries 100 200
Future methods per invocation 50 0 (batch/future); 50 (queueable)
System.enqueueJob calls 50 1
Total Heap Size 6 MB 12 MB
Max CPU Time 10,000 ms 60,000 ms

Double the queries. Double the heap. Six times the CPU time. That's not a minor upgrade — that's the system giving you room to breathe because you agreed to be patient.


What's Coming in This Series

This is the first of many drafts I wrote while revisiting this topic

In the next parts, we'll get into the four tools Salesforce gives us to actually do async work:

  1. Future Methods — the quick, lightweight option

  2. Batch Apex — for when you need to process thousands of records

  3. Queueable Apex — the modern, chainable approach

  4. Scheduled Apex — run your code on a timer, like a cron job

If any of this is landing differently than how you learned it, drop it in the comments. That's the whole point of documenting in public.

Async Apex — From the Ground Up

Part 1 of 6

A series revisiting Asynchronous Apex from first principles. Covers the why behind Governor Limits, and walks through all four async tools — Future Methods, Batch Apex, Queueable Apex, and Scheduled Apex — with real examples, gotchas, and the things most tutorials skip. Written by a developer, for developers who want to actually understand what's happening under the hood.

Up next

Batch Apex: One Brick at a Time — Async Apex Part 2

How Salesforce lets you process thousands of records without blowing up your Governor Limits — and why it thinks exactly like a Lego instruction manual.