In contact object, we have 15,000 records. I want to display them into a lightning component.

Functionality :

  1. Need to load 15,000(maybe more) records.
  2. Need to provide pagination.
  3. Need to Provide filters for search functionality.
  4. Need to provide multiple row selection(select all also) to send email to contacts at a time. After sending email need to update selected contacts and reflect them in UI.

It's taking lot of time to iterate 15,000 records in every server call.

My question is: What is the maximum number of records will get from a lightning server call? what is best way to achieve this functionality? what is the best way in Visualforce Remoting, Lightning Implementation?

  • While I haven't tried it out myself - but if I have to answer your question, then I would say it's possible. There's no limitation as such defined where you cannot do so. However to be able to provide any further details, it will be good to know what have you tried so far and what are your observations and if there are any specific issues. In its current form your question is too broad and needs some more details.
    – Jayant Das
    Oct 31, 2018 at 13:21
  • Easiest way would be using cache mechanism like storable actions or auraenabled cache true and bring all the records at once to you lightning component and using a client side grid (like jquery datatables) or build one for yourself. The idea here is to show meaning full wait items like a stencil or spinner because first time it’s going to take a longer time (based on number of records)but once it has it in cache it’s going to be a quick load(on my way to work can get you a more detailed answer later) Oct 31, 2018 at 13:36
  • As of now the functionality was implemented in Lightning Component. We tested it with 1000 records which is working fine. But later data size has increased. Suppose, I have 10,000 records. Page size is 100. It is spitted into 100 pages. I choose few records in 3rd page and 4th page. When I click on "Next", "Previous" buttons the selection shouldn't be changed. Also, after click on send email button, I need to iterate 10,000 records to update selected records in 3rd and 4th pages.
    – Manoj
    Oct 31, 2018 at 13:38

4 Answers 4


Here's a demo I wrote some time ago. The code there only queries 1,000 rows, but you could change the limit to 50,000 rows. The actual loading process will take a few seconds (I'd guess about 4-6 seconds), but the pagination should be fast enough for practical uses. If you wanted to use some sort of pagination, you could sort by Id or CreatedDate, then do the query in chunks. Actual performance will vary, though, so you'll want to do some testing to see if it's necessary to perform multiple queries.


You have to make custom pagination with help of Apex. You can use Lightning data table for displaying records with pagination.

// Apex Class
public   with sharing class DataTableWithPagenation {

 public static AccountPagerWrapper fetchAccount(Decimal pageNumber ,Integer recordToDisply) {
      Integer pageSize = recordToDisply;
      Integer offset = ((Integer)pageNumber - 1) * pageSize;

    AccountPagerWrapper obj =  new AccountPagerWrapper();
      obj.pageSize = pageSize;
        obj.page = (Integer) pageNumber;
        obj.total = [SELECT count() FROM account];
        obj.accounts = [SELECT Id, Name,Phone FROM Account ORDER BY Name LIMIT :recordToDisply OFFSET :offset];
         return obj;

 public class AccountPagerWrapper {
    @AuraEnabled public Integer pageSize {get;set;}
    @AuraEnabled public Integer page {get;set;}
    @AuraEnabled public Integer total {get;set;}
    @AuraEnabled public List accounts {get;set;}

Lightning :

// Component

<aura:attribute name="Accounts" type="Account[]"/>
<aura:attribute name="page" type="integer" description="using for store page Number"/>
<aura:attribute name="pages" type="integer" description="using for store All Pages page Number"/>
<aura:attribute name="total" type="integer" description="total records count store "/>
<aura:attribute name="mycolumns" type="List"/>

<div class="slds-m-around_small">
    <div class="slds-page-header" role="banner">

        <p class="slds-page-header__title slds-truncate">{!v.total} Accounts • page {!v.page} / {!v.pages}</p>
        <ui:inputSelect aura:id="recordSize" label="Display Record Per Page: " change="{!c.onSelectChange}">
            <ui:inputSelectOption text="10" label="10" value="true"/>
            <ui:inputSelectOption text="15" label="15"/>
            <ui:inputSelectOption text="20" label="20"/>

    <p class="slds-p-horizontal_small slds-box">
        <lightning:datatable data="{!v.Accounts}" columns="{! v.mycolumns }" keyField="id"  />
    <div class="slds-align_absolute-center">            
        <lightning:button disabled="{!v.page == 1}" variant="brand" label="Previous Page" onclick="{! c.navigate }" />            
        <lightning:button disabled="{!v.page == v.pages}" aura:id="previousPage" variant="brand" label="Next Page" onclick="{! c.navigate }" />

//Js Controller

   doInit: function(component, event, helper) {
      // this function call on the component load first time     
      // get the page Number if it's not define, take 1 as default

      var page = component.get("v.page") || 1;
      // get the select option (drop-down) values.   
      var recordToDisply = component.find("recordSize").get("v.value");

       component.set('v.mycolumns', [
                   {label: 'Account Name', fieldName: 'Name', type: 'Name',sortable:'true'},                   
                {label: 'Phone', fieldName: 'Phone', type: 'Phone',sortable:'true'},
                {label: 'Email ID', fieldName: 'Email_ID__c', type: 'Email',sortable:'true'}

      // call the helper function   
      helper.getAccounts(component, page, recordToDisply);


   navigate: function(component, event, helper) {
      // this function call on click on the previous page button  
      var page = component.get("v.page") || 1;
      // get the previous button label  
      var direction = event.getSource().get("v.label");
      // get the select option (drop-down) values.  
      var recordToDisply = component.find("recordSize").get("v.value");
      // set the current page,(using ternary operator.)  
      page = direction === "Previous Page" ? (page - 1) : (page + 1);
      // call the helper function
      helper.getAccounts(component, page, recordToDisply);


   onSelectChange: function(component, event, helper) {
      // this function call on the select opetion change,     
      var page = 1
      var recordToDisply = component.find("recordSize").get("v.value");
      helper.getAccounts(component, page, recordToDisply);

//js Helper

   getAccounts: function(component, page, recordToDisply) {

      // create a server side action. 
      var action = component.get("c.fetchAccount");
      // set the parameters to method 
         "pageNumber": page,
         "recordToDisply": recordToDisply
      // set a call back   
      action.setCallback(this, function(a) {
         // store the response return value (wrapper class insatance)  
         var result = a.getReturnValue();
         console.log('result ---->' + JSON.stringify(result));
         // set the component attributes value with wrapper class properties.   

         component.set("v.Accounts", result.accounts);
         component.set("v.page", result.page);
         component.set("v.total", result.total);
         component.set("v.pages", Math.ceil(result.total / recordToDisply));

      // enqueue the action 

Your question :

What is the maximum number of records will get from a lightning server call?

As we get limited record with page count and record count. It should not create any problem in record fetching.

what is best way to achieve this functionality? You can try above approach.

what is the best way in Visualforce Remoting, Lightning Implementation? You can use both.

  • If OFFSET is 2000, will we get offset error?
    – Manoj
    Oct 31, 2018 at 13:33
  • If we use pagination, i dont think we should display 2000 records in one go. if we display records in data table normally we take 20,30 or 50 records. So that limit will not come. Oct 31, 2018 at 14:11
  • This solution doesn’t scale. As Manoj pointed out, offset doesn’t work over 2000. Oct 31, 2018 at 14:57
  • See another thread of using offset and avoiding offset exception. salesforce.stackexchange.com/questions/22631/… Oct 31, 2018 at 15:23

An error is coming in your code Unable to find action 'fetchAccount' on the controller of c:Account.

Please check it.


This is an interesting question. But thinking about requirements details, who would iterate over 15k records?

If one wants to select a subset of thousands of records, he/she would filter this set of records at the first glance.

#1 Approach : sorting and filtering at client side

If the amount is not too high, you can get all records and filtering and sorting them at client side by using a LWC Datatable. It will work fine.

Here is a nice example of pagination at client side

#2 Approach: filtering by using a Screenflow and a Datatable

But you're speaking about thousands of records. So, you could use a Screenflow and inside it, to create a logic by using a Datatable where you can select many records by holding their IDs.

You can perform countless of filters, and for each filter you increment the IDs collection and at final stage you would have a subset of these 15k records.

Doing so, there's no need to worry about pagination at server side or client side.

Here a nice tutorial of ScreenFlows with Datatable

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .