diff -r a6fc8e87a380 src/org/openbravo/mobile/core/login/LabelsChangedEvent.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openbravo/mobile/core/login/LabelsChangedEvent.java	Thu Nov 21 12:12:03 2019 +0100
@@ -0,0 +1,49 @@
+package org.openbravo.mobile.core.login;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Observes;
+
+import org.openbravo.base.model.Entity;
+import org.openbravo.base.model.ModelProvider;
+import org.openbravo.client.kernel.event.EntityDeleteEvent;
+import org.openbravo.client.kernel.event.EntityNewEvent;
+import org.openbravo.client.kernel.event.EntityPersistenceEventObserver;
+import org.openbravo.client.kernel.event.EntityUpdateEvent;
+import org.openbravo.model.ad.module.Module;
+import org.openbravo.model.ad.ui.Message;
+import org.openbravo.model.ad.ui.MessageTrl;
+
+@ApplicationScoped
+public class LabelsChangedEvent extends EntityPersistenceEventObserver {
+
+  private static Entity[] entities = { ModelProvider.getInstance().getEntity(Message.ENTITY_NAME),
+      ModelProvider.getInstance().getEntity(MessageTrl.ENTITY_NAME),
+      ModelProvider.getInstance().getEntity(Module.ENTITY_NAME) };
+
+  @Override
+  protected Entity[] getObservedEntities() {
+    return entities;
+  }
+
+  public void onUpdate(@Observes EntityUpdateEvent event) {
+    if (!isValidEvent(event)) {
+      return;
+    }
+    LabelsComponent.clearMaps();
+  }
+
+  public void onSave(@Observes EntityNewEvent event) {
+    if (!isValidEvent(event)) {
+      return;
+    }
+    LabelsComponent.clearMaps();
+  }
+
+  public void onDelete(@Observes EntityDeleteEvent event) {
+    if (!isValidEvent(event)) {
+      return;
+    }
+    LabelsComponent.clearMaps();
+  }
+
+}
diff -r a6fc8e87a380 src/org/openbravo/mobile/core/login/LabelsComponent.java
--- a/src/org/openbravo/mobile/core/login/LabelsComponent.java	Tue Nov 19 16:10:46 2019 +0100
+++ b/src/org/openbravo/mobile/core/login/LabelsComponent.java	Thu Nov 21 12:12:03 2019 +0100
@@ -10,6 +10,8 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -19,6 +21,7 @@
 import org.openbravo.dal.core.OBContext;
 import org.openbravo.dal.service.OBCriteria;
 import org.openbravo.dal.service.OBDal;
+import org.openbravo.dal.service.OBQuery;
 import org.openbravo.mobile.core.MobileCoreConstants;
 import org.openbravo.model.ad.module.Module;
 import org.openbravo.model.ad.module.ModuleDependency;
@@ -28,20 +31,13 @@
 
 public class LabelsComponent {
   private static final Logger log = LogManager.getLogger();
+  
+  private static final ConcurrentMap<String, JSONObject> labelsMap = new ConcurrentHashMap<String, JSONObject>();
+  private static final ConcurrentMap<String, JSONObject> listsMap = new ConcurrentHashMap<String, JSONObject>();
+  private static Boolean inDevelopment;
 
   public static JSONObject getLabels(String languageId, String moduleId) {
     try {
-      String modules = getMobileAppDependantModuleIds(moduleId);
-      JSONObject labels = new JSONObject();
-      String hqlLabel = "select message.searchKey, message.messageText "//
-          + "from ADMessage message " //
-          + "where module.id in " + modules;
-      Query<Object[]> qryLabel = OBDal.getInstance()
-          .getSession()
-          .createQuery(hqlLabel, Object[].class);
-      for (Object[] qryLabelObjectItem : qryLabel.list()) {
-        labels.put(qryLabelObjectItem[0].toString(), qryLabelObjectItem[1].toString());
-      }
 
       Language currentLanguage = null;
       Language computedLanguage = null;
@@ -54,6 +50,28 @@
       String langId = currentLanguage != null ? currentLanguage.getId() : computedLanguage.getId();
       String langSk = currentLanguage != null ? currentLanguage.getLanguage()
           : computedLanguage.getLanguage();
+
+      String modules = getMobileAppDependantModuleIds(moduleId);
+
+      if (inDevelopment == null) {
+        inDevelopment = checkModulesInDevelopment(modules);
+      }
+
+      if (!inDevelopment && labelsMap.containsKey(moduleId + langId)) {
+        return labelsMap.get(moduleId + langId);
+      }
+      
+      JSONObject labels = new JSONObject();
+      String hqlLabel = "select message.searchKey, message.messageText "//
+          + "from ADMessage message " //
+          + "where module.id in " + modules;
+      Query<Object[]> qryLabel = OBDal.getInstance()
+          .getSession()
+          .createQuery(hqlLabel, Object[].class);
+      for (Object[] qryLabelObjectItem : qryLabel.list()) {
+        labels.put(qryLabelObjectItem[0].toString(), qryLabelObjectItem[1].toString());
+      }
+
       String hqlTrlLabels = "select trl.message.searchKey, trl.messageText from ADMessageTrl trl where trl.message.module.id in "
           + modules + " and trl.language.id='" + langId + "'";
       Query<Object[]> qryTrlLabels = OBDal.getInstance()
@@ -69,7 +87,9 @@
 
       labels.put("languageSk", langSk);
       labels.put("languageId", langId);
-      labels.put("userId", OBContext.getOBContext().getUser().getId());
+      if (!inDevelopment) {
+        labelsMap.putIfAbsent(moduleId + langId, labels);
+      }
       return labels;
     } catch (Exception e) {
       log.error("There was an exception while generating the Mobile labels", e);
@@ -77,12 +97,28 @@
     }
   }
 
+  private static Boolean checkModulesInDevelopment(String modules) {
+    String criteria = Module.PROPERTY_INDEVELOPMENT + " = 'Y' AND " + Module.PROPERTY_ID + " IN " + modules;
+    OBQuery<Module> modulesInDevQuery = OBDal.getInstance().createQuery(Module.class, criteria);
+    return !modulesInDevQuery.list().isEmpty();
+  }
+
   public static JSONObject getLists(String languageId, String moduleId) {
     try {
-      String modules = getMobileAppDependantModuleIds(moduleId);
-      JSONObject lists = new JSONObject();
       String computedLanguage = getComputedLanguage();
       String langId = languageId != null ? languageId : computedLanguage;
+
+      String modules = getMobileAppDependantModuleIds(moduleId);
+
+      if (inDevelopment == null) {
+        inDevelopment = checkModulesInDevelopment(modules);
+      }
+
+      if (!inDevelopment && listsMap.containsKey(moduleId + langId)) {
+        return listsMap.get(moduleId + langId);
+      }
+      
+      JSONObject lists = new JSONObject();
       String hqlLists = "select list.reference.id, list.searchKey as id, coalesce("
           + " (select trl.name from list.aDListTrlList trl where trl.language.id = '" + langId
           + "'), list.name) as name " + "from ADList list " //
@@ -105,6 +141,9 @@
         listValues.put(item);
       }
       lists.put("languageId", computedLanguage);
+      if (!inDevelopment) {
+        listsMap.putIfAbsent(moduleId + langId,lists);
+      }
       return lists;
     } catch (Exception e) {
       log.error("There was an exception while generating the Mobile reference list", e);
@@ -165,4 +204,9 @@
     }
     return computedLanguage;
   }
+  
+  public static void clearMaps() {
+    labelsMap.clear();
+    listsMap.clear();
+  }
 }
diff -r a6fc8e87a380 web/org.openbravo.mobile.core/source/model/ob-terminal-model.js
--- a/web/org.openbravo.mobile.core/source/model/ob-terminal-model.js	Tue Nov 19 16:10:46 2019 +0100
+++ b/web/org.openbravo.mobile.core/source/model/ob-terminal-model.js	Thu Nov 21 12:12:03 2019 +0100
@@ -1551,7 +1551,7 @@
             // The labels will only be saved in the localStorage if they come from an active session
             // We do this to prevent the labels loaded in the login page from being stored here and overwritting
             // the labels in the correct language (see issue 23613)
-            OB.UTIL.localStorage.setItem('languageForUser_' + inResponse.labels.userId, inResponse.labels.languageId);
+            OB.UTIL.localStorage.setItem('languageForUser_' + OB.MobileApp.model.get('orgUserId'), inResponse.labels.languageId);
             OB.UTIL.localStorage.setItem('I18NLabels', JSON.stringify(OB.I18N.labels));
             OB.UTIL.localStorage.setItem('I18NLabels_' + inResponse.labels.languageId, JSON.stringify(OB.I18N.labels));
           }
