diff --git a/mercurial/help/internals/wireprotocol.txt b/mercurial/help/internals/wireprotocol.txt
--- a/mercurial/help/internals/wireprotocol.txt
+++ b/mercurial/help/internals/wireprotocol.txt
@@ -718,6 +718,46 @@
 The last atom in the frame SHOULD end with a newline (``\n``). If it
 doesn't, clients MAY add a newline to facilitate immediate printing.
 
+Progress Update (``0x07``)
+--------------------------
+
+This frame holds the progress of an operation on the peer. Consumption
+of these frames allows clients to display progress bars, estimated
+completion times, etc.
+
+Each frame defines the progress of a single operation on the peer. The
+payload consists of:
+
+* A 64-bit signed little-endian integer denoting the numeric position
+  of this topic.
+* A 64-bit unsigned little-endian integer denoting the total/end
+  numeric position of this topic.
+* An 8-bit unsigned integer denoting the string length of the topic
+  that is being updated.
+* An 8-bit unsigned integer denoting the string length of the unit
+  label.
+* A 16-bit unsigned little-endian integer denoting the string length
+  of the item currently being processed.
+* 1 or more bytes containing the topic name, interpreted as UTF-8.
+* 0 or more bytes containing the unit label, interpreted as UTF-8.
+* 0 or more bytes containing the item name, interpreted as UTF-8.
+
+Progress state is created when a frame is received referencing a
+*topic* that isn't currently tracked. Progress tracking for that
+*topic* is finished when a frame is received reporting the current
+position of that topic as ``-1``.
+
+Multiple *topics* may be active at any given time.
+
+Rendering of progress information is not mandated or governed by this
+specification: implementations MAY render progress information however
+they see fit, including not at all.
+
+The string data describing the topic SHOULD be static strings to
+facilitate receivers localizing that string data. The emitter
+MUST normalize all string data to valid UTF-8 and receivers SHOULD
+validate that received data conforms to UTF-8.
+
 Issuing Commands
 ----------------
 
diff --git a/mercurial/wireprotoframing.py b/mercurial/wireprotoframing.py
--- a/mercurial/wireprotoframing.py
+++ b/mercurial/wireprotoframing.py
@@ -31,6 +31,7 @@
 FRAME_TYPE_BYTES_RESPONSE = 0x04
 FRAME_TYPE_ERROR_RESPONSE = 0x05
 FRAME_TYPE_TEXT_OUTPUT = 0x06
+FRAME_TYPE_PROGRESS = 0x07
 
 FRAME_TYPES = {
     b'command-name': FRAME_TYPE_COMMAND_NAME,
@@ -39,6 +40,7 @@
     b'bytes-response': FRAME_TYPE_BYTES_RESPONSE,
     b'error-response': FRAME_TYPE_ERROR_RESPONSE,
     b'text-output': FRAME_TYPE_TEXT_OUTPUT,
+    b'progress': FRAME_TYPE_PROGRESS,
 }
 
 FLAG_COMMAND_NAME_EOS = 0x01
@@ -91,6 +93,7 @@
     FRAME_TYPE_BYTES_RESPONSE: FLAGS_BYTES_RESPONSE,
     FRAME_TYPE_ERROR_RESPONSE: FLAGS_ERROR_RESPONSE,
     FRAME_TYPE_TEXT_OUTPUT: {},
+    FRAME_TYPE_PROGRESS: {},
 }
 
 ARGUMENT_FRAME_HEADER = struct.Struct(r'<HH')