Skip to main content
New tool CRON Expression Builder — preview next run times before you schedule Apex. Open the builder →
A guide illustrating different Apex data types for efficient Salesforce programming and avoiding errors.
Apex

SFDC Data Types in Apex: Primitives, Collections & sObjects

Every SFDC data type developers need to know: Integer, Decimal, String, Boolean, Date, sObject, plus when to use Decimal vs Double and why Long is rarely the answer.

The short answer

Apex has primitive types, sObjects, and collections for storing, manipulating, and bulkifying data in Salesforce applications. Picking the right type for each value prevents rounding issues, heap limit errors, and unhandled runtime exceptions.

Key takeaways Use Decimal instead of Double for currency to keep exact precision and avoid rounding errors. Assign record IDs to the ID data type rather than String so you get built-in validation for 15- and 18-character IDs. Use sObject put() and get() methods to assign and retrieve field values when the field names are only known at runtime. Store queried records in Maps keyed by record ID so lookups stay fast without nested loops. Check whether a collection is empty before accessing an element by index to avoid runtime errors.

If you're building anything in Salesforce, you're going to spend a lot of time thinking about Apex data types. It's one of those foundational things that seems simple until you're staring at a heap limit error or a rounding issue with currency. I've seen plenty of projects where a simple mistake in choosing a data type caused massive headaches during testing.

Whether you're a dev or an admin getting into code, handling your data well is the difference between a clean deployment and a buggy mess.

The basics of Apex data types: primitives

Primitives are your building blocks. They hold a single value and they're what you'll use most often for basic logic. There are traps even here. A quick rundown of the ones you'll use every day:

  • Integer is for whole numbers like counters. It's a 32-bit number.
  • Long is 64-bit. Use it when you're dealing with very large numbers or timestamps.
  • Decimal is your best friend for money. It handles exact precision, which is vital for currency.
  • Double is a floating-point number. Honestly, I rarely use these unless I'm doing complex scientific math.
  • String holds text values. Strings in Apex are immutable, so if you're doing heavy text manipulation, look into the StringBuilder class.
  • Boolean is your standard true or false flag.
  • Date is just the day, while DateTime includes the time. Remember that Salesforce stores DateTime in GMT.
  • ID is the specific type for Salesforce record IDs. It handles both 15 and 18-character versions automatically.
  • Blob is for binary data, like file attachments or crypto keys.
// Quick primitive examples
Integer leadCount = 5;
Decimal totalAmount = 1500.50;
Id myAccountId = '001D00000123456789';
DateTime now = DateTime.now();

A split-screen visualization showing a code editor with data variables next to a realistic Salesforce record layout interface.

A split-screen visualization showing a code editor with data variables next to a realistic Salesforce record layout interface.

Working with sObjects and dynamic data

An sObject is a record in code form. It could be a standard object like an Account or a custom one you built yourself. When you work with these, you're interacting with the standard and custom tables in your database.

One thing that trips people up is the difference between static and dynamic access. You can hard-code a field like acc.Name, or you can use put() and get() if you don't know the field name until the code is actually running. Here's how that looks:

// Static access
Account acc = new Account(Name = 'Cloud Tech');
acc.Industry = 'Technology';

// Dynamic access
acc.put('Phone', '555-0123');
String phone = (String) acc.get('Phone');

Apex data types for bulkification: collections

If you're writing code instead of using Flow, you're likely doing it because you need more control or better performance. If you're still deciding which to use, check out this guide on Apex vs Flow. But if you're in the code, you need collections. Without them, your code won't scale.

Lists, sets, and maps

Lists are your go-to for ordered groups of data, and you'll use them for almost every SOQL query result. Sets are great when you need to make sure every value is unique. I use them all the time to collect IDs before running a query. Maps are the real power players: they store key-value pairs, which makes looking up data incredibly fast.

// A List for ordered records
List<Account> accList = [SELECT Id, Name FROM Account LIMIT 10];

// A Set for unique IDs
Set<Id> accountIds = new Set<Id>();

// A Map for fast lookups
Map<Id, Account> accMap = new Map<Id, Account>(accList);
Account specificAcc = accMap.get('001D00000123456');

Real-world best practices for Apex data types

I've seen teams run into serious production bugs because they didn't pick the right types early on. Apex is pretty forgiving, but it has limits, and once you're handling large datasets you have to be smart about memory and precision.

Always use Decimal for currency. Doubles will give you rounding headaches that are a nightmare to debug when the numbers don't add up in your financial reports.

  • Don't use Strings for everything. If it's an ID, use the ID type. It provides extra validation.
  • Watch your heap size. Blobs and large Lists can eat up your memory fast.
  • Null checks are your friend. Always check if a collection is empty before you try to access an index.
  • Use the right numeric type. Don't use a Long if an Integer will do the job.

Key takeaways

  • Primitives handle single values like text, numbers, and dates.
  • sObjects represent your Salesforce records and allow for both static and dynamic field access.
  • Collections (List, Set, Map) are essential for writing bulkified, scalable code.
  • Decimal is the only choice for currency to avoid rounding errors.
  • Maps are the most efficient way to link data together without using nested loops.

Choosing the right Apex data types is what makes code last. When you pick the correct type for the job, your code is easier to read, faster to run, and way less likely to break when the data volume grows. Stick to these basics, keep your collections organized, and you'll avoid the most common pitfalls I see in the field.

Frequently asked questions

What are the data types in SFDC Apex?

Apex supports five categories: (1) Primitives, which are Integer, Long, Double, Decimal, Boolean, Date, DateTime, Time, String, Id, Blob; (2) Collections, which are List, Set, Map; (3) sObjects such as Account, Contact, custom__c; (4) Enums, or user-defined named constants; (5) Classes, including built-ins like System.URL, System.Address, and Schema.* classes.

What is the difference between Decimal and Double in Apex?

Decimal is exact arbitrary-precision arithmetic, required for currency and any value where rounding matters (financial calculations, totals, percentages). Double is IEEE 754 floating-point: faster, but susceptible to precision loss (0.1 + 0.2 != 0.3). Always use Decimal for money in Apex, even though Double feels more familiar from other languages.

Which Apex data type should I use for currency fields?

Decimal, always. Salesforce currency fields surface in Apex as Decimal because they need exact arithmetic. Use the .setScale() method to control decimal places (e.g., amount.setScale(2, RoundingMode.HALF_UP) for cents). Never store currency in Double or Integer, because you lose precision in the first multiplication.

What is the maximum size of a String in Apex?

6,000,000 characters per Apex String, but in practice you hit the heap size governor limit (6 MB synchronous, 12 MB async) long before reaching that. For larger payloads, use Blob for binary data or stream chunks via the platform's REST callouts. Trying to JSON.serialize a 5 MB String often crashes with LIMIT_USAGE_FOR_NS errors.

What is the difference between Id and String in Apex?

Id is a strict 15- or 18-character Salesforce record identifier with built-in validation, so assigning a malformed string to an Id throws a runtime error. String is generic text. Use Id when you know a value is a record reference and you want the type system to catch typos at compile time. Apex auto-converts between 15- and 18-char IDs when you compare them.

When should I use Long vs Integer in Apex?

Almost never use Long. Apex Integer is 32-bit signed (range ±2.1 billion). Long is 64-bit (range ±9.2 quintillion). Use Long only when you genuinely need values larger than 2 billion, such as record counts or timestamps in milliseconds. For everything else, Integer is faster, smaller, and the convention in Salesforce code.

Are Apex collections (List, Set, Map) data types?

Yes, and they are typed: List<Account>, Set<Id>, Map<Id, Account>. List preserves insertion order and allows duplicates. Set removes duplicates and is unordered. Map is key-value storage with O(1) lookup. Most bulk-safe Apex revolves around building Maps in advance and avoiding queries inside loops.

Newsletter

One email every Tuesday

New guides, tool updates, and the release-note changes that break things.

No spam. Unsubscribe in one click.

Comments

Loading comments...

Leave a Comment