diff --git a/include/osv/trace.hh b/include/osv/trace.hh
index 5f0cb9758595d4d5319489b6f14bbf0a102343c7..36d04029a7452e28a6f28a129ea83fe88d3ec515 100644
--- a/include/osv/trace.hh
+++ b/include/osv/trace.hh
@@ -30,6 +30,7 @@ class tracepoint_base;
 struct trace_record {
     tracepoint_base* tp;
     sched::thread* thread;
+    std::array<char, 16> thread_name;
     u64 time;
     unsigned cpu;
     bool backtrace : 1;  // 10-element backtrace precedes parameters
@@ -308,6 +309,7 @@ public:
         auto tr = allocate_trace_record(size());
         tr->tp = this;
         tr->thread = sched::thread::current();
+        tr->thread_name = tr->thread->name_raw();
         tr->time = 0;
         tr->cpu = -1;
         auto buffer = tr->buffer;
diff --git a/scripts/loader.py b/scripts/loader.py
index 7f6eeed53a8d6a39992ae553348009b30ae342e7..e75d7c115b0131a5d5f951a34783c49aaf8a08ad 100644
--- a/scripts/loader.py
+++ b/scripts/loader.py
@@ -837,7 +837,8 @@ def all_traces():
 
     i = 0
     while i < last:
-        tp_key, thread, time, cpu, flags = struct.unpack('QQQII', trace_log[i:i+32])
+        tp_key, thread, thread_name, time, cpu, flags = struct.unpack('QQ16sQII', trace_log[i:i+48])
+        thread_name = thread_name.rstrip('\0')
         if tp_key == 0:
             i = align_up(i + 8, trace_page_size)
             continue
@@ -849,7 +850,7 @@ def all_traces():
                 sig_to_string(ulong(tp_ref['sig'])), str(tp_ref["format"].string()))
             tracepoints[tp_key] = tp
 
-        i += 32
+        i += 48
 
         backtrace = None
         if flags & 1:
@@ -860,7 +861,7 @@ def all_traces():
         data = struct.unpack(tp.signature, trace_log[i:i+size])
         i += size
         i = align_up(i, 8)
-        yield Trace(tp, thread, time, cpu, data, backtrace=backtrace)
+        yield Trace(tp, thread, thread_name, time, cpu, data, backtrace=backtrace)
 
 def save_traces_to_file(filename):
     trace.write_to_file(filename, list(all_traces()))
diff --git a/scripts/osv/trace.py b/scripts/osv/trace.py
index 5bdd9ef3d83a7b4f593874c77624a070b446b91a..be6832c7134de01ed10b06a16d407f7b17a69454 100644
--- a/scripts/osv/trace.py
+++ b/scripts/osv/trace.py
@@ -79,9 +79,10 @@ class TracePoint:
                 self.format)
 
 class Trace:
-    def __init__(self, tp, thread, time, cpu, data, backtrace=None):
+    def __init__(self, tp, thread, thread_name, time, cpu, data, backtrace=None):
         self.tp = tp
         self.thread = thread
+        self.thread_name = thread_name
         self.time = time
         self.cpu = cpu
         self.data = data
@@ -97,8 +98,9 @@ class Trace:
         return format % self.data
 
     def format(self, bt_formatter=default_backtrace_formatter):
-        return '0x%016x %2d %19s %-20s %s%s' % (
+        return '0x%016x %-15s %2d %19s %-20s %s%s' % (
             self.thread,
+            self.thread_name,
             self.cpu,
             format_time(self.time),
             self.name,
@@ -172,7 +174,8 @@ def read(buffer_view):
             unpacker.unpack_str(), unpacker.unpack_str())
 
     while unpacker:
-        tp_key, thread, time, cpu = unpacker.unpack('QQQI')
+        tp_key, thread, thread_name, time, cpu = unpacker.unpack('QQ16sQI')
+        thread_name = thread_name.rstrip('\0')
         tp = tracepoints[tp_key]
 
         backtrace = []
@@ -183,7 +186,7 @@ def read(buffer_view):
             backtrace.append(frame)
 
         data = unpacker.unpack(tp.signature)
-        yield Trace(tp, thread, time, cpu, data, backtrace=backtrace)
+        yield Trace(tp, thread, thread_name, time, cpu, data, backtrace=backtrace)
 
 def write(traces, writer):
     packer = WritingPacker(writer)
@@ -196,7 +199,8 @@ def write(traces, writer):
         packer.pack_str(tp.name, tp.signature, tp.format)
 
     for trace in traces:
-        packer.pack('QQQI', trace.tp.key, trace.thread, trace.time, trace.cpu)
+        packer.pack('QQ16sQI', trace.tp.key, trace.thread, trace.thread_name,
+                    trace.time, trace.cpu)
 
         if trace.backtrace:
             for frame in filter(None, trace.backtrace):