Apex Nirvana
Embracing Governor Limits
Dan Appleman, Full Circle CRM, CTO
Author: “Advanced Apex Programming for Salesforce.com and Force.com”
@danappleman
Safe Harbor
 Safe harbor statement under the Private Securities Litigation Reform Act of 1995:

 This presentation may contain forward-looking statements that involve risks, uncertainties, and assumptions. If any such uncertainties materialize or if
 any of the assumptions proves incorrect, the results of salesforce.com, inc. could differ materially from the results expressed or implied by the forward-
 looking statements we make. All statements other than statements of historical fact could be deemed forward-looking, including any projections of
 product or service availability, subscriber growth, earnings, revenues, or other financial items and any statements regarding strategies or plans of
 management for future operations, statements of belief, any statements concerning new, planned, or upgraded services or technology developments
 and customer contracts or use of our services.

 The risks and uncertainties referred to above include – but are not limited to – risks associated with developing and delivering new functionality for our
 service, new products and services, our new business model, our past operating losses, possible fluctuations in our operating results and rate of growth,
 interruptions or delays in our Web hosting, breach of our security measures, the outcome of intellectual property and other litigation, risks associated
 with possible mergers and acquisitions, the immature market in which we operate, our relatively limited operating history, our ability to expand, retain,
 and motivate our employees and manage our growth, new releases of our service and successful customer deployment, our limited history reselling
 non-salesforce.com products, and utilization and selling to larger enterprise customers. Further information on potential factors that could affect the
 financial results of salesforce.com, inc. is included in our annual report on Form 10-Q for the most recent fiscal quarter ended July 31, 2012. This
 documents and others containing important disclosures are available on the SEC Filings section of the Investor Information section of our Web site.

 Any unreleased services or features referenced in this or other presentations, press releases or public statements are not currently available and may
 not be delivered on time or at all. Customers who purchase our services should make the purchase decisions based upon features that are currently
 available. Salesforce.com, inc. assumes no obligation and does not intend to update these forward-looking statements.
Coding is Fun


 Where do we come from?
 What makes it fun?
This ol’ Programmer

 1976: PDP11/45 - 256KB (8k/user)
 1981: PC – 16K-256KB
 1986: Mac Plus 1MB
 1991: x486 – 64MB
 2000: PIII – 256-512MB
 Smartphone – 512MB – 1GB
 Desktop computer – 16GB+
Two rules….
Rule #1 to Live By




Design First, Code Later.
              Limits are a first order factor in design
Rule #2 to Live By



        There is no code
           but bulk code
Challenge:

     Match incoming leads to accounts by comparing
     Email address to account website domain



Leads with Email domain            Black box
                           Cost N script lines * leads *   Best match
    Matching accounts       matching accounts/lead
To Much To Like
For each lead
        Pull the domain from the Email address
        Add to dynamic query string for accounts using ‘LIKE’ on the website field
Database.query ( ‘ Select Id, …. , from Account where website like ‘%xyz.com’ or …. ‘)
Run through black box
Update leads
    Logic issues: LIKE isn’t reliable.
             Mycompany.com, yourcompany.com matches %company.com
             Fails for subdirectories: mysite.com/default.html
          Limit issues:                  Captures extra accounts that need to be
             Script lines?
             Heap?                       filtered
             SOQL complexity?            = more script lines, more heap usage
             Non-Selective query?
Scripts and Heaps                                                        Account
                                        Account
                                        Insert/update                  Custom field
                                        trigger                        Domain__c


For each lead
          Pull the domain from the Email address and add to Set
[Select id, …, from Account where Domain__c in :theset]
Build Map from lead ID to list of accounts (possible Group By query)
Run through black box
Update leads
            Limit issues:
               Script lines?                 No wasted accounts captured
               Heap?                         No extra filtering
               SOQL complexity?
               Non-Selective query?
Into the Future
For each lead insert trigger
        Future call – pass lead IDs as parameters

For each lead
          Pull the domain from the Email address and add to Set
[Select id, …, from Account where Domain__c in :theset]
Build Map from lead ID to list of accounts (possible Group By query)
Run through black box
Update leads

          Limit issues:
                                        Easy way to get more limits,
             Future calls
             Script lines?              But look at the cost
             Heap?
             SOQL complexity?
             Non-Selective query?
B to C – Queue & Batch                                                 Lead

Scheduled batch                                                      Custom field
Query leads where Match_Pending__c                                   MatchPending__c
For each lead
          Pull the domain from the Email address and add to Set
[Select id, …, from Account where Domain__c in :theset]
Build Map from lead ID to list of accounts (possible Group By query)
Run through black box
Update leads

             Limit issues:                       Imagine > 100K leads
                Script lines?                    And > 100K person accounts
                Heap?
                SOQL complexity?                  Ok - If you use custom indexes
                Non-Selective query?              (which are also limited)
B to C – In Reverse
Scheduled batch
Query all accounts with Domain__c, group by Domain__c
Build set of domains
Query all leads with domain (custom field / formula field?) that aren’t yet assigned
Build Map from lead ID to list of matching accounts
Run through black box
Update leads

                                                      Imagine > 100K leads
              Limit issues:                           And > 100K person accounts
                 Script lines?
                 Heap?                                Ok with indexed custom field,
                 SOQL complexity?                     Or small # of leads
                 Non-Selective query?                 Or if date filter is ok
Custom Custom Index                                            Account
           DomainIndexer__c
                                                          Lookup
             Domain__c                                    DomainIndexer__c
             External/unique

For each lead
          Pull the domain from the Email address and add to Set
[Select id, (Select ID from Accounts), from DomainIndexer__c where Domain__c in :theset]
Build Map from lead ID to list of accounts by way of DomainIndexer objects
Run through black box
Update leads
             Limit issues:
                Script lines?
                Heap?
                SOQL complexity?
                Non-Selective query?              Ok with managed apps
                Custom object count?
Which Design is Best?
Which Design is Best?

 That’s not the point
   Choosing among multiple designs results in better solutions than
    coding and iterating
   Considering limits from the start makes you a better developer.
   Solving limit issues at design time means you may never see a limit
    issue.
Conclusion

 • Limits are fun!
 • Design first!
 • There is no code but bulk code!
Next Steps

Question for chatter – tell us about a time you
overcame a limit issue.


Stop by and chat at the Full Circle CRM booth
                                 btw… we’re hiring




                                                     www.AdvancedApex.com
No question?
Tell us about your favorite way to overcome a particular limit.
AdvancedApex.com

Apex Nirvana

  • 1.
    Apex Nirvana Embracing GovernorLimits Dan Appleman, Full Circle CRM, CTO Author: “Advanced Apex Programming for Salesforce.com and Force.com” @danappleman
  • 2.
    Safe Harbor Safeharbor statement under the Private Securities Litigation Reform Act of 1995: This presentation may contain forward-looking statements that involve risks, uncertainties, and assumptions. If any such uncertainties materialize or if any of the assumptions proves incorrect, the results of salesforce.com, inc. could differ materially from the results expressed or implied by the forward- looking statements we make. All statements other than statements of historical fact could be deemed forward-looking, including any projections of product or service availability, subscriber growth, earnings, revenues, or other financial items and any statements regarding strategies or plans of management for future operations, statements of belief, any statements concerning new, planned, or upgraded services or technology developments and customer contracts or use of our services. The risks and uncertainties referred to above include – but are not limited to – risks associated with developing and delivering new functionality for our service, new products and services, our new business model, our past operating losses, possible fluctuations in our operating results and rate of growth, interruptions or delays in our Web hosting, breach of our security measures, the outcome of intellectual property and other litigation, risks associated with possible mergers and acquisitions, the immature market in which we operate, our relatively limited operating history, our ability to expand, retain, and motivate our employees and manage our growth, new releases of our service and successful customer deployment, our limited history reselling non-salesforce.com products, and utilization and selling to larger enterprise customers. Further information on potential factors that could affect the financial results of salesforce.com, inc. is included in our annual report on Form 10-Q for the most recent fiscal quarter ended July 31, 2012. This documents and others containing important disclosures are available on the SEC Filings section of the Investor Information section of our Web site. Any unreleased services or features referenced in this or other presentations, press releases or public statements are not currently available and may not be delivered on time or at all. Customers who purchase our services should make the purchase decisions based upon features that are currently available. Salesforce.com, inc. assumes no obligation and does not intend to update these forward-looking statements.
  • 3.
    Coding is Fun Where do we come from? What makes it fun?
  • 4.
    This ol’ Programmer 1976: PDP11/45 - 256KB (8k/user) 1981: PC – 16K-256KB 1986: Mac Plus 1MB 1991: x486 – 64MB 2000: PIII – 256-512MB Smartphone – 512MB – 1GB Desktop computer – 16GB+
  • 5.
  • 6.
    Rule #1 toLive By Design First, Code Later. Limits are a first order factor in design
  • 7.
    Rule #2 toLive By There is no code but bulk code
  • 8.
    Challenge: Match incoming leads to accounts by comparing Email address to account website domain Leads with Email domain Black box Cost N script lines * leads * Best match Matching accounts matching accounts/lead
  • 9.
    To Much ToLike For each lead Pull the domain from the Email address Add to dynamic query string for accounts using ‘LIKE’ on the website field Database.query ( ‘ Select Id, …. , from Account where website like ‘%xyz.com’ or …. ‘) Run through black box Update leads Logic issues: LIKE isn’t reliable. Mycompany.com, yourcompany.com matches %company.com Fails for subdirectories: mysite.com/default.html Limit issues: Captures extra accounts that need to be Script lines? Heap? filtered SOQL complexity? = more script lines, more heap usage Non-Selective query?
  • 10.
    Scripts and Heaps Account Account Insert/update Custom field trigger Domain__c For each lead Pull the domain from the Email address and add to Set [Select id, …, from Account where Domain__c in :theset] Build Map from lead ID to list of accounts (possible Group By query) Run through black box Update leads Limit issues: Script lines? No wasted accounts captured Heap? No extra filtering SOQL complexity? Non-Selective query?
  • 11.
    Into the Future Foreach lead insert trigger Future call – pass lead IDs as parameters For each lead Pull the domain from the Email address and add to Set [Select id, …, from Account where Domain__c in :theset] Build Map from lead ID to list of accounts (possible Group By query) Run through black box Update leads Limit issues: Easy way to get more limits, Future calls Script lines? But look at the cost Heap? SOQL complexity? Non-Selective query?
  • 12.
    B to C– Queue & Batch Lead Scheduled batch Custom field Query leads where Match_Pending__c MatchPending__c For each lead Pull the domain from the Email address and add to Set [Select id, …, from Account where Domain__c in :theset] Build Map from lead ID to list of accounts (possible Group By query) Run through black box Update leads Limit issues: Imagine > 100K leads Script lines? And > 100K person accounts Heap? SOQL complexity? Ok - If you use custom indexes Non-Selective query? (which are also limited)
  • 13.
    B to C– In Reverse Scheduled batch Query all accounts with Domain__c, group by Domain__c Build set of domains Query all leads with domain (custom field / formula field?) that aren’t yet assigned Build Map from lead ID to list of matching accounts Run through black box Update leads Imagine > 100K leads Limit issues: And > 100K person accounts Script lines? Heap? Ok with indexed custom field, SOQL complexity? Or small # of leads Non-Selective query? Or if date filter is ok
  • 14.
    Custom Custom Index Account DomainIndexer__c Lookup Domain__c DomainIndexer__c External/unique For each lead Pull the domain from the Email address and add to Set [Select id, (Select ID from Accounts), from DomainIndexer__c where Domain__c in :theset] Build Map from lead ID to list of accounts by way of DomainIndexer objects Run through black box Update leads Limit issues: Script lines? Heap? SOQL complexity? Non-Selective query? Ok with managed apps Custom object count?
  • 15.
  • 16.
    Which Design isBest? That’s not the point  Choosing among multiple designs results in better solutions than coding and iterating  Considering limits from the start makes you a better developer.  Solving limit issues at design time means you may never see a limit issue.
  • 17.
    Conclusion • Limitsare fun! • Design first! • There is no code but bulk code!
  • 18.
    Next Steps Question forchatter – tell us about a time you overcame a limit issue. Stop by and chat at the Full Circle CRM booth btw… we’re hiring www.AdvancedApex.com
  • 19.
    No question? Tell usabout your favorite way to overcome a particular limit.
  • 20.