diff --git a/src/zabbix_server/preprocessor/preproc_manager.c b/src/zabbix_server/preprocessor/preproc_manager.c
index b610200690..3ec80bf928 100644
--- a/src/zabbix_server/preprocessor/preproc_manager.c
+++ b/src/zabbix_server/preprocessor/preproc_manager.c
@@ -106,9 +106,17 @@ typedef struct
 
 	zbx_list_t			direct_queue;	/* Queue of external requests that have to be */
 							/* forwarded to workers for preprocessing.    */
+	zbx_hashset_t			resultpool;	/* result pool to be shared between master and dependent items */
 }
 zbx_preprocessing_manager_t;
 
+typedef struct
+{
+	void	*result;
+	int	refcount;
+}
+zbx_resultpool_t;
+
 static void	preprocessor_enqueue_dependent(zbx_preprocessing_manager_t *manager,
 		zbx_preproc_item_value_t *value, zbx_list_item_t *master);
 
@@ -338,6 +346,37 @@ out:
 	return task;
 }
 
+static void	preproc_item_result_prepare(zbx_hashset_t *resultpool, const AGENT_RESULT *result)
+{
+	zbx_resultpool_t	*result_ptr, result_local;
+
+	if (NULL == (result_ptr = (zbx_resultpool_t *)zbx_hashset_search(resultpool, &result)))
+	{
+		result_local.result = (void *)result;
+		result_local.refcount = 1;
+
+		zbx_hashset_insert(resultpool, &result_local, sizeof(result_local));
+		return;
+	}
+
+	result_ptr->refcount++;
+}
+
+static void	preproc_item_result_free(zbx_hashset_t *resultpool, zbx_preproc_item_value_t *value)
+{
+	zbx_resultpool_t	*result_ptr;
+
+	if (NULL != (result_ptr = (zbx_resultpool_t *)zbx_hashset_search(resultpool, &value->result)) &&
+			0 == --(result_ptr->refcount))
+	{
+		free_result(value->result);
+		zbx_free(value->result);
+		zbx_hashset_remove_direct(resultpool, result_ptr);
+	}
+	else
+		value->result = NULL;
+}
+
 /******************************************************************************
  *                                                                            *
  * Function: preprocessor_get_worker_by_client                                *
@@ -440,14 +479,13 @@ static void	preprocessor_assign_tasks(zbx_preprocessing_manager_t *manager)
  * Parameters: value - [IN] value to be freed                                 *
  *                                                                            *
  ******************************************************************************/
-static void	preproc_item_value_clear(zbx_preproc_item_value_t *value)
+static void	preproc_item_value_clear(zbx_hashset_t *alertpool, zbx_preproc_item_value_t *value)
 {
 	zbx_free(value->error);
+
 	if (NULL != value->result)
-	{
-		free_result(value->result);
-		zbx_free(value->result);
-	}
+		preproc_item_result_free(alertpool, value);
+
 	zbx_free(value->ts);
 }
 
@@ -460,9 +498,9 @@ static void	preproc_item_value_clear(zbx_preproc_item_value_t *value)
  * Parameters: request - [IN] request data to be freed                        *
  *                                                                            *
  ******************************************************************************/
-static void	preprocessor_free_request(zbx_preprocessing_request_t *request)
+static void	preprocessor_free_request(zbx_hashset_t *alertpool, zbx_preprocessing_request_t *request)
 {
-	preproc_item_value_clear(&request->value);
+	preproc_item_value_clear(alertpool, &request->value);
 	request_free_steps(request);
 	zbx_free(request);
 }
@@ -527,7 +565,7 @@ static void	preprocessing_flush_queue(zbx_preprocessing_manager_t *manager)
 			break;
 
 		preprocessor_flush_value(&request->value);
-		preprocessor_free_request(request);
+		preprocessor_free_request(&manager->resultpool, request);
 
 		if (SUCCEED == zbx_list_iterator_equal(&iterator, &manager->priority_tail))
 			zbx_list_iterator_clear(&manager->priority_tail);
@@ -617,33 +655,6 @@ static void	preprocessor_copy_value(zbx_preproc_item_value_t *target, zbx_prepro
 		target->ts = (zbx_timespec_t *)zbx_malloc(NULL, sizeof(zbx_timespec_t));
 		memcpy(target->ts, source->ts, sizeof(zbx_timespec_t));
 	}
-
-	if (NULL != source->result)
-	{
-		target->result = (AGENT_RESULT *)zbx_malloc(NULL, sizeof(AGENT_RESULT));
-		memcpy(target->result, source->result, sizeof(AGENT_RESULT));
-
-		if (NULL != source->result->str)
-			target->result->str = zbx_strdup(NULL, source->result->str);
-
-		if (NULL != source->result->text)
-			target->result->text = zbx_strdup(NULL, source->result->text);
-
-		if (NULL != source->result->msg)
-			target->result->msg = zbx_strdup(NULL, source->result->msg);
-
-		if (NULL != source->result->log)
-		{
-			target->result->log = (zbx_log_t *)zbx_malloc(NULL, sizeof(zbx_log_t));
-			memcpy(target->result->log, source->result->log, sizeof(zbx_log_t));
-
-			if (NULL != source->result->log->value)
-				target->result->log->value = zbx_strdup(NULL, source->result->log->value);
-
-			if (NULL != source->result->log->source)
-				target->result->log->source = zbx_strdup(NULL, source->result->log->source);
-		}
-	}
 }
 
 /******************************************************************************
@@ -688,7 +699,7 @@ static void	preprocessor_enqueue(zbx_preprocessing_manager_t *manager, zbx_prepr
 			preprocessor_flush_value(value);
 			manager->processed_num++;
 			preprocessor_enqueue_dependent(manager, value, NULL);
-			preproc_item_value_clear(value);
+			preproc_item_value_clear(&manager->resultpool, value);
 
 			goto out;
 		}
@@ -786,8 +797,16 @@ static void	preprocessor_enqueue_dependent(zbx_preprocessing_manager_t *manager,
 		if (NULL != (item = (zbx_preproc_item_t *)zbx_hashset_search(&manager->item_config, &item_local)) &&
 				0 != item->dep_itemids_num)
 		{
+			zbx_resultpool_t	*result_ptr;
+
+			/* result is shared between all dependent items, new result will be created after preprocessing */
+			result_ptr = (zbx_resultpool_t *)zbx_hashset_search(&manager->resultpool, &source_value->result);
+
 			for (i = item->dep_itemids_num - 1; i >= 0; i--)
 			{
+				if (NULL != result_ptr)
+					result_ptr->refcount++;
+
 				preprocessor_copy_value(&value, source_value);
 				value.itemid = item->dep_itemids[i].first;
 				value.item_flags = item->dep_itemids[i].second;
@@ -824,6 +843,8 @@ static void	preprocessor_add_request(zbx_preprocessing_manager_t *manager, zbx_i
 	while (offset < message->size)
 	{
 		offset += zbx_preprocessor_unpack_value(&value, message->data + offset);
+		if (NULL != value.result)
+			preproc_item_result_prepare(&manager->resultpool, value.result);
 		preprocessor_enqueue(manager, &value, NULL);
 	}
 
@@ -873,7 +894,8 @@ static void	preprocessor_add_test_request(zbx_preprocessing_manager_t *manager,
  *             error   - [IN] error message (if any)                          *
  *                                                                            *
  ******************************************************************************/
-static int	preprocessor_set_variant_result(zbx_preprocessing_request_t *request, zbx_variant_t *value, char *error)
+static int	preprocessor_set_variant_result(zbx_hashset_t *resultpool, zbx_preprocessing_request_t *request,
+		zbx_variant_t *value, char *error)
 {
 	int		type, ret = FAIL;
 	zbx_log_t	*log;
@@ -890,12 +912,10 @@ static int	preprocessor_set_variant_result(zbx_preprocessing_request_t *request,
 
 	if (ZBX_VARIANT_NONE == value->type)
 	{
-		UNSET_UI64_RESULT(request->value.result);
-		UNSET_DBL_RESULT(request->value.result);
-		UNSET_STR_RESULT(request->value.result);
-		UNSET_TEXT_RESULT(request->value.result);
-		UNSET_LOG_RESULT(request->value.result);
-		UNSET_MSG_RESULT(request->value.result);
+		preproc_item_result_free(resultpool, &request->value);
+		request->value.result = zbx_malloc(NULL, sizeof(AGENT_RESULT));
+		init_result(request->value.result);
+		preproc_item_result_prepare(resultpool, request->value.result);
 		ret = FAIL;
 
 		goto out;
@@ -916,43 +936,45 @@ static int	preprocessor_set_variant_result(zbx_preprocessing_request_t *request,
 
 	if (FAIL != (ret = zbx_variant_convert(value, type)))
 	{
+		/* old result is shared between dependent and master items, it cannot be modified, create new result */
+		AGENT_RESULT *result = zbx_malloc(NULL, sizeof(AGENT_RESULT));
+
+		init_result(result);
+
 		switch (request->value_type)
 		{
 			case ITEM_VALUE_TYPE_FLOAT:
-				UNSET_RESULT_EXCLUDING(request->value.result, AR_DOUBLE);
-				SET_DBL_RESULT(request->value.result, value->data.dbl);
+				SET_DBL_RESULT(result, value->data.dbl);
 				break;
 			case ITEM_VALUE_TYPE_STR:
-				UNSET_RESULT_EXCLUDING(request->value.result, AR_STRING);
-				UNSET_STR_RESULT(request->value.result);
-				SET_STR_RESULT(request->value.result, value->data.str);
+				SET_STR_RESULT(result, value->data.str);
 				break;
 			case ITEM_VALUE_TYPE_LOG:
-				UNSET_RESULT_EXCLUDING(request->value.result, AR_LOG);
+				log = (zbx_log_t *)zbx_malloc(NULL, sizeof(zbx_log_t));
+
 				if (ISSET_LOG(request->value.result))
 				{
-					log = GET_LOG_RESULT(request->value.result);
-					zbx_free(log->value);
+					*log = *request->value.result->log;
+					if (NULL != log->source)
+						log->source = zbx_strdup(NULL, log->source);
 				}
 				else
-				{
-					log = (zbx_log_t *)zbx_malloc(NULL, sizeof(zbx_log_t));
 					memset(log, 0, sizeof(zbx_log_t));
-					SET_LOG_RESULT(request->value.result, log);
-				}
+
 				log->value = value->data.str;
+				SET_LOG_RESULT(result, log);
 				break;
 			case ITEM_VALUE_TYPE_UINT64:
-				UNSET_RESULT_EXCLUDING(request->value.result, AR_UINT64);
-				SET_UI64_RESULT(request->value.result, value->data.ui64);
+				SET_UI64_RESULT(result, value->data.ui64);
 				break;
 			case ITEM_VALUE_TYPE_TEXT:
-				UNSET_RESULT_EXCLUDING(request->value.result, AR_TEXT);
-				UNSET_TEXT_RESULT(request->value.result);
-				SET_TEXT_RESULT(request->value.result, value->data.str);
+				SET_TEXT_RESULT(result, value->data.str);
 				break;
 		}
 
+		preproc_item_result_free(resultpool, &request->value);
+		preproc_item_result_prepare(resultpool, (request->value.result = result));
+
 		zbx_variant_set_none(value);
 	}
 	else
@@ -1033,7 +1055,7 @@ static void	preprocessor_add_result(zbx_preprocessing_manager_t *manager, zbx_ip
 
 	preprocessor_set_request_state_done(manager, request, worker->task);
 
-	if (FAIL != preprocessor_set_variant_result(request, &value, error))
+	if (FAIL != preprocessor_set_variant_result(&manager->resultpool, request, &value, error))
 		preprocessor_enqueue_dependent(manager, &request->value, worker->task);
 
 	worker->task = NULL;
@@ -1112,6 +1134,7 @@ static void	preprocessor_init_manager(zbx_preprocessing_manager_t *manager)
 	zbx_hashset_create(&manager->linked_items, 0, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
 	zbx_hashset_create(&manager->history_cache, 1000, ZBX_DEFAULT_UINT64_HASH_FUNC,
 			ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+	zbx_hashset_create(&manager->resultpool, 1000, ZBX_DEFAULT_PTR_HASH_FUNC, ZBX_DEFAULT_PTR_COMPARE_FUNC);
 
 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
 }
@@ -1182,13 +1205,14 @@ static void	preprocessor_destroy_manager(zbx_preprocessing_manager_t *manager)
 	zbx_list_destroy(&manager->direct_queue);
 
 	while (SUCCEED == zbx_list_pop(&manager->queue, (void **)&request))
-		preprocessor_free_request(request);
+		preprocessor_free_request(&manager->resultpool, request);
 
 	zbx_list_destroy(&manager->queue);
 
 	zbx_hashset_destroy(&manager->item_config);
 	zbx_hashset_destroy(&manager->linked_items);
 	zbx_hashset_destroy(&manager->history_cache);
+	zbx_hashset_destroy(&manager->resultpool);
 }
 
 ZBX_THREAD_ENTRY(preprocessing_manager_thread, args)
