diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index fa148f1719323eed3f9240a583a08e2f1d300d0a..a0412f91598e3fff4eb2045e85f03c5bc8a09029 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -583,6 +583,7 @@ set(viewer_SOURCE_FILES
     llsyntaxid.cpp
     llsyswellitem.cpp
     llsyswellwindow.cpp
+    lltelemetry.cpp
     llteleporthistory.cpp
     llteleporthistorystorage.cpp
     lltextureatlas.cpp
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 4339aa880752bac2e5a26c212bebdaa190630a79..2feba40d23bb2c2cdcb6bc728f6cf256e6df8c15 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -89,6 +89,7 @@
 #include "llsdutil_math.h"
 #include "lllocationhistory.h"
 #include "llfasttimerview.h"
+#include "lltelemetry.h"
 #include "llvector4a.h"
 #include "llviewermenufile.h"
 #include "llvoicechannel.h"
@@ -1608,6 +1609,8 @@ bool LLAppViewer::doFrame()
 		LL_INFOS() << "Exiting main_loop" << LL_ENDL;
 	}
 
+    LLPROFILE_UPDATE();
+
 	return ! LLApp::isRunning();
 }
 
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 3ef2d47d372d946c98dad71c6957c11d8d462bbd..8fd9a03a4410734b4aa167d6517a20d5cb74fc7f 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -176,6 +176,7 @@
 #include "pipeline.h"
 #include "llappviewer.h"
 #include "llfasttimerview.h"
+#include "lltelemetry.h"
 #include "llfloatermap.h"
 #include "llweb.h"
 #include "llvoiceclient.h"
@@ -527,6 +528,8 @@ bool idle_startup()
 			}
 
 			#if LL_WINDOWS
+                LLPROFILE_STARTUP();
+
 				// On the windows dev builds, unpackaged, the message.xml file will 
 				// be located in indra/build-vc**/newview/<config>/app_settings.
 				std::string message_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"message.xml");
diff --git a/indra/newview/lltelemetry.cpp b/indra/newview/lltelemetry.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0c63e2fede5d45b4b56949d9399d812a98c166f4
--- /dev/null
+++ b/indra/newview/lltelemetry.cpp
@@ -0,0 +1,145 @@
+ /**
+ * @file lltelemetry.cpp
+ * @brief Wrapper for Rad Game Tools Telemetry
+ *
+ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2020, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lltelemetry.h"
+
+#if LLPROFILE_USE_RAD_TELEMETRY_PROFILER
+    #if LL_WINDOWS
+        #include "llwin32headers.h"
+
+        // build-vc120-64\packages\lib\release
+        // build-vc150-64\packages\lib\release
+        #ifdef _MSC_VER
+            #pragma comment(lib,"rad_tm_win64.lib")
+        #else
+            #pragma message "NOTE: Rad GameTools Telemetry requested but non-MSVC compiler not yet supported on Windows"
+        #endif
+    #endif // LL_WINDOWS
+
+    #if LL_DARWIN
+        #pragma message "NOTE: Rad Game Tools Telemetry requested but not yet supported on Darwin"
+    #endif
+
+    #if LL_LINUX
+        #pragma message "NOTE: Rad Game Tools Telemetry requested but not yet supported on Linux"
+    #endif
+
+//
+// local consts
+//
+static const tm_int32 TELEMETRY_BUFFER_SIZE  = 8 * 1024 * 1024;
+
+//
+// local globals
+//
+static char *gTelemetryBufferPtr = NULL; // Telemetry
+
+static const char *tm_status[ TMERR_INIT_NETWORKING_FAILED + 1 ] =
+{
+      "Telemetry pass: connected"                       // TM_OK
+    , "Telemetry FAIL: disabled via #define NTELEMETRY" // TMERR_DISABLED
+    , "Telemetry FAIL: invalid paramater"               // TMERR_INVALID_PARAM
+    , "Telemetry FAIL: DLL not found"                   // TMERR_NULL_API
+    , "Telemetry FAIL: out of resources"                // TMERR_OUT_OF_RESOURCES
+    , "Telemetry FAIL: tmInitialize() not called"       // TMERR_UNINITIALIZED
+    , "Telemetry FAIL: bad hostname"                    // TMERR_BAD_HOSTNAME
+    , "Telemetry FAIL: couldn't connect to server"      // TMERR_COULD_NOT_CONNECT
+    , "Telemetry FAIL: unknown network error"           // TMERR_UNKNOWN_NETWORK
+    , "Telemetry FAIL: tmShutdown() already called"     // TMERR_ALREADY_SHUTDOWN
+    , "Telemetry FAIL: memory buffer too small"         // TMERR_ARENA_TOO_SMALL
+    , "Telemetry FAIL: server handshake error"          // TMERR_BAD_HANDSHAKE
+    , "Telemetry FAIL: unaligned parameters"            // TMERR_UNALIGNED
+    , "Telemetry FAIL: network not initialized"         // TMERR_NETWORK_NOT_INITIALIZED -- WSAStartup not called before tmOpen()
+    , "Telemetry FAIL: bad version"                     // TMERR_BAD_VERSION
+    , "Telemetry FAIL: timer too large"                 // TMERR_BAD_TIMER
+    , "Telemetry FAIL: tmOpen() already called"         // TMERR_ALREADY_OPENED
+    , "Telemetry FAIL: tmInitialize() already called"   // TMERR_ALREADY_INITIALIZED
+    , "Telemetry FAIL: could't open file"               // TMERR_FILE_OPEN_FAILED
+    , "Telemetry FAIL: tmOpen() failed networking"      // TMERR_INIT_NETWORKING_FAILED
+};
+
+//
+// exported functionality
+//
+
+void telemetry_shutdown()
+{
+    #if LL_WINDOWS
+        if (gTelemetryBufferPtr)
+        {
+            tmClose(0);
+            tmShutdown();
+
+            delete[] gTelemetryBufferPtr;
+            gTelemetryBufferPtr = NULL;
+        }
+    #endif
+}
+
+void telemetry_startup()
+{
+    #if LL_WINDOWS
+        tmLoadLibrary(TM_RELEASE); // Loads .dll
+
+        gTelemetryBufferPtr = new char[ TELEMETRY_BUFFER_SIZE ];
+        tmInitialize(TELEMETRY_BUFFER_SIZE, gTelemetryBufferPtr);
+
+        tm_error telemetry_status = tmOpen(
+            0,                     // unused
+            "SecondLife",          // app name
+            __DATE__ " " __TIME__, // build identifier
+            "localhost",           // server name (or filename)
+            TMCT_TCP,              // connection type (or TMCT_FILE)
+            4719,                  // port
+            TMOF_INIT_NETWORKING,  // open flags
+            250 );                 // timeout ms
+
+        if (telemetry_status == TMERR_UNKNOWN)
+        {
+            LL_ERRS() << "Telemetry FAIL: unknown error" << LL_ENDL;
+        }
+        else if (telemetry_status && (telemetry_status <= TMERR_INIT_NETWORKING_FAILED))
+        {
+            LL_INFOS() << tm_status[ telemetry_status ] << LL_ENDL;
+            free(gTelemetryBufferPtr);
+            gTelemetryBufferPtr = NULL;
+        }
+    #endif // LL_WINDOWS
+}
+
+// Called after we render a frame
+void telemetry_update()
+{
+    #if LL_WINDOWS
+        if (gTelemetryBufferPtr)
+        {
+            tmTick(0);
+        }
+    #endif
+}
+#endif // LLPROFILE_USE_RAD_TELEMETRY_PROFILER
diff --git a/indra/newview/lltelemetry.h b/indra/newview/lltelemetry.h
new file mode 100644
index 0000000000000000000000000000000000000000..a73e5fcfa27aef28cdd4ad71f6a273885bbba7b1
--- /dev/null
+++ b/indra/newview/lltelemetry.h
@@ -0,0 +1,81 @@
+/**
+ * @file lltelemetry.h
+ * @brief Wrapper for Rad Game Tools Telemetry
+ *
+ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2020, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+/*
+To use:
+
+1. Uncomment #define LLPROFILE_USE_RAD_TELEMETRY_PROFILER below
+
+2. Include this header file
+    #include "lltelemetry.h"
+
+3. Add zones to the functions you wish to profile
+    void onFoo()
+    {
+        LLPROFILE_ZONE("Foo");
+    }
+*/
+//#define LLPROFILE_USE_RAD_TELEMETRY_PROFILER 1
+
+// Default NO local telemetry profiling
+#ifndef LLPROFILE_USE_RAD_TELEMETRY_PROFILER
+    #define LLPROFILE_USE_RAD_TELEMETRY_PROFILER 0
+    #define LLPROFILE_SHUTDOWN( ...) {}
+    #define LLPROFILE_STARTUP(  ...) {}
+    #define LLPROFILE_UPDATE(   ...) {}
+
+    #define LLPROFILE_AUTO_CPU_MARKER_COLOR(r, g, b)
+    #define LLPROFILE_ENTER(name)
+    #define LLPROFILE_ENTER_FORMAT(format, ...)
+    #define LLPROFILE_FUNCTION
+    #define LLPROFILE_LEAVE()
+    #define LLPROFILE_THREAD_NAME(name)
+    #define LLPROFILE_ZONE(name)
+    #define LLPROFILE_ZONE_FORMAT(format, ...)
+#else
+    #include <rad_tm.h>
+
+    #define LLPROFILE_SHUTDOWN                       telemetry_shutdown
+    #define LLPROFILE_STARTUP                        telemetry_startup
+    #define LLPROFILE_UPDATE                         telemetry_update
+
+    #define LLPROFILE_AUTO_CPU_MARKER_COLOR(r, g, b) tmZoneColor(r, g, b)
+    #define LLPROFILE_ENTER(name)                    tmEnter(0, 0, name)
+    #define LLPROFILE_ENTER_FORMAT(format, ...)      tmEnter(0, 0, format, __VA_ARGS__)
+    #define LLPROFILE_FUNCTION                       tmFunction(0, 0)
+    #define LLPROFILE_LEAVE()                        tmLeave(0)
+    #define LLPROFILE_THREAD_NAME(name)              tmThreadName(0, 0, name)
+    #define LLPROFILE_ZONE(name)                     tmZone(0, 0, name)
+    #define LLPROFILE_ZONE_FORMAT(format, ...)       tmZone(0, 0, format, __VA_ARGS__)
+#endif // LLPROFILE_USE_RAD_TELEMETRY_PROFILER
+
+//
+// exported functionality
+//
+
+extern void telemetry_startup();
+extern void telemetry_shutdown();
+extern void telemetry_update(); // called after every frame update