diff --git a/configure.ac b/configure.ac
index 9bb07fccfe..9233515c47 100644
--- a/configure.ac
+++ b/configure.ac
@@ -833,7 +833,7 @@ AC_SUBST(LIBTOOL_LIB_EXTEN)
 # Checks for header files.
 AC_HEADER_DIRENT
 AC_HEADER_STDC
-AC_CHECK_HEADERS([sys/types.h sys/resource.h sched.h wchar.h sys/filio.h sys/ioctl.h sys/prctl.h sys/select.h netdb.h execinfo.h])
+AC_CHECK_HEADERS([sys/types.h sys/resource.h sched.h wchar.h sys/filio.h sys/ioctl.h sys/prctl.h sys/select.h netdb.h execinfo.h sys/time.h])
 
 if test x"$ac_cv_header_wchar_h" = xyes; then
   HAVE_WCHAR_H_DEFINE=1
@@ -880,7 +880,7 @@ AC_FUNC_MALLOC
 AC_TYPE_SIGNAL
 AC_FUNC_STRFTIME
 AC_CHECK_FUNCS([gethostname vasprintf mmap mlock mlockall usleep getifaddrs timerfd_create getdtablesize posix_openpt poll])
-AC_CHECK_FUNCS([sched_setscheduler setpriority setrlimit setgroups initgroups])
+AC_CHECK_FUNCS([sched_setscheduler setpriority setrlimit setgroups initgroups getrusage])
 AC_CHECK_FUNCS([wcsncmp setgroups asprintf setenv pselect gettimeofday localtime_r gmtime_r strcasecmp stricmp _stricmp])
 
 # Check availability and return type of strerror_r
diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h
index 73b6de1241..6f6ee6bef6 100644
--- a/src/include/switch_utils.h
+++ b/src/include/switch_utils.h
@@ -1279,6 +1279,15 @@ SWITCH_DECLARE(switch_status_t) switch_frame_buffer_dup(switch_frame_buffer_t *f
 SWITCH_DECLARE(switch_status_t) switch_frame_buffer_destroy(switch_frame_buffer_t **fbP);
 SWITCH_DECLARE(switch_status_t) switch_frame_buffer_create(switch_frame_buffer_t **fbP);
 
+typedef struct {
+	int64_t userms;
+	int64_t kernelms;
+} switch_cputime;
+/**
+/ Return used CPU time in this process for user and kernel code
+**/
+SWITCH_DECLARE(void) switch_getcputime(switch_cputime *t);
+
 SWITCH_END_EXTERN_C
 #endif
 /* For Emacs:
diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c
index 765ffba1ff..a415c8c7f0 100644
--- a/src/mod/applications/mod_commands/mod_commands.c
+++ b/src/mod/applications/mod_commands/mod_commands.c
@@ -6059,6 +6059,22 @@ SWITCH_STANDARD_API(quote_shell_arg_function)
 	return SWITCH_STATUS_SUCCESS;
 }
 
+#define GETCPUTIME_SYNTAX "[reset]"
+SWITCH_STANDARD_API(getcputime_function) 
+{
+	static int64_t reset_ums = 0, reset_kms = 0; // Last reset times in ms
+	switch_cputime t = { 0 };
+	switch_getcputime(&t);
+	t.userms -= reset_ums;
+	t.kernelms -= reset_kms;
+	stream->write_function(stream, "%"SWITCH_INT64_T_FMT", %"SWITCH_INT64_T_FMT, t.userms, t.kernelms);
+	if (cmd && !strncmp(cmd, "reset", 5) && t.userms != -1) {
+		reset_ums += t.userms;
+		reset_kms += t.kernelms;
+	}
+	return SWITCH_STATUS_SUCCESS;
+}
+
 #define UUID_LOGLEVEL_SYNTAX "<uuid> <level>"
 SWITCH_STANDARD_API(uuid_loglevel)
 {
@@ -6916,6 +6932,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
 	SWITCH_ADD_API(commands_api_interface, "xml_locate", "Find some xml", xml_locate_function, "[root | <section> <tag> <tag_attr_name> <tag_attr_val>]");
 	SWITCH_ADD_API(commands_api_interface, "xml_wrap", "Wrap another api command in xml", xml_wrap_api_function, "<command> <args>");
 	SWITCH_ADD_API(commands_api_interface, "file_exists", "Check if a file exists on server", file_exists_function, "<file>");
+	SWITCH_ADD_API(commands_api_interface, "getcputime", "Gets CPU time in milliseconds (user,kernel)", getcputime_function, GETCPUTIME_SYNTAX);
 	SWITCH_ADD_API(commands_api_interface, "json", "JSON API", json_function, "JSON");
 
 	SWITCH_ADD_JSON_API(json_api_interface, "mediaStats", "JSON Media Stats", json_stats_function, "");
@@ -7096,6 +7113,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
 	switch_console_set_complete("add uuid_warning ::console::list_uuid");
 	switch_console_set_complete("add ...");
 	switch_console_set_complete("add file_exists");
+	switch_console_set_complete("add getcputime");
 
 	/* indicate that the module should continue to be loaded */
 	return SWITCH_STATUS_NOUNLOAD;
diff --git a/src/switch_utils.c b/src/switch_utils.c
index e0851c3c55..c4a2482356 100644
--- a/src/switch_utils.c
+++ b/src/switch_utils.c
@@ -35,6 +35,10 @@
 #include <switch.h>
 #ifndef WIN32
 #include <arpa/inet.h>
+#if defined(HAVE_SYS_TIME_H) && defined(HAVE_SYS_RESOURCE_H)
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
 #endif
 #include "private/switch_core_pvt.h"
 #define ESCAPE_META '\\'
@@ -4203,6 +4207,25 @@ SWITCH_DECLARE(void) switch_http_dump_request(switch_http_request_t *request)
 	}
 }
 
+SWITCH_DECLARE(void) switch_getcputime(switch_cputime *t)
+{
+#if defined(_WIN32)
+	FILETIME ct, et, kt, ut; // Times are in 100-ns ticks (div 10000 to get ms)
+	GetProcessTimes(GetCurrentProcess(), &ct, &et, &kt, &ut);
+	t->userms = ((int64_t)ut.dwLowDateTime | ((int64_t)ut.dwHighDateTime << 32)) / 10000;
+	t->kernelms = ((int64_t)kt.dwLowDateTime | ((int64_t)kt.dwHighDateTime << 32)) / 10000;
+#elif defined(HAVE_GETRUSAGE)
+	struct rusage r;
+	getrusage(RUSAGE_SELF, &r);
+	t->userms = r.ru_utime.tv_sec * 1000 + r.ru_utime.tv_usec / 1000;
+	t->kernelms = r.ru_stime.tv_sec * 1000 + r.ru_stime.tv_usec / 1000;
+#else
+	t->userms = -1;
+	t->kernelms = -1;
+#endif
+}
+
+
 /* For Emacs:
  * Local Variables:
  * mode:c