diff -r f93d312ddd2f src-db/database/sourcedata/AD_MESSAGE.xml
--- a/src-db/database/sourcedata/AD_MESSAGE.xml	Fri Aug 30 14:39:38 2019 +0200
+++ b/src-db/database/sourcedata/AD_MESSAGE.xml	Fri Aug 30 14:45:25 2019 +0200
@@ -2092,6 +2092,18 @@
 <!--C4E1B578B13840ADA3BC8092798E743A-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--C4E1B578B13840ADA3BC8092798E743A--></AD_MESSAGE>
 
+<!--C768AEA530B44845ACBDA07AA15CF291--><AD_MESSAGE>
+<!--C768AEA530B44845ACBDA07AA15CF291-->  <AD_MESSAGE_ID><![CDATA[C768AEA530B44845ACBDA07AA15CF291]]></AD_MESSAGE_ID>
+<!--C768AEA530B44845ACBDA07AA15CF291-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--C768AEA530B44845ACBDA07AA15CF291-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--C768AEA530B44845ACBDA07AA15CF291-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--C768AEA530B44845ACBDA07AA15CF291-->  <VALUE><![CDATA[OBMOBC_MasterdataRequestError]]></VALUE>
+<!--C768AEA530B44845ACBDA07AA15CF291-->  <MSGTEXT><![CDATA[There was an error in the masterdata requests, aborted current refresh]]></MSGTEXT>
+<!--C768AEA530B44845ACBDA07AA15CF291-->  <MSGTYPE><![CDATA[W]]></MSGTYPE>
+<!--C768AEA530B44845ACBDA07AA15CF291-->  <AD_MODULE_ID><![CDATA[08943B85ADF64E708797A753E5B6AAEE]]></AD_MODULE_ID>
+<!--C768AEA530B44845ACBDA07AA15CF291-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--C768AEA530B44845ACBDA07AA15CF291--></AD_MESSAGE>
+
 <!--C88B6F2C58B3477BAEA816BF54559E50--><AD_MESSAGE>
 <!--C88B6F2C58B3477BAEA816BF54559E50-->  <AD_MESSAGE_ID><![CDATA[C88B6F2C58B3477BAEA816BF54559E50]]></AD_MESSAGE_ID>
 <!--C88B6F2C58B3477BAEA816BF54559E50-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
diff -r f93d312ddd2f src-db/database/sourcedata/AD_PREFERENCE.xml
--- a/src-db/database/sourcedata/AD_PREFERENCE.xml	Fri Aug 30 14:39:38 2019 +0200
+++ b/src-db/database/sourcedata/AD_PREFERENCE.xml	Fri Aug 30 14:45:25 2019 +0200
@@ -22,6 +22,17 @@
 <!--01EAFAD3A2204971A35D18E8CEBE9F8C-->  <AD_MODULE_ID><![CDATA[08943B85ADF64E708797A753E5B6AAEE]]></AD_MODULE_ID>
 <!--01EAFAD3A2204971A35D18E8CEBE9F8C--></AD_PREFERENCE>
 
+<!--0280B1B0ED464B34924688C1C678A52A--><AD_PREFERENCE>
+<!--0280B1B0ED464B34924688C1C678A52A-->  <AD_PREFERENCE_ID><![CDATA[0280B1B0ED464B34924688C1C678A52A]]></AD_PREFERENCE_ID>
+<!--0280B1B0ED464B34924688C1C678A52A-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--0280B1B0ED464B34924688C1C678A52A-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--0280B1B0ED464B34924688C1C678A52A-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--0280B1B0ED464B34924688C1C678A52A-->  <VALUE><![CDATA[Y]]></VALUE>
+<!--0280B1B0ED464B34924688C1C678A52A-->  <PROPERTY><![CDATA[OBMOBC_NotAutoLoadIncrementalAtLogin]]></PROPERTY>
+<!--0280B1B0ED464B34924688C1C678A52A-->  <ISPROPERTYLIST><![CDATA[Y]]></ISPROPERTYLIST>
+<!--0280B1B0ED464B34924688C1C678A52A-->  <AD_MODULE_ID><![CDATA[08943B85ADF64E708797A753E5B6AAEE]]></AD_MODULE_ID>
+<!--0280B1B0ED464B34924688C1C678A52A--></AD_PREFERENCE>
+
 <!--18639B6C06B44324A65D199CD8A32440--><AD_PREFERENCE>
 <!--18639B6C06B44324A65D199CD8A32440-->  <AD_PREFERENCE_ID><![CDATA[18639B6C06B44324A65D199CD8A32440]]></AD_PREFERENCE_ID>
 <!--18639B6C06B44324A65D199CD8A32440-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
diff -r f93d312ddd2f src-db/database/sourcedata/AD_REF_LIST.xml
--- a/src-db/database/sourcedata/AD_REF_LIST.xml	Fri Aug 30 14:39:38 2019 +0200
+++ b/src-db/database/sourcedata/AD_REF_LIST.xml	Fri Aug 30 14:45:25 2019 +0200
@@ -496,6 +496,18 @@
 <!--6D6BEF55A6864548BDF3F2771B669D0C-->  <AD_MODULE_ID><![CDATA[08943B85ADF64E708797A753E5B6AAEE]]></AD_MODULE_ID>
 <!--6D6BEF55A6864548BDF3F2771B669D0C--></AD_REF_LIST>
 
+<!--6E6E9B37800B4F50AAAD606330E887C3--><AD_REF_LIST>
+<!--6E6E9B37800B4F50AAAD606330E887C3-->  <AD_REF_LIST_ID><![CDATA[6E6E9B37800B4F50AAAD606330E887C3]]></AD_REF_LIST_ID>
+<!--6E6E9B37800B4F50AAAD606330E887C3-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--6E6E9B37800B4F50AAAD606330E887C3-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--6E6E9B37800B4F50AAAD606330E887C3-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--6E6E9B37800B4F50AAAD606330E887C3-->  <VALUE><![CDATA[OBMOBC_BackgroundMasterdataMaxSize]]></VALUE>
+<!--6E6E9B37800B4F50AAAD606330E887C3-->  <NAME><![CDATA[Background Masterdata Maximum Size]]></NAME>
+<!--6E6E9B37800B4F50AAAD606330E887C3-->  <DESCRIPTION><![CDATA[Maximum size for all models for incremental masterdata refresh in background. Value -1 disable the background refresh of the masterdata]]></DESCRIPTION>
+<!--6E6E9B37800B4F50AAAD606330E887C3-->  <AD_REFERENCE_ID><![CDATA[A26BA480E2014707B47257024C3CBFF7]]></AD_REFERENCE_ID>
+<!--6E6E9B37800B4F50AAAD606330E887C3-->  <AD_MODULE_ID><![CDATA[08943B85ADF64E708797A753E5B6AAEE]]></AD_MODULE_ID>
+<!--6E6E9B37800B4F50AAAD606330E887C3--></AD_REF_LIST>
+
 <!--73967117B13C4B5EAEA505E04A7E80A3--><AD_REF_LIST>
 <!--73967117B13C4B5EAEA505E04A7E80A3-->  <AD_REF_LIST_ID><![CDATA[73967117B13C4B5EAEA505E04A7E80A3]]></AD_REF_LIST_ID>
 <!--73967117B13C4B5EAEA505E04A7E80A3-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
diff -r f93d312ddd2f src-util/modulescript/src/org/openbravo/mobile/core/modulescript/MantainMasterdataRefreshBehaviour41027.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src-util/modulescript/src/org/openbravo/mobile/core/modulescript/MantainMasterdataRefreshBehaviour41027.java	Fri Aug 30 14:45:25 2019 +0200
@@ -0,0 +1,55 @@
+/*
+ ************************************************************************************
+ * Copyright (C) 2019 Openbravo S.L.U.
+ * Licensed under the Openbravo Commercial License version 1.0
+ * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html
+ * or in the legal folder of this module distribution.
+ ************************************************************************************
+ */
+
+package org.openbravo.mobile.core.modulescript;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.openbravo.database.ConnectionProvider;
+import org.openbravo.modulescript.ModuleScript;
+import org.openbravo.modulescript.ModuleScriptExecutionLimits;
+import org.openbravo.modulescript.OpenbravoVersion;
+
+/**
+ * 
+ * Previous to 19Q4 masterdata is refreshed in each login or F5.
+ * From 19Q4, this preference OBMOBC_NotAutoLoadIncrementalAtLogin comes set by default to 'Y'.
+ * This module script will mantain the old behaviour for current instalations.
+ *
+ */
+public class MantainMasterdataRefreshBehaviour41027 extends ModuleScript {
+
+  private static final Logger log4j = LogManager.getLogger();
+  private static final String RETAIL_PACK_MODULE_ID = "03FAB282A7BF47D3B1B242AC67F7845B";
+
+  @Override
+  public void execute() {
+    try {
+      ConnectionProvider cp = getConnectionProvider();
+      final boolean preferenceExists = MantainMasterdataRefreshBehaviour41027Data.preferenceCreated(cp);
+      if ( ! preferenceExists ) {
+        MantainMasterdataRefreshBehaviour41027Data.createPreference(cp);
+      }
+    } catch (Exception e) {
+      handleError(e);
+    }
+  }
+
+  @Override
+  protected ModuleScriptExecutionLimits getModuleScriptExecutionLimits() {
+    return new ModuleScriptExecutionLimits(RETAIL_PACK_MODULE_ID, null,
+        new OpenbravoVersion(1, 8, 4700)); // execute when updating till 19Q4
+  }
+
+  @Override
+  protected boolean executeOnInstall() {
+    return false;
+  }
+
+}
diff -r f93d312ddd2f src-util/modulescript/src/org/openbravo/mobile/core/modulescript/MantainMasterdataRefreshBehaviour41027_Data.xsql
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src-util/modulescript/src/org/openbravo/mobile/core/modulescript/MantainMasterdataRefreshBehaviour41027_Data.xsql	Fri Aug 30 14:45:25 2019 +0200
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+/*
+ ************************************************************************************
+ * Copyright (C) 2019 Openbravo S.L.U.
+ * Licensed under the Openbravo Commercial License version 1.0
+ * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html
+ * or in the legal folder of this module distribution.
+ ************************************************************************************
+ */
+-->
+<SqlClass name="MantainMasterdataRefreshBehaviour41027Data" package="org.openbravo.mobile.core.modulescript">
+  <SqlMethod name="preferenceCreated" type="preparedStatement" return="boolean">
+      <Sql>
+        <![CDATA[
+        SELECT count(*) as exist 
+        FROM DUAL 
+        WHERE EXISTS ( 
+          select 1 as num 
+          from ad_preference 
+          where property='OBMOBC_NotAutoLoadIncrementalAtLogin' 
+          and ad_module_id is null
+        )
+        ]]>
+      </Sql>
+  </SqlMethod>
+  <SqlMethod name="createPreference" type="preparedStatement" return="rowcount">
+       <Sql> 
+       <![CDATA[ 
+           INSERT INTO ad_preference (
+           ad_preference_id, ad_client_id, ad_org_id, isactive,
+           createdby, created, updatedby, updated, property, value, selected, ispropertylist
+           ) VALUES (
+           get_uuid(), '0', '0', 'Y', '0', NOW(), '0', NOW(),'OBMOBC_NotAutoLoadIncrementalAtLogin', 'N', 'Y', 'Y')
+         ]]>
+        </Sql>
+   </SqlMethod>
+</SqlClass>
diff -r f93d312ddd2f src-util/modulescript/src/src/org/openbravo/mobile/core/modulescript/MantainMasterdataRefreshBehaviour41027Data.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src-util/modulescript/src/src/org/openbravo/mobile/core/modulescript/MantainMasterdataRefreshBehaviour41027Data.java	Fri Aug 30 14:45:25 2019 +0200
@@ -0,0 +1,123 @@
+//Sqlc generated V1.O00-1
+package org.openbravo.mobile.core.modulescript;
+
+import java.sql.*;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.LogManager;
+
+import javax.servlet.ServletException;
+
+import org.openbravo.data.FieldProvider;
+import org.openbravo.database.ConnectionProvider;
+import org.openbravo.data.UtilSql;
+import org.openbravo.database.SessionInfo;
+
+@SuppressWarnings("serial")
+class MantainMasterdataRefreshBehaviour41027Data implements FieldProvider {
+static Logger log4j = LogManager.getLogger();
+  private String InitRecordNumber="0";
+  public String exist;
+
+  public String getInitRecordNumber() {
+    return InitRecordNumber;
+  }
+
+  public String getField(String fieldName) {
+    if (fieldName.equalsIgnoreCase("exist"))
+      return exist;
+   else {
+     log4j.debug("Field does not exist: " + fieldName);
+     return null;
+   }
+ }
+
+  public static boolean preferenceCreated(ConnectionProvider connectionProvider)    throws ServletException {
+    String strSql = "";
+    strSql = strSql + 
+      "        SELECT count(*) as exist " +
+      "        FROM DUAL " +
+      "        WHERE EXISTS ( " +
+      "          select 1 as num " +
+      "          from ad_preference " +
+      "          where property='OBMOBC_NotAutoLoadIncrementalAtLogin' " +
+      "          and ad_module_id is null" +
+      "        )";
+
+    ResultSet result;
+    boolean boolReturn = false;
+    PreparedStatement st = null;
+
+    try {
+    st = connectionProvider.getPreparedStatement(strSql);
+
+      result = st.executeQuery();
+      if(result.next()) {
+        boolReturn = !UtilSql.getValue(result, "exist").equals("0");
+      }
+      result.close();
+    } catch(SQLException e){
+      if (log4j.isDebugEnabled()) {
+        log4j.error("SQL error in query: " + strSql, e);
+      } else {
+        log4j.error("SQL error in query: " + strSql + " :" + e);
+      }
+      throw new ServletException("@CODE=" + Integer.toString(e.getErrorCode()) + "@" + e.getMessage());
+    } catch(Exception ex){
+      if (log4j.isDebugEnabled()) {
+        log4j.error("Exception in query: " + strSql, ex);
+      } else {
+        log4j.error("Exception in query: " + strSql + " :" + ex);
+      }
+      throw new ServletException("@CODE=@" + ex.getMessage());
+    } finally {
+      try {
+        connectionProvider.releasePreparedStatement(st);
+      } catch(Exception e){
+        log4j.error("Error during release*Statement of query: " + strSql, e);
+      }
+    }
+    return(boolReturn);
+  }
+
+  public static int createPreference(ConnectionProvider connectionProvider)    throws ServletException {
+    String strSql = "";
+    strSql = strSql + 
+      "           INSERT INTO ad_preference (" +
+      "           ad_preference_id, ad_client_id, ad_org_id, isactive," +
+      "           createdby, created, updatedby, updated, property, value, selected, ispropertylist" +
+      "           ) VALUES (" +
+      "           get_uuid(), '0', '0', 'Y', '0', NOW(), '0', NOW(),'OBMOBC_NotAutoLoadIncrementalAtLogin', 'N', 'Y', 'Y')";
+
+    int updateCount = 0;
+    PreparedStatement st = null;
+
+    try {
+    st = connectionProvider.getPreparedStatement(strSql);
+
+      SessionInfo.saveContextInfoIntoDB(connectionProvider.getConnection());
+      updateCount = st.executeUpdate();
+    } catch(SQLException e){
+      if (log4j.isDebugEnabled()) {
+        log4j.error("SQL error in query: " + strSql, e);
+      } else {
+        log4j.error("SQL error in query: " + strSql + " :" + e);
+      }
+      throw new ServletException("@CODE=" + Integer.toString(e.getErrorCode()) + "@" + e.getMessage());
+    } catch(Exception ex){
+      if (log4j.isDebugEnabled()) {
+        log4j.error("Exception in query: " + strSql, ex);
+      } else {
+        log4j.error("Exception in query: " + strSql + " :" + ex);
+      }
+      throw new ServletException("@CODE=@" + ex.getMessage());
+    } finally {
+      try {
+        connectionProvider.releasePreparedStatement(st);
+      } catch(Exception e){
+        log4j.error("Error during release*Statement of query: " + strSql, e);
+      }
+    }
+    return(updateCount);
+  }
+}
diff -r f93d312ddd2f web/org.openbravo.mobile.core/source/data/ob-dal.js
--- a/web/org.openbravo.mobile.core/source/data/ob-dal.js	Fri Aug 30 14:39:38 2019 +0200
+++ b/web/org.openbravo.mobile.core/source/data/ob-dal.js	Fri Aug 30 14:45:25 2019 +0200
@@ -1539,7 +1539,7 @@
    *
    *
    */
-  OB.Dal.loadModels = function (online, models, data, incremental, callback) {
+  OB.Dal.loadModels = function (online, models, data, incremental, callback, background) {
     var timestamp = 0;
     var key;
 
@@ -1576,6 +1576,7 @@
         // We can safely set the POSLastIncRefresh timestamp now.
         OB.UTIL.localStorage.setItem('POSLastIncRefresh', new Date().getTime());
         dalLoadModelsCallback();
+        return;
       }
       if (
       OB.MobileApp.model.get('modelsToLoad').length === 0 && OB.UTIL.queueStatus(models._LoadQueue || {})) {
@@ -1728,23 +1729,27 @@
                     }
                   }
                   };
-              OB.Data.localDB.transaction(
+              if (incremental) {
+                finishTransaction();
+              } else {
+                OB.Data.localDB.transaction(
 
-              function (tx) {
-                tx.executeSql('select count(1) as totalRecords from ' + item.prototype.tableName, [], function (tx, result) {
-                  logMsgForTransaction(
-                  true, item.prototype.modelName, result.rows.item(0).totalRecords);
-                  checkRecordsWithBackend(
-                  item.prototype.modelName, result.rows.item(0).totalRecords);
+                function (tx) {
+                  tx.executeSql('select count(1) as totalRecords from ' + item.prototype.tableName, [], function (tx, result) {
+                    logMsgForTransaction(
+                    true, item.prototype.modelName, result.rows.item(0).totalRecords);
+                    checkRecordsWithBackend(
+                    item.prototype.modelName, result.rows.item(0).totalRecords);
+                  }, function () {
+                    logMsgForTransaction(false, item.prototype.modelName);
+                  });
+                }, function (errorMsg) {
+                  OB.error(errorMsg);
+                  finishTransaction();
                 }, function () {
-                  logMsgForTransaction(false, item.prototype.modelName);
+                  finishTransaction();
                 });
-              }, function (errorMsg) {
-                OB.error(errorMsg);
-                finishTransaction();
-              }, function () {
-                finishTransaction();
-              });
+              }
             }
 
             // Skip load of models if it's a incremental refresh and the request timeout has been reached
@@ -1760,7 +1765,7 @@
             item.params.terminalTime = currentDate;
             item.params.terminalTimeOffset = currentDate.getTimezoneOffset();
           }
-          ds.load(item.params, incremental);
+          ds.load(item.params, incremental, background);
         }
       } else if (
       item && item.prototype.remote && OB.MobileApp.model.hasPermission(item.prototype.remote, true)) {
diff -r f93d312ddd2f web/org.openbravo.mobile.core/source/data/ob-datasource.js
--- a/web/org.openbravo.mobile.core/source/data/ob-datasource.js	Fri Aug 30 14:39:38 2019 +0200
+++ b/web/org.openbravo.mobile.core/source/data/ob-datasource.js	Fri Aug 30 14:45:25 2019 +0200
@@ -20,6 +20,8 @@
     OB.DS.requestAllowed = isAllowed;
   };
 
+  OB.DS.masterdataBackgroundModels = {}; // To store the models loaded in the masterdata refresh done in background
+
   function serviceSuccess(inSender, inResponse, callback, tx, requestCallback) {
     if (inResponse._entityname) {
       callback([inResponse]);
@@ -525,9 +527,8 @@
   };
   _.extend(OB.DS.DataSource.prototype, Backbone.Events);
 
-  OB.DS.DataSource.prototype.load = function (params, incremental) {
+  OB.DS.DataSource.prototype.load = function (params, incremental, background) {
     this.modelPagination = 1;
-    OB.info('[sdreresh-' + (incremental ? 'inc' : 'full') + '] The model ' + this.request.model.prototype.modelName + ' has started masterdata load');
     var me = this,
         handleError, handleIncrementalRequest, dataLoaded = 0;
     OB.UTIL.localStorage.setItem('recordsFromBackendFor' + me.request.model.prototype.modelName, 0);
@@ -537,16 +538,29 @@
 
       me.trigger('ready', 'failed');
     };
-    handleIncrementalRequest = function (
-    limit, offset, params, incremental, lastId) {
-      params = params || {};
-      params._limit = limit;
-      params._offset = offset;
-      params._count = OB.UTIL.localStorage.getItem('recordsFromBackendFor' + me.request.model.prototype.modelName) ? parseInt(
-      OB.UTIL.localStorage.getItem('recordsFromBackendFor' + me.request.model.prototype.modelName), 10) : 0;
-      params._isMasterdata = true;
-      params.overrideDefaultTimeout = true;
-      params.lastId = lastId;
+
+    const updateModelLastUpdatedTimestamp = function (
+    lastUpdated, data, totalRows) {
+      if (lastUpdated && data.length > 0) {
+        if (
+        OB.UTIL.localStorage.getItem('requestTimestamp' + me.request.model.prototype.modelName) && OB.UTIL.localStorage.getItem('requestTimestamp' + me.request.model.prototype.modelName) !== 'null') {
+          OB.UTIL.localStorage.setItem('lastUpdatedTimestamp' + me.request.model.prototype.modelName, OB.UTIL.localStorage.getItem('requestTimestamp' + me.request.model.prototype.modelName));
+        } else {
+          OB.error('[lastUpdatedTimestamp] ' + 'local storage (lastUpdatedTimestamp' + me.request.model.prototype.modelName + ') attempted to be set as null. Ignored. Current Value: ' + OB.UTIL.localStorage.getItem('lastUpdatedTimestamp' + me.request.model.prototype.modelName));
+        }
+        OB.UTIL.localStorage.removeItem('requestTimestamp' + me.request.model.prototype.modelName);
+        OB.UTIL.localStorage.setItem('recordsFromBackendFor' + me.request.model.prototype.modelName, totalRows);
+      } else {
+        if (
+        OB.UTIL.localStorage.getItem('requestTimestamp' + me.request.model.prototype.modelName) && OB.UTIL.localStorage.getItem('requestTimestamp' + me.request.model.prototype.modelName) !== 'null') {
+          OB.UTIL.localStorage.setItem('lastUpdatedTimestamp' + me.request.model.prototype.modelName, OB.UTIL.localStorage.getItem('requestTimestamp' + me.request.model.prototype.modelName));
+        }
+      }
+    };
+
+    const doModelRequest = function (params, functionSave, errorCallback) {
+      var offset = params._offset;
+      var limit = params._limit;
       if (offset === 0) {
         OB.UTIL.localStorage.setItem('requestTimestamp' + me.request.model.prototype.modelName, new Date().getTime());
         OB.UTIL.showLoadingMessage(
@@ -557,6 +571,10 @@
         OB.I18N.getLabel('OBMOBC_LoadingMessageModelPage', [
         me.request.model.prototype.modelName, offset / limit + 1]));
       }
+      delete params._data;
+      delete params._model;
+      delete params._lastUpdated;
+      delete params._totalRows;
       me.request.exec(
       params, function (data, message, lastUpdated, totalRows) {
         var newLastId;
@@ -574,49 +592,37 @@
             OB.UTIL.localStorage.removeItem('lastUpdatedTimestamp' + me.request.model.prototype.modelName);
             OB.UTIL.localStorage.setItem('recordsFromBackendFor' + me.request.model.prototype.modelName, totalRows);
             handleIncrementalRequest(
-            limit, offset + limit, params, incremental, newLastId);
+            limit, offset + limit, params, incremental, newLastId, background);
           } else {
             OB.UTIL.completeLoadingStep();
             OB.debug('[sdreresh-' + (incremental ? 'inc' : 'full') + '] The model ' + me.request.model.prototype.modelName + ' has loaded from ' + offset + ' to ' + (offset + limit + 1) + ' with a ' + data.length + ' records in the pagination ' + me.modelPagination);
-            OB.info('[sdreresh-' + (incremental ? 'inc' : 'full') + '] The model ' + me.request.model.prototype.modelName + ' has finished loading with a total of ' + dataLoaded + ' records. ' + (me.modelPagination === 1 ? 'There was no pagination.' : 'The number of paginations created were ' + me.modelPagination));
-            if (lastUpdated && data.length > 0) {
-              if (
-              OB.UTIL.localStorage.getItem('requestTimestamp' + me.request.model.prototype.modelName) && OB.UTIL.localStorage.getItem('requestTimestamp' + me.request.model.prototype.modelName) !== 'null') {
-                OB.UTIL.localStorage.setItem('lastUpdatedTimestamp' + me.request.model.prototype.modelName, OB.UTIL.localStorage.getItem('requestTimestamp' + me.request.model.prototype.modelName));
-              } else {
-                OB.error('[lastUpdatedTimestamp] ' + 'local storage (lastUpdatedTimestamp' + me.request.model.prototype.modelName + ') attempted to be set as null. Ignored. Current Value: ' + OB.UTIL.localStorage.getItem('lastUpdatedTimestamp' + me.request.model.prototype.modelName));
-              }
-              OB.UTIL.localStorage.removeItem('requestTimestamp' + me.request.model.prototype.modelName);
-              OB.UTIL.localStorage.setItem('recordsFromBackendFor' + me.request.model.prototype.modelName, totalRows);
-            } else {
-              if (
-              OB.UTIL.localStorage.getItem('requestTimestamp' + me.request.model.prototype.modelName) && OB.UTIL.localStorage.getItem('requestTimestamp' + me.request.model.prototype.modelName) !== 'null') {
-                OB.UTIL.localStorage.setItem('lastUpdatedTimestamp' + me.request.model.prototype.modelName, OB.UTIL.localStorage.getItem('requestTimestamp' + me.request.model.prototype.modelName));
-              }
+            if (dataLoaded > 0) {
+              OB.info('[sdreresh-' + (incremental ? 'inc' : 'full') + '] The model ' + me.request.model.prototype.modelName + ' has finished loading with a total of ' + dataLoaded + ' records. ' + (me.modelPagination === 1 ? 'There was no pagination.' : 'The number of paginations created were ' + me.modelPagination));
             }
+
+            if (background === undefined) {
+              updateModelLastUpdatedTimestamp(lastUpdated, data, totalRows);
+            }
+
             me.trigger('ready');
           }
         }
 
         if (data.exception) {
           OB.error('Error in datasource: ' + data.exception);
+          OB.DS.masterdataBackgroundModels = {};
           me.trigger('ready', 'failed');
           return;
         }
         if (me.request.model && me.request.model.prototype.online) {
           me.cache = me.cache ? me.cache.concat(data) : data;
         }
-        if (me.request.model && !me.request.model.prototype.online) {
-          if (offset === 0) {
-            OB.Dal.initCache(
-            me.request.model, data, success, handleError, incremental);
-          } else {
-            OB.Dal.insertData(
-            me.request.model, data, success, handleError, incremental, dataLoaded);
-          }
-        } else {
-          success();
-        }
+
+        params._data = data;
+        params._model = me.request.model;
+        params._lastUpdated = lastUpdated;
+        params._totalRows = totalRows;
+        functionSave(params, success, errorCallback);
       }, function (data) {
         OB.UTIL.Debug.execute(function () {
           if (data && data.exception && data.exception.message) {
@@ -624,6 +630,10 @@
             return;
           }
         });
+        OB.DS.masterdataBackgroundModels = {};
+
+        OB.info(OB.I18N.getLabel('OBMOBC_MasterdataRequestError'));
+        OB.UTIL.showI18NWarning('OBMOBC_MasterdataRequestError');
         if (
         data && data.exception && data.exception.message && data.exception.message === 'Application server is not available.') {
           me.trigger('ready', 'timeout');
@@ -635,11 +645,112 @@
       me.request.source).getServiceTimeout(5000) * 20);
     };
 
+    const doModelDataSave = function (params, success, handleError) {
+      const offset = params._offset;
+      const data = params._data;
+      const model = params._model;
+      if (model && !model.prototype.online) {
+        if (offset === 0) {
+          OB.Dal.initCache(model, data, success, handleError, incremental);
+        } else {
+          OB.Dal.insertData(
+          model, data, success, handleError, incremental, dataLoaded);
+        }
+      } else {
+        success();
+      }
+    };
+
+    const doModelDataSaveInRAM = function (params, success, handleError) {
+      const data = params._data;
+      const limit = params._limit;
+      const currentLength = data.length;
+      const backgroundLimit = OB.MobileApp.model.hasPermission('OBMOBC_BackgroundMasterdataMaxSize', true) ? OB.MobileApp.model.hasPermission('OBMOBC_BackgroundMasterdataMaxSize', true) : limit;
+      if (
+      OB.DS.masterdataBackgroundModels['totalLength'] + currentLength > backgroundLimit) {
+        OB.info('Failed to do masterdata refresh in background because exceeds the limit of data. Trying normal refresh.');
+        OB.UTIL.localStorage.setItem('neededForeGroundMasterDataRefresh');
+        OB.UTIL.refreshMasterDataForeground();
+        OB.DS.masterdataBackgroundModels = {};
+        return;
+      }
+      if (!OB.DS.masterdataBackgroundModels.hasOwnProperty(me.request.source)) {
+        OB.DS.masterdataBackgroundModels[me.request.source] = {};
+        OB.DS.masterdataBackgroundModels[me.request.source]['data'] = [];
+      }
+
+      OB.DS.masterdataBackgroundModels[me.request.source]['data'] = [...OB.DS.masterdataBackgroundModels[me.request.source]['data'], ...params._data];
+
+      OB.DS.masterdataBackgroundModels[me.request.source]['model'] = params._model;
+      OB.DS.masterdataBackgroundModels[me.request.source]['lastUpdated'] = params._lastUpdated;
+      OB.DS.masterdataBackgroundModels[me.request.source]['totalRows'] = params._totalRows;
+
+      OB.DS.masterdataBackgroundModels[me.request.source]['lastUpdated'] = me.request.lastUpdated;
+
+      if (!OB.DS.masterdataBackgroundModels.hasOwnProperty('totalLength')) {
+        OB.DS.masterdataBackgroundModels['totalLength'] = 0;
+      }
+      OB.DS.masterdataBackgroundModels['totalLength'] += currentLength;
+      success();
+    };
+
+    const doModelReadFromRAM = function (params, functionSave, errorCallback) {
+      if (
+      OB.DS.masterdataBackgroundModels[me.request.source]['data'].length === 0) {
+        me.trigger('ready');
+        return;
+      }
+      let parameters = {};
+      parameters._data = OB.DS.masterdataBackgroundModels[me.request.source]['data'];
+      parameters._model = OB.DS.masterdataBackgroundModels[me.request.source]['model'];
+      const lastUpdated_ = OB.DS.masterdataBackgroundModels[me.request.source]['lastUpdated'];
+      const totalRows = OB.DS.masterdataBackgroundModels[me.request.source]['totalRows'];
+      parameters._offset = 0; // in background all the pages are concatenated into one
+      const success = function () {
+        OB.info('[sdreresh-' + (incremental ? 'inc' : 'full') + '] The model ' + me.request.model.prototype.modelName + ' has finished saving in db with a total of ' + parameters._data.length + ' records. ');
+        updateModelLastUpdatedTimestamp(
+        lastUpdated_, parameters._data, totalRows);
+        me.trigger('ready');
+      };
+      functionSave(parameters, success, errorCallback);
+    };
+
+    handleIncrementalRequest = function (
+    limit, offset, params, incremental, lastId, background) {
+      params = params || {};
+      params._limit = limit;
+      params._offset = offset;
+      params._count = OB.UTIL.localStorage.getItem('recordsFromBackendFor' + me.request.model.prototype.modelName) ? parseInt(
+      OB.UTIL.localStorage.getItem('recordsFromBackendFor' + me.request.model.prototype.modelName), 10) : 0;
+      params._isMasterdata = true;
+      params.overrideDefaultTimeout = true;
+      params.lastId = lastId;
+      params.incremental = incremental;
+
+      if (background === undefined) {
+        // foreground
+        doModelRequest(
+        params, function (params, successCallback, errorCallback) {
+          doModelDataSave(params, successCallback, errorCallback);
+        }, handleError);
+      } else if (background === 'background-request') {
+        doModelRequest(
+        params, function (params, successCallback, errorCallback) {
+          doModelDataSaveInRAM(params, successCallback, errorCallback);
+        }, handleError);
+      } else if (background === 'background-save') {
+        doModelReadFromRAM(
+        params, function (params, successCallback, errorCallback) {
+          doModelDataSave(params, successCallback, errorCallback);
+        }, handleError);
+      }
+    };
+
     this.cache = null;
     var lastId = null; // First request don't have lastId
     handleIncrementalRequest(
     OB.MobileApp.model.hasPermission('OBMOBC_MasterdataBatchSize', true) ? OB.DEC.abs(
-    OB.MobileApp.model.hasPermission('OBMOBC_MasterdataBatchSize', true)) : 10000, 0, params, incremental, lastId);
+    OB.MobileApp.model.hasPermission('OBMOBC_MasterdataBatchSize', true)) : 10000, 0, params, incremental, lastId, background);
   };
 
   OB.DS.DataSource.prototype.find = function (filter, callback) {
diff -r f93d312ddd2f web/org.openbravo.mobile.core/source/model/ob-terminal-model.js
--- a/web/org.openbravo.mobile.core/source/model/ob-terminal-model.js	Fri Aug 30 14:39:38 2019 +0200
+++ b/web/org.openbravo.mobile.core/source/model/ob-terminal-model.js	Fri Aug 30 14:45:25 2019 +0200
@@ -1817,10 +1817,15 @@
     }
   },
 
-  loadModels: function (windows, incremental, callback) {
+  loadModels: function (windows, incremental, parentCallback, background) {
     var i, j, windowName, windowClass, windowDatasources, datasources = [],
         w, c, path;
 
+    const callback = function () {
+      OB.info('[sdrefresh] Finished loading models ' + (incremental ? 'incrementally' : 'full') + '.' + (background ? ' (' + background + ' )' : ''));
+      parentCallback();
+    };
+
     if (OB.MobileApp.model.get('loggedOffline')) {
       if (callback instanceof Function) {
         callback();
@@ -1835,7 +1840,7 @@
       });
     }
 
-    OB.info('[sdrefresh] Load models ' + (incremental ? 'incrementally' : 'full') + '.');
+    OB.info('[sdrefresh] Load models ' + (incremental ? 'incrementally' : 'full') + '.' + (background ? ' (' + background + ' )' : ''));
 
     for (i = 0; i < windows.length; i++) {
       windowClass = windows[i].windowClass;
@@ -1868,9 +1873,10 @@
 
     _.extend(datasources, Backbone.Events);
 
-    OB.debug('[sdrefresh] window: ' + windowName);
+    OB.debug('[sdrefresh] window: ' + windowName + (background ? '. (' + background + ' )' : ''));
 
-    OB.Dal.loadModels(false, datasources, null, incremental, callback);
+    OB.Dal.loadModels(
+    false, datasources, null, incremental, callback, background);
 
     this.postLoadModels();
   },
