diff --git a/daemon/call.c b/daemon/call.c
index 3760086ba..f74ce2152 100644
--- a/daemon/call.c
+++ b/daemon/call.c
@@ -2966,12 +2966,7 @@ out:
 void add_total_calls_duration_in_interval(struct timeval *interval_tv) {
 	struct timeval ongoing_calls_dur = add_ongoing_calls_dur_in_interval(
 			&rtpe_latest_graphite_interval_start, interval_tv);
-
-	mutex_lock(&rtpe_totalstats_interval.total_calls_duration_lock);
-	timeval_add(&rtpe_totalstats_interval.total_calls_duration_interval,
-			&rtpe_totalstats_interval.total_calls_duration_interval,
-			&ongoing_calls_dur);
-	mutex_unlock(&rtpe_totalstats_interval.total_calls_duration_lock);
+	RTPE_STATS_ADD(total_calls_duration, timeval_us(&ongoing_calls_dur));
 }
 
 static struct timeval add_ongoing_calls_dur_in_interval(struct timeval *interval_start,
diff --git a/daemon/graphite.c b/daemon/graphite.c
index 3023b9fb0..eaaf94d9d 100644
--- a/daemon/graphite.c
+++ b/daemon/graphite.c
@@ -32,7 +32,6 @@ static time_t next_run;
 // HEAD: static time_t rtpe_now, next_run;
 static char* graphite_prefix = NULL;
 static struct timeval graphite_interval_tv;
-static struct totalstats graphite_stats;
 
 void set_graphite_interval_tv(struct timeval *tv) {
 	graphite_interval_tv = *tv;
@@ -72,24 +71,13 @@ static int connect_to_graphite_server(const endpoint_t *graphite_ep) {
 	return 0;
 }
 
-GString *print_graphite_data(struct totalstats *sent_data) {
+GString *print_graphite_data(void) {
 
 	long long time_diff_us = timeval_diff(&rtpe_now, &rtpe_latest_graphite_interval_start);
 	stats_counters_ax_calc_avg(&rtpe_stats_graphite, time_diff_us, &rtpe_stats_graphite_interval);
 	stats_counters_min_max_reset(&rtpe_stats_graphite_min_max, &rtpe_stats_graphite_min_max_interval);
 	stats_gauge_calc_avg_reset(&rtpe_stats_gauge_graphite_min_max_interval, &rtpe_stats_gauge_graphite_min_max);
 
-	struct totalstats *ts = sent_data;
-
-	/* atomically copy values to stack and reset to zero */
-
-	mutex_lock(&rtpe_totalstats_interval.total_calls_duration_lock);
-	ts->total_calls_duration_interval = rtpe_totalstats_interval.total_calls_duration_interval;
-	rtpe_totalstats_interval.total_calls_duration_interval.tv_sec = 0;
-	rtpe_totalstats_interval.total_calls_duration_interval.tv_usec = 0;
-	//ZERO(rtpe_totalstats_interval.total_calls_duration_interval);
-	mutex_unlock(&rtpe_totalstats_interval.total_calls_duration_lock);
-
 	GString *graph_str = g_string_new("");
 
 #define GPF(fmt, ...) \
@@ -106,7 +94,7 @@ GString *print_graphite_data(struct totalstats *sent_data) {
 				(double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.avg.ng_command_times[i]) / 1000000.0);
 	}
 
-	GPF("call_dur %llu.%06llu",(unsigned long long)ts->total_calls_duration_interval.tv_sec,(unsigned long long)ts->total_calls_duration_interval.tv_usec);
+	GPF("call_dur %.6f", (double) atomic64_get_na(&rtpe_stats_graphite_interval.total_calls_duration) / 1000000.0);
 	struct timeval avg_duration;
 	uint64_t managed_sess = atomic64_get_na(&rtpe_stats_graphite_interval.managed_sess);
 	if (managed_sess)
@@ -181,11 +169,10 @@ GString *print_graphite_data(struct totalstats *sent_data) {
 	g_list_free(chains);
 
 
-	ilog(LOG_DEBUG, "min_sessions:%llu max_sessions:%llu, call_dur_per_interval:%llu.%06llu at time %llu\n",
+	ilog(LOG_DEBUG, "min_sessions:%llu max_sessions:%llu, call_dur_per_interval:%.6f at time %llu\n",
 			(unsigned long long) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.min.total_sessions),
 			(unsigned long long) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.max.total_sessions),
-			(unsigned long long ) ts->total_calls_duration_interval.tv_sec,
-			(unsigned long long ) ts->total_calls_duration_interval.tv_usec,
+			(double) atomic64_get_na(&rtpe_stats_graphite_interval.total_calls_duration) / 1000000.0,
 			(unsigned long long ) rtpe_now.tv_sec);
 
 	for (int i = 0; i < NGC_COUNT; i++) {
@@ -199,14 +186,14 @@ GString *print_graphite_data(struct totalstats *sent_data) {
 	return graph_str;
 }
 
-static int send_graphite_data(struct totalstats *sent_data) {
+static int send_graphite_data(void) {
 
 	if (graphite_sock.fd < 0) {
 		ilog(LOG_ERROR,"Graphite socket is not connected.");
 		return -1;
 	}
 
-	GString *graph_str = print_graphite_data(sent_data);
+	GString *graph_str = print_graphite_data();
 
 	size_t sent = 0;
 	int blockings = 10; // let it block that many times
@@ -238,11 +225,6 @@ error:
 	return -1;
 }
 
-static inline void copy_with_lock(struct totalstats *ts_dst, struct totalstats *ts_src, mutex_t *ts_lock) {
-	mutex_lock(ts_lock);
-	memcpy(ts_dst, ts_src, sizeof(struct totalstats));
-	mutex_unlock(ts_lock);
-}
 
 static void graphite_loop_run(endpoint_t *graphite_ep, int seconds) {
 
@@ -304,15 +286,13 @@ static void graphite_loop_run(endpoint_t *graphite_ep, int seconds) {
 		add_total_calls_duration_in_interval(&graphite_interval_tv);
 
 		gettimeofday(&rtpe_now, NULL);
-		rc = send_graphite_data(&graphite_stats);
+		rc = send_graphite_data();
 		rtpe_latest_graphite_interval_start = rtpe_now;
 		if (rc < 0) {
 			ilog(LOG_ERROR,"Sending graphite data failed.");
 			close_socket(&graphite_sock);
 			connection_state = STATE_DISCONNECTED;
 		}
-
-		copy_with_lock(&rtpe_totalstats_lastinterval, &graphite_stats, &rtpe_totalstats_lastinterval_lock);
 	}
 
 }
diff --git a/daemon/statistics.c b/daemon/statistics.c
index becf18317..8721a0573 100644
--- a/daemon/statistics.c
+++ b/daemon/statistics.c
@@ -5,11 +5,6 @@
 #include "control_ng.h"
 
 
-struct totalstats       rtpe_totalstats;
-struct totalstats       rtpe_totalstats_interval;
-mutex_t		       	rtpe_totalstats_lastinterval_lock;
-struct totalstats       rtpe_totalstats_lastinterval;
-
 struct timeval rtpe_started;
 
 
@@ -17,48 +12,6 @@ mutex_t rtpe_codec_stats_lock;
 GHashTable *rtpe_codec_stats;
 
 
-static void timeval_totalstats_call_duration_add(struct totalstats *s,
-		struct timeval *call_start, struct timeval *call_stop,
-		struct timeval *interval_start, int interval_dur_s) {
-
-	/* work with graphite interval start val which might be changed elsewhere in the code*/
-	struct timeval real_iv_start = {0,};
-	struct timeval call_duration;
-	struct timeval *call_start_in_iv = call_start;
-
-	if (interval_start) {
-		real_iv_start = *interval_start;
-
-		/* in case graphite interval needs to be the previous one */
-		if (timercmp(&real_iv_start, call_stop, >) && interval_dur_s) {
-			// round up to nearest while interval_dur_s
-			long long d = timeval_diff(&real_iv_start, call_stop);
-			d += (interval_dur_s * 1000000) - 1;
-			d /= 1000000 * interval_dur_s;
-			d *= interval_dur_s;
-			struct timeval graph_dur = { .tv_sec = d, .tv_usec = 0LL };
-			timeval_subtract(&real_iv_start, interval_start, &graph_dur);
-		}
-
-		if (timercmp(&real_iv_start, call_start, >))
-			call_start_in_iv = &real_iv_start;
-
-		/* this should never happen and is here for sanitization of output */
-		if (timercmp(call_start_in_iv, call_stop, >)) {
-			ilog(LOG_ERR, "Call start seems to exceed call stop");
-			return;
-		}
-	}
-
-	timeval_subtract(&call_duration, call_stop, call_start_in_iv);
-
-	mutex_lock(&s->total_calls_duration_lock);
-	timeval_add(&s->total_calls_duration_interval,
-			&s->total_calls_duration_interval, &call_duration);
-	mutex_unlock(&s->total_calls_duration_lock);
-}
-
-
 // op can be CMC_INCREMENT or CMC_DECREMENT
 // check not to multiple decrement or increment
 void statistics_update_ip46_inc_dec(struct call* c, int op) {
@@ -222,14 +175,6 @@ void statistics_update_oneway(struct call* c) {
 
 			RTPE_STATS_ADD(call_duration, timeval_us(&tim_result_duration));
 			RTPE_STATS_INC(managed_sess);
-
-			timeval_totalstats_call_duration_add(
-					&rtpe_totalstats_interval, &ml->started, &ml->terminated,
-					&rtpe_latest_graphite_interval_start,
-					rtpe_config.graphite_interval);
-			timeval_totalstats_call_duration_add(
-					&rtpe_totalstats, &ml->started, &ml->terminated,
-					NULL, 0);
 		}
 
 		if (ml->term_reason==FINAL_TIMEOUT)
@@ -381,7 +326,8 @@ void statistics_update_oneway(struct call* c) {
 GQueue *statistics_gather_metrics(void) {
 	GQueue *ret = g_queue_new();
 
-	struct timeval avg, calls_dur_iv;
+	struct timeval avg;
+	double calls_dur_iv;
 	uint64_t cur_sessions, num_sessions, min_sess_iv, max_sess_iv;
 
 	HEADER("{", "");
@@ -455,18 +401,16 @@ GQueue *statistics_gather_metrics(void) {
 	PROM("one_way_sessions_total", "counter");
 	METRICva("avgcallduration", "Average call duration", "%ld.%06ld", "%ld.%06ld", avg.tv_sec, avg.tv_usec);
 
-	mutex_lock(&rtpe_totalstats_lastinterval_lock);
-	calls_dur_iv = rtpe_totalstats_lastinterval.total_calls_duration_interval;
+	calls_dur_iv = (double) atomic64_get_na(&rtpe_stats_graphite_interval.total_calls_duration) / 1000000.0;
 	min_sess_iv = atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.min.total_sessions);
 	max_sess_iv = atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.max.total_sessions);
-	mutex_unlock(&rtpe_totalstats_lastinterval_lock);
 
 	HEADER(NULL, "");
 	HEADER("}", "");
 	HEADER("intervalstatistics", "Graphite interval statistics (last reported values to graphite):");
 	HEADER("{", NULL);
 
-	METRICva("totalcallsduration", "Total calls duration", "%ld.%06ld", "%ld.%06ld", calls_dur_iv.tv_sec,calls_dur_iv.tv_usec);
+	METRICva("totalcallsduration", "Total calls duration", "%.6f", "%.6f", calls_dur_iv);
 	HEADER(NULL, "");
 
 	METRIC("minmanagedsessions", "Min managed sessions", UINT64F, UINT64F, min_sess_iv);
@@ -682,10 +626,6 @@ void statistics_free_metrics(GQueue **q) {
 }
 
 void statistics_free() {
-	mutex_destroy(&rtpe_totalstats_interval.total_calls_duration_lock);
-
-	mutex_destroy(&rtpe_totalstats_lastinterval_lock);
-
 	mutex_destroy(&rtpe_codec_stats_lock);
 	g_hash_table_destroy(rtpe_codec_stats);
 }
@@ -698,14 +638,10 @@ static void codec_stats_free(void *p) {
 }
 
 void statistics_init() {
-	mutex_init(&rtpe_totalstats_interval.total_calls_duration_lock);
-
 	gettimeofday(&rtpe_started, NULL);
 	//rtpe_totalstats_interval.managed_sess_min = 0; // already zeroed
 	//rtpe_totalstats_interval.managed_sess_max = 0;
 
-	mutex_init(&rtpe_totalstats_lastinterval_lock);
-
 	mutex_init(&rtpe_codec_stats_lock);
 	rtpe_codec_stats = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, codec_stats_free);
 }
diff --git a/include/counter_stats_fields.inc b/include/counter_stats_fields.inc
index 5c61529c4..06343c6dc 100644
--- a/include/counter_stats_fields.inc
+++ b/include/counter_stats_fields.inc
@@ -14,3 +14,4 @@ F(forced_term_sess)
 F(nopacket_relayed_sess)
 F(oneway_stream_sess)
 F(call_duration)
+F(total_calls_duration)
diff --git a/include/graphite.h b/include/graphite.h
index 00a7e7153..74556c079 100644
--- a/include/graphite.h
+++ b/include/graphite.h
@@ -24,6 +24,6 @@ void graphite_loop(void *d);
 void set_latest_graphite_interval_start(struct timeval *tv);
 void set_graphite_interval_tv(struct timeval *tv);
 
-GString *print_graphite_data(struct totalstats *sent_data);
+GString *print_graphite_data(void);
 
 #endif /* GRAPHITE_H_ */
diff --git a/include/statistics.h b/include/statistics.h
index f2c5d6a39..79a99f507 100644
--- a/include/statistics.h
+++ b/include/statistics.h
@@ -62,11 +62,6 @@ struct global_stats_min_max {
 };
 
 
-struct totalstats {
-	mutex_t			total_calls_duration_lock; /* for these two below */
-	struct timeval		total_calls_duration_interval;
-};
-
 struct rtp_stats {
 	unsigned int		payload_type;
 	atomic64		packets;
@@ -109,11 +104,6 @@ struct call_stats {
 	struct stream_stats	totals[4]; /* rtp in, rtcp in, rtp out, rtcp out */
 };
 
-extern struct totalstats       rtpe_totalstats;
-extern struct totalstats       rtpe_totalstats_interval;
-extern mutex_t		       rtpe_totalstats_lastinterval_lock;
-extern struct totalstats       rtpe_totalstats_lastinterval;
-
 extern struct timeval rtpe_started;
 
 extern mutex_t rtpe_codec_stats_lock;
diff --git a/t/test-stats.c b/t/test-stats.c
index 2b3b2a006..68da88fab 100644
--- a/t/test-stats.c
+++ b/t/test-stats.c
@@ -73,7 +73,7 @@ int main(void) {
 
 	// test cmd_time_min/max/avg
 
-	GString *graph_str = print_graphite_data(&rtpe_totalstats_lastinterval);
+	GString *graph_str = print_graphite_data();
 	assert_g_string_eq(graph_str,
 			"ping_time_min 0.000000 150\n"
 			"ping_time_max 0.000000 150\n"
@@ -835,7 +835,7 @@ int main(void) {
 	RTPE_STATS_INC(ng_commands[NGC_OFFER]);
 	RTPE_GAUGE_SET(ng_command_times[NGC_OFFER], 3200000);
 
-	graph_str = print_graphite_data(&rtpe_totalstats_lastinterval);
+	graph_str = print_graphite_data();
 	assert_g_string_eq(graph_str,
 			"ping_time_min 0.000000 150\n"
 			"ping_time_max 0.000000 150\n"
@@ -1594,7 +1594,7 @@ int main(void) {
 	RTPE_STATS_INC(ng_commands[NGC_ANSWER]);
 	RTPE_GAUGE_SET(ng_command_times[NGC_ANSWER], 3200000);
 
-	graph_str = print_graphite_data(&rtpe_totalstats_lastinterval);
+	graph_str = print_graphite_data();
 	assert_g_string_eq(graph_str,
 			"ping_time_min 0.000000 150\n"
 			"ping_time_max 0.000000 150\n"
@@ -2366,7 +2366,7 @@ int main(void) {
 	RTPE_STATS_ADD(ng_commands[NGC_OFFER], 200);
 	call_timer(NULL);
 
-	graph_str = print_graphite_data(&rtpe_totalstats_lastinterval);
+	graph_str = print_graphite_data();
 	assert_g_string_eq(graph_str,
 			"ping_time_min 0.000000 157\n"
 			"ping_time_max 0.000000 157\n"
@@ -3133,7 +3133,7 @@ int main(void) {
 	ml1->started = (struct timeval) {157,0};
 	ml2->started = (struct timeval) {57,0};
 
-	graph_str = print_graphite_data(&rtpe_totalstats_lastinterval);
+	graph_str = print_graphite_data();
 	assert_g_string_eq(graph_str,
 			"ping_time_min 0.000000 157\n"
 			"ping_time_max 0.000000 157\n"
@@ -3895,7 +3895,7 @@ int main(void) {
 
 	add_total_calls_duration_in_interval(&graphite_interval_tv);
 
-	graph_str = print_graphite_data(&rtpe_totalstats_lastinterval);
+	graph_str = print_graphite_data();
 	assert_g_string_eq(graph_str,
 			"ping_time_min 0.000000 200\n"
 			"ping_time_max 0.000000 200\n"
@@ -4659,7 +4659,7 @@ int main(void) {
 
 	// test average call duration
 
-	graph_str = print_graphite_data(&rtpe_totalstats_lastinterval);
+	graph_str = print_graphite_data();
 	assert_g_string_eq(graph_str,
 			"ping_time_min 0.000000 200\n"
 			"ping_time_max 0.000000 200\n"