diff --git a/src/main/java/org/olat/core/commons/services/notifications/NotificationHelper.java b/src/main/java/org/olat/core/commons/services/notifications/NotificationHelper.java
index 302fccd092a28573e63ee184aa20a0d34a798c98..9777e18509a78a201f20c97924b9247a7b55dfdb 100644
--- a/src/main/java/org/olat/core/commons/services/notifications/NotificationHelper.java
+++ b/src/main/java/org/olat/core/commons/services/notifications/NotificationHelper.java
@@ -27,14 +27,18 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
+import org.olat.core.commons.services.notifications.ui.NotificationNewsController;
 import org.olat.core.gui.translator.Translator;
 import org.olat.core.id.Identity;
 import org.olat.core.id.User;
-import org.olat.core.id.UserConstants;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.Util;
+import org.olat.core.util.cache.CacheWrapper;
+import org.olat.core.util.coordinate.CoordinatorManager;
 import org.olat.core.util.i18n.I18nManager;
+import org.olat.user.UserManager;
+import org.olat.user.propertyhandlers.UserPropertyHandler;
 
 
 /**
@@ -50,7 +54,12 @@ import org.olat.core.util.i18n.I18nManager;
 public class NotificationHelper {
 	
 	private static final OLog log = Tracing.createLoggerFor(NotificationHelper.class);
-
+	private static CacheWrapper<Long,String> userPropertiesCache;
+	
+	static {
+		userPropertiesCache = CoordinatorManager.getInstance().getCoordinator().getCacher().getCache(NotificationHelper.class.getSimpleName(), "userPropertiesCache");			
+	}
+	
 	public static Map<Subscriber, SubscriptionInfo> getSubscriptionMap(Identity identity, Locale locale, boolean showWithNewsOnly, Date compareDate) {
 		return getSubscriptionMap(identity, locale, showWithNewsOnly, compareDate, Collections.<String>emptyList());
 	}
@@ -99,15 +108,38 @@ public class NotificationHelper {
 	public static String getFormatedName(Identity ident) {
 		Translator trans;
 		User user = null;
+		String formattedName = null;
+		
 		if (ident == null) {
-			trans = Util.createPackageTranslator(NotificationHelper.class, I18nManager.getInstance().getLocaleOrDefault(null));
+			trans = Util.createPackageTranslator(NotificationNewsController.class, I18nManager.getInstance().getLocaleOrDefault(null));
+			return trans.translate("user.unknown");
 		} else {
-		 trans = Util.createPackageTranslator(NotificationHelper.class, I18nManager.getInstance().getLocaleOrDefault(
+			// Optimize: use from cache to not re-calculate user properties over and over again
+			formattedName = userPropertiesCache.get(ident.getKey());
+			if (formattedName != null) {
+				return formattedName;
+			}
+		}
+		trans = Util.createPackageTranslator(NotificationNewsController.class, I18nManager.getInstance().getLocaleOrDefault(
 				ident.getUser().getPreferences().getLanguage()));
-		 user = ident.getUser();
+		user = ident.getUser();
+		
+		if (user == null) {
+			formattedName =  trans.translate("user.unknown");
+		} else {
+			// grap user properties from context
+			List<UserPropertyHandler> propertyHandlers = UserManager.getInstance().getUserPropertyHandlersFor(NotificationHelper.class.getName(), false);
+			String[] properties = new String[propertyHandlers.size()];
+			for (int i = 0; i < propertyHandlers.size(); i++) {
+				UserPropertyHandler propHandler = propertyHandlers.get(i);
+				properties[i] = propHandler.getUserProperty(user, trans.getLocale());
+			}
+			formattedName = trans.translate("user.formatted", properties);
 		}
-		if (user == null) return trans.translate("user.unknown");
-		return user.getProperty(UserConstants.FIRSTNAME, null) + " " + user.getProperty(UserConstants.LASTNAME, null);
+		// put formatted name in cache, times out after 5 mins
+		userPropertiesCache.put(ident.getKey(), formattedName);
+		
+		return formattedName;
 	}
 
 	/**
diff --git a/src/main/java/org/olat/core/commons/services/notifications/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/core/commons/services/notifications/ui/_i18n/LocalStrings_de.properties
index 4abab2e05a6f4ae6edfe5ccc3b2232822aed5589..162ad8a41673f2c40a6a34c57afeefc54e2b5037 100644
--- a/src/main/java/org/olat/core/commons/services/notifications/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/core/commons/services/notifications/ui/_i18n/LocalStrings_de.properties
@@ -31,6 +31,7 @@ command.unsubscribe=Abbestellen
 help.hover.notif=Hilfe zu den Benachrichtigungen
 subscription.listitem.dateprefix=am {0}
 user.unknown=unbekannt
+user.formatted={0} {1}
 action.choose=Select 
 confirm.delete=Wollen Sie die abonnierte Benachrichtigung f\u00FCr die Lernressource wirklich l\u00F6schen?
 error.publisherdeleted=Die Ressource wurde gel\u00F6scht und kann nicht mehr angezeigt werden.
diff --git a/src/main/java/org/olat/core/commons/services/notifications/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/core/commons/services/notifications/ui/_i18n/LocalStrings_en.properties
index 992bee089f41e13d750009baf6548c3bf8f1cd57..bdd20c68821577a57e51dbf98d306bfa43eeed16 100644
--- a/src/main/java/org/olat/core/commons/services/notifications/ui/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/core/commons/services/notifications/ui/_i18n/LocalStrings_en.properties
@@ -31,6 +31,7 @@ command.unsubscribe=Unsubscribe
 help.hover.notif=Help regarding notifications
 subscription.listitem.dateprefix=on {0}
 user.unknown=unknown
+user.formatted={0} {1}
 action.choose=Select
 confirm.delete=Do you really want to delete this notification you subscribed to for your learning resource?
 email.nok=News could not be sent via e-mail. Please try again later or contact your support team.
diff --git a/src/main/java/org/olat/core/util/_spring/utilCorecontext.xml b/src/main/java/org/olat/core/util/_spring/utilCorecontext.xml
index 3608aef9fd72f96b7543c9a1804047662607c96f..d0f6657b5b5aa8735674fe90c0ab841314c5db05 100644
--- a/src/main/java/org/olat/core/util/_spring/utilCorecontext.xml
+++ b/src/main/java/org/olat/core/util/_spring/utilCorecontext.xml
@@ -182,53 +182,48 @@
 		</property>
 	</bean>
 
+	<!-- * * * * * * *  -->
+	<!--  DEPRECATED!! use src/main/resources/infinispan-config.xml instead !! -->
+	<!--  Configure caches directly in infinispan files, not here. timeToLive not supported anymore -->
+	<!-- * * * * * * *  -->
+
 	<!-- Cache beans -->
 	<bean id="org.olat.login.LoginModule_blockafterfailedattempts" class="org.olat.core.util.cache.CacheConfig" >
-		<property name="timeToLive" value="300" />
 		<property name="timeToIdle" value="0" />
 		<property name="maxElementsInMemory" value="1000" />
 	</bean>
 	<bean id="org.olat.ims.qti.process.QTIHelper_QTI_xml_Documents" class="org.olat.core.util.cache.CacheConfig">
-		<property name="timeToLive" value="3600" />
 		<property name="timeToIdle" value="1800" />
 		<!-- qti files may be large -->
 		<property name="maxElementsInMemory" value="20" />
 	</bean>					
 	<bean id="org.olat.modules.wiki.WikiManager_wiki" class="org.olat.core.util.cache.CacheConfig">
-		<property name="timeToLive" value="14400" />
 		<property name="timeToIdle" value="1800" />
 		<property name="maxElementsInMemory" value="50" />								
 	</bean>
 	<bean id="org.olat.commons.calendar.ICalFileCalendarManager_calendar" class="org.olat.core.util.cache.CacheConfig">
-		<property name="timeToLive" value="3600" />
 		<property name="timeToIdle" value="3600" />
 		<property name="maxElementsInMemory" value="50" />								
 	</bean>
 	<bean id="org.olat.course.CourseFactory_courses" class="org.olat.core.util.cache.CacheConfig">
-		<property name="timeToLive" value="0" />
 		<property name="timeToIdle" value="3600" />
 		<property name="maxElementsInMemory" value="${course.cache.elements}" />								
 	</bean>
 	<bean id="org.olat.collaboration.CollaborationToolsFactory_tools" class="org.olat.core.util.cache.CacheConfig">
-			<property name="timeToLive" value="3600" />
 			<property name="timeToIdle" value="1800" />
 			<property name="maxElementsInMemory" value="5000" />								
 	</bean>
 	<bean id="org.olat.core.modules.glossary.GlossaryItemManager_glossary" class="org.olat.core.util.cache.CacheConfig">
-			<property name="timeToLive" value="7200" />
 			<property name="timeToIdle" value="1800" />
 			<property name="maxElementsInMemory" value="50" />								
 	</bean>
 	<bean id="org.olat.course.nodes.projectbroker.service.ProjectBrokerManagerImpl_pb" class="org.olat.core.util.cache.CacheConfig">
-		<property name="timeToLive" value="3600" />
 		<property name="timeToIdle" value="3600" />
 		<property name="maxElementsInMemory" value="50" />								
 	</bean>
 	<bean id="org.olat.course.assessment.NewCachePersistingAssessmentManager" class="org.olat.core.util.cache.CacheConfig">
-		<property name="timeToLive" value="0" />
 		<property name="timeToIdle" value="60" />
 		<property name="maxElementsInMemory" value="20000" />							
 	</bean>
 	
-	
 </beans>
diff --git a/src/main/java/org/olat/core/util/cache/CacheConfig.java b/src/main/java/org/olat/core/util/cache/CacheConfig.java
index ba7ab132d3b03c8f11f85d8d055046f5ee1a17fb..2785d490235e22795884ba9deb11fb5fcf3bd671 100644
--- a/src/main/java/org/olat/core/util/cache/CacheConfig.java
+++ b/src/main/java/org/olat/core/util/cache/CacheConfig.java
@@ -38,6 +38,12 @@ package org.olat.core.util.cache;
  * Initial Date:  19.10.2007 <br>
  * @author Felix Jost, http://www.goodsolutions.ch
  */
+
+/* * * * * * * * 
+	DEPRECATED!! use src/main/resources/infinispan-config.xml instead !!
+	Configure caches directly in infinispan files, not here. timeToLive not supported anymore
+ * * * * * * * */
+@Deprecated
 public class CacheConfig {
 	
 	private int maxElementsInMemory = 10000;
@@ -46,7 +52,6 @@ public class CacheConfig {
 	private boolean diskPersistent = false;
 	private String diskStorePath;
 	private boolean eternal = false;
-	private int timeToLive = 120;
 	private int timeToIdle = 120;
 	private int diskExpiryThreadIntervalSeconds = 120;
 
@@ -112,19 +117,6 @@ public class CacheConfig {
 		this.eternal = eternal;
 	}
 	
-	public int getTimeToLive() {
-		return timeToLive;
-	}
-
-	/**
-	 * Set t he time in seconds to live for an element before it expires,
-	 * i.e. the maximum time between creation time and when an element expires.
-	 * It is only used if the element is not eternal. Default is 120 seconds.
-	 */
-	public void setTimeToLive(int timeToLive) {
-		this.timeToLive = timeToLive;
-	}
-	
 	public int getTimeToIdle() {
 		return timeToIdle;
 	}
diff --git a/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml b/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml
index 2d3b31c3e2207b4e70cb7f4a78022b7438642b2a..aea771b205228092be58fad1bcadec65091d9e23 100644
--- a/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml
+++ b/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml
@@ -890,7 +890,7 @@
 					</bean>
 				</entry>
 				
-				<!-- fxdiff: FXOLAT-227 user properties used for group-mail-function -->
+				<!-- User properties used for group-mail-function -->
 				<entry key="org.olat.group.ui.run.BusinessGroupSendToChooserForm">
 					<bean class="org.olat.user.propertyhandlers.UserPropertyUsageContext">
 						<property name="description" value=" " />
@@ -904,7 +904,7 @@
 				</entry>	
 				
 				
-				<!-- fxdiff: FXOLAT-93 user properties used in Businesscards (mitgleidersite) -->
+				<!-- User properties used in Businesscards (mitgleidersite) -->
 				<entry key="com.frentix.olat.user.UserBusinessCardController">
 					<bean class="org.olat.user.propertyhandlers.UserPropertyUsageContext">
 						<property name="description" value="BusinessCards in Membersite" />
@@ -920,7 +920,7 @@
 					</bean>
 				</entry>	
 				
-				<!-- fxdiff: FXOLAT-356 user properties used for the mail-footer line together with i18nkey: "footer.with.userdata" -->
+				<!-- User properties used for the mail-footer line together with i18nkey: "footer.with.userdata" -->
 				<entry key="org.olat.core.util.mail.MailHelper">
 					<bean class="org.olat.user.propertyhandlers.UserPropertyUsageContext">
 						<property name="description" value="Properties used for the mail footer for emails sent from this system. Configure i18nkey: 'footer.with.userdata' accordingly. " />
@@ -933,6 +933,19 @@
 						</property>						
 					</bean>
 				</entry>			
+
+				<!-- User properties used for the mail-notifications line together with i18nkey: "user.formatted" -->
+				<entry key="org.olat.core.commons.services.notifications.NotificationHelper">
+					<bean class="org.olat.user.propertyhandlers.UserPropertyUsageContext">
+						<property name="description" value="Properties used for the notification emails sent from this system. Configure i18nkey: 'user.formatted' accordingly. " />
+						<property name="propertyHandlers">
+							<list>
+								<ref bean="userPropertyFirstName" />
+								<ref bean="userPropertyLastName" />	
+							</list>
+						</property>						
+					</bean>
+				</entry>			
 				
 				<!--
 					Default configuration in case nothing else matches.
diff --git a/src/main/resources/infinispan-config.xml b/src/main/resources/infinispan-config.xml
index d1f1d3e1bdc5fbf4397ffe299c27a0e4b2c91956..118787fb946ef48dd7372f64f07b5ea535012ea3 100644
--- a/src/main/resources/infinispan-config.xml
+++ b/src/main/resources/infinispan-config.xml
@@ -73,7 +73,13 @@
 		<expiration maxIdle="300000" lifespan="300000" wakeUpInterval="5000"/>
 		<transaction transactionMode="NON_TRANSACTIONAL" />
 	</namedCache>
-	
+
+	<namedCache name="NotificationHelper@userPropertiesCache">
+		<locking isolationLevel="READ_COMMITTED" concurrencyLevel="1000" lockAcquisitionTimeout="15000" useLockStriping="false"/>
+		<eviction maxEntries="2000" strategy="LRU"/>
+		<expiration maxIdle="120000" wakeUpInterval="15000"/>
+		<transaction transactionMode="NON_TRANSACTIONAL" />
+	</namedCache>
 
 	<!-- 
 	Hibernate cache