Skip to main content

Salesforce File Handling: Architecture and Pitfalls

About Us
Published by yuliya.dzemidchuk
26 February 2026

File Handling in Salesforce: Real-World Architecture and Pitfalls

 

The Problem Nobody Talks About

Pick any Salesforce file handling tutorial and you'll find sanitized examples: upload a file, store it in ContentVersion, retrieve it with SOQL. Perfect for demos, useless for production. The moment you need images for a public website, process PDFs with complex layouts, or handle API file size limits, you discover that Salesforce file storage is a minefield of architectural decisions that can make or break your application.

“I've built systems handling everything from CV parsing to auction site galleries. Every approach has brutal trade-offs that documentation conveniently omits. This article covers what actually works, what fails spectacularly, and the architectural decisions you need to make before writing code.”

 

ContentVersion vs Attachment: The Decision That Matters

The Real Differences:

Query Performance: ContentVersion requires three-object joins (ContentVersion → ContentDocument → ContentDocumentLink). Attachment is straightforward parent-child. In loops processing 200 records, ContentVersion hits SOQL limits. Attachment doesn't.

File Sharing: ContentVersion works in Experience Cloud with granular permissions. Attachment access control is primitive - see parent record or nothing.

API Limits: Both support 2GB via UI, but API uploads typically face smaller limits - generally around 38MB for ContentVersion and 25MB for Attachment, though this varies by upload method (REST, SOAP, multipart). Base64 encoding adds 33% overhead, further reducing practical limits.

Version Control: ContentVersion tracks versions natively. Attachment is single-version only.

Use ContentVersion when: file sharing across records, version history, Experience Cloud access. The use of  Attachment is considered a deprecated practice and should be avoided unless there are strict system restrictions.

 

Image Loading: URL vs Base64

Architecture 1: Image URLs
How it works: Store in ContentVersion, generate URLs, browser loads from Salesforce CDN.

✓ Clean separation, browser caching, CDN delivery
✗ Authentication nightmares, URL expiration, CORS issues, no image optimization control, expensive three-object queries

Architecture 2: Base64 Data
How it works: Store binary as a base64 string in the Long Text Area field (max 131,072 characters), render as data:image URLs.

✓ Single object queries, no auth issues, works everywhere, immediate delete, version control
✗ Size limit (~98KB after encoding), SOQL character limits, heap consumption, 33% storage overhead, no CDN, slower browser parsing

Real Implementation:
An auction platform was implemented using both approaches simultaneously, controlled by Custom Metadata (Images_Loading_Type__c). Story thumbnails (<50KB) used Base64 for instant loading. Full-size images (200KB-2MB) used ContentVersion URLs with CDN caching. User profiles used Base64. PDF receipts used ContentVersion for version history.

 

The Heap Limit Nightmare

The 6MB Wall
Apex heap limit: 6MB sync, 12MB async. Base64 encoding adds 33% overhead, and you need memory for BOTH original Blob AND encoded String. Practical limit: ~4MB files before heap explosions.

Real Example:
CV parsing system: retrieve ContentVersion.VersionData, encode base64, send to OpenAI API. Worked perfectly with 500KB test PDFs. Production users uploaded 5MB CVs with embedded images. Heap limit exception. Every. Single. Time.

Solutions:

  • Winter '26 External Services: Use ContentDocument ID pointers instead of loading into the heap. Supports files up to 16MB, depending on the integration pattern and API capabilities.

  • File size validation: Reject >4MB at upload. Simple but user-hostile.

  • External storage: Upload to S3/Google Drive, store reference in Salesforce.

  • Chunking: Split files, process sequentially. Requires API multipart upload support.

     

File Format Hell

Salesforce Has Zero Native Parsing
PDF, DOCX, DOC - Salesforce can't parse any of them. ContentVersion.VersionData gives raw binary. Your options:

  • External API (OpenAI, AWS Textract): Accurate but expensive. Best for complex layouts.

  • Pre-process before upload: Convert to text externally, upload both.

  • Accept plain text only: Simplest but limits user experience.

Real CV Parsing Issues:
PDFs with heavy images return garbage text. Scanned PDFs need OCR (lower accuracy, higher cost). Multi-column layouts confuse extraction order. Solution: Validate format client-side, reject scanned PDFs, provide clear error messages.

 

Security: The Silent Failure Mode

ContentDocument Sharing Complexity:

  • Inferred sharing doesn't work in Communities - requires ContentDistribution

  • Parent record sharing ≠ ContentDocument sharing

  • ContentDocumentLink not included in sharing rules

  • Guest users may need to use ContentDistribution (paid) or Base64 to get access to ContentDocument 

Secure Pattern:
Store sensitive files in ContentVersion with Viewer ShareType. Link only to user-owned records. Use without sharing Apex with custom access logic. For public files, use ContentDistribution with expiration or Base64 in public objects. Log access via Platform Events.

 

Performance Patterns

Loading Strategies:

Lazy Loading: Load on demand. Best for galleries where users view few files. Pros: Fast initial load. Cons: Delay on click.

Eager Loading: Load everything upfront. Best for single-file displays. Pros: Instant display. Cons: Slow if unused.

Hybrid: Load thumbnails eager, full files lazy. Best for most cases. Pros: Fast previews + quality on demand.

Batch Processing Trick:
Don't process files in batch execute() - heap limit applies to entire chunk. Instead, batch creates Queueable jobs for each file. Each Queueable gets its own 12MB heap limit. Failures isolated, better error reporting.

 

Decision Framework

File Size:

Under 50KB → Base64 in custom fields

50KB - 4MB → ContentVersion (careful heap management)

4MB - 16MB → External Services (Winter '26)

Over 16MB → External storage (S3, Drive)

Access Pattern:

Internal users only → ContentVersion + URLs

External/guest users → Base64 or ContentDistribution

Frequent reads → URLs with CDN

Rare reads → Either works

Processing Needs:

Display only → URLs

Text extraction → External API

Image manipulation → Client-side pre-upload

Complex operations → External worker service

 

Top 10 Disasters

  1. Processing in triggers: Always queue async. Triggers have strict limits and shared heap.
  2. Assuming UTF-8: Windows users upload various encodings. Explicitly handle character encoding.
  3. No ContentDocument cleanup: Deleting records doesn't delete files. Storage costs explode.
  4. Loading all files together: Querying VersionData for multiple files blows heap. One at a time.
  5. Trusting file extensions: Extensions lie. Check actual MIME type.
  6. No async error handling: Queueable fails silently. Implement logging and notifications.
  7. Forgetting IsLatest: ContentVersion creates versions on update. Always use IsLatest = true.
  8. Client-side validation only: Users bypass it. Always re-validate in Apex.
  9. Not testing edge cases: Test corrupted, oversized, wrong format, concurrent uploads.
  10. Hardcoding file types: Use Custom Metadata to switch URL/Base64. Build for migration.

 

The Reality Check

There Is No Perfect Solution
Every file handling approach is a compromise. URLs have auth complexity. Base64 has size limits. ContentVersion has query overhead. External storage has integration costs.

What Works:

  • Start with ContentVersion + URLs unless you have specific reasons

  • Move to Base64 for small, frequently-accessed community images

  • Always process files asynchronously

  • Plan for cleanup from day one

  • Test with realistic sizes and formats, not toy examples

  • Use Custom Metadata to switch approaches - you WILL need to refactor

 

Treat File Architecture as a Strategic Decision

In practice, file handling decisions should be driven not only by technical constraints but by business context, expected scale, and long-term maintainability. The "right" approach depends on how often files are accessed, who needs access, how they are processed, and how the system is expected to evolve. A community site serving 10,000 guest users needs different architecture than an internal app for 50 employees. A document management system processing 1,000 PDFs daily needs different infrastructure than a profile picture uploader.

Treat file architecture as a foundational decision — not an implementation detail — because changing it later is expensive. Migrating from Attachment to ContentVersion means rebuilding sharing logic and access patterns. Switching from Base64 to URLs requires data migration and front-end refactoring. Moving from on-platform storage to external services impacts authentication, performance, and compliance.

File handling is where theory meets reality and theory loses. Build for edge cases, test failures, never trust documentation examples. Production files are malformed, oversized, and uploaded by users who don't understand file types. Your architecture needs to handle that, not the happy path. Make architectural decisions early, document the trade-offs, and build flexibility to adapt when requirements inevitably change.


Alexander Zherebilo
Certified Salesforce Developer
image
Expertise
Question to the expert
image

We have available resources to start working on your project within 5 business days

1 UX Designer

image

1 Admin

image

2 QA engineers

image

1 Consultant

image
Related Articles
All articles
image
How to Customize Salesforce Field Service Mobile for Your Technicians
Salesforce Field Service Mobile provides a standard technician experience that companies can extend to fit their own service processes. This article looks at areas where a custom mobile workflow can help: AI repair assistance, field documentation, external tools, back-office integrations, quotes and payments on site, barcode scanning and role-based mobile layouts. It also outlines four practical steps for planning a mobile workflow around the technician’s work.
21 October 2026
image
Salesforce Field Service Mobile: New Capabilities for Technicians
Salesforce Field Service Mobile continues to evolve with new capabilities for technicians working in the field. Explore how updates to job preparation, mobile forms, voice input, mapping, and Work Order views are changing the technician experience, and learn why configuring these capabilities around your service operations matters.
14 October 2026
image
Closing the Gap Between Field Service and Business Needs
Standard Salesforce Field Service configuration covers many service processes, but individual businesses can have different workflows, working conditions, scheduling rules, and operational requirements. This article looks at three areas where standard configuration can fall short: how technicians work, the conditions of field service operations, and business-specific processes. It also provides a practical checklist of signs that a Salesforce Field Service setup could benefit from customization.
07 October 2026