diff --git a/2023-12_usb-real-data-rates.md b/2023-12_usb-real-data-rates.md
index bacf107ff2f43608030d0ba72d5dc77cb7cbad9d..f1343b3854f4057f51c5a5616446fe4a175de798 100644
--- a/2023-12_usb-real-data-rates.md
+++ b/2023-12_usb-real-data-rates.md
@@ -88,9 +88,103 @@ There's a nice natural alignment with this and the rest of these systems (which
 
 For future-architecture, my assumption is that I would do something like... one process does oversight, then we build one process per link layer, and probably even one per port, with user-application code going somewhere else. 
 
-So, I presume this will be a lot heavier-handed programming wise, I'll put a stake down before carrying on. 
+So, I presume this will be a lot heavier-handed programming wise, I'll put a stake down before carrying on. Neil also reminded me that Urumbu has implemented multiprocessing, so I should take a look at that as well. 
 
---- 
+### Due Dilligence on Serial Sources
+
+The underlying 0.4MBit/s is pretty underwhelming, I should:
+
+- revisit with smaller packets, to check 
+- delete COBS and see what happens, 
+- delete the .ctr(), basically, right? 
+- return to SAMD21 
+- ... do native-rp2040-codes 
+
+So let's start with a baseline of 32 packets, with the existing (COBS, etc). In this test, we wrap things up using COBS, and we are basically doing two memcpy: one from the application code into the SerialCOBS class, and then again when we encode, and (actually, presumably) a third time when the arduino core copies it out. Since I'm going to end up counting time with python, I've changed stamps-collection for this (stamps were previously minted on the embedded side). 
+
+![baseline](images/2023-12-27_simple-01-baseline.png)
+
+So, all the way down, we'll just absolutely blast the bytes upstream with little regard for any amount of flow control, etc.
+
+![cobsless](images/2023-12-27_simple-02-cobsless.png)
+
+So, there is about ~ 15% overhead reduction there ~ in that we shift from ~ 0.4MBit/s to ~ 0.475 ish. But we are now missing flow-control and framing. We also deleted an information-gather-encode-and-decode (in the datagram) step. 
+
+When we bump from 133MHz to 240MHz, we see this tightening up in the distribution, which is rad... and which suggests a lower bound to packet delay (?) - 
+
+![cobsless](images/2023-12-27_simple-03-cobsless-240mhz.png)
+
+So, I could try on a D21 - might as well (**note the x-axis is stretched 4x!**)
+
+![d21](images/2023-12-27_simple-04-cobsless-d21.png)
+
+This is actually much worse, down to ~ 0.15MBit/s. 
+
+Here's what the basics of those were:
+
+```cpp
+// py-transport-tester 
+// using the RP2040 at 133 MHz 
+
+void setup() {
+  Serial.begin();
+  pinMode(PIN_LED_B, OUTPUT);
+  digitalWrite(PIN_LED_B, HIGH);
+}
+
+uint32_t lastBlink = 0;
+
+void loop() {
+  // write forever, 
+  if(Serial.availableForWrite()){
+    while(Serial.availableForWrite()){
+      Serial.write(125);
+    }
+  }
+  // blink to see hangups 
+  if(lastBlink + 100 < millis()){
+    lastBlink = millis();
+    digitalWrite(PIN_LED_B, !digitalRead(PIN_LED_B));
+  }
+}
+```
+
+```python
+import time, serial 
+import numpy as np 
+import pandas as pd 
+import matplotlib.pyplot as plt 
+
+class UsbSerial:
+    def __init__(self, port, baudrate=115200):
+        self.port = port
+        self.ser = serial.Serial(port, baudrate=baudrate, timeout=1)
+
+    def write(self, data: bytes):
+        self.ser.write(data)
+
+    def read(self):
+        return self.ser.read()
+
+ser = UsbSerial("COM23") 
+
+stamp_count = 1000
+pck_len = 32
+
+stamps = np.zeros(stamp_count)
+
+for i in range(stamp_count):
+  count = 0 
+  while True:
+    if count >= 32:
+      stamps[i] = time.perf_counter() * 1e6
+      break 
+    byte = ser.read()
+    if byte:
+      count += 1 
+
+print("stamps, ", stamps)
+```
 
 ---
 
diff --git a/code/serial_multi_sink_asyncio/multi_sink_blocking.py b/code/serial_multi_sink_asyncio/multi_sink_blocking.py
index 833f5be12216b5619ad3449abc0ae513d6fb1faf..4ef7da39521964b49279cea66cd8f1d392c69149 100644
--- a/code/serial_multi_sink_asyncio/multi_sink_blocking.py
+++ b/code/serial_multi_sink_asyncio/multi_sink_blocking.py
@@ -1,4 +1,4 @@
-from cobs_usb_serial import CobsUsbSerial 
+from cobs_usb_serial_async import CobsUsbSerial 
 import struct 
 import numpy as np 
 import pandas as pd 
diff --git a/code/serial_sink_simple/serial_list.py b/code/serial_sink_simple/serial_list.py
new file mode 100644
index 0000000000000000000000000000000000000000..5f25377227f77c79dc2db925a16f5a5a280f412b
--- /dev/null
+++ b/code/serial_sink_simple/serial_list.py
@@ -0,0 +1,20 @@
+import serial.tools.list_ports
+
+def list_serial_ports():
+    ports = serial.tools.list_ports.comports()
+    for port in ports:
+        print(f"Port: {port.device}")
+        print(f" - Description: {port.description}")
+        if port.serial_number:
+            print(f" - Serial Number: {port.serial_number}")
+        if port.manufacturer:
+            print(f" - Manufacturer: {port.manufacturer}")
+        if port.product:
+            print(f" - Product: {port.product}")
+        if port.vid is not None:
+            print(f" - VID: {port.vid:04X}")
+        if port.pid is not None:
+            print(f" - PID: {port.pid:04X}")
+        print()
+
+list_serial_ports()
diff --git a/code/serial_sink_simple/sink_simple.py b/code/serial_sink_simple/sink_simple.py
new file mode 100644
index 0000000000000000000000000000000000000000..0c26725e418730463c9442f592437d2c6b62ed49
--- /dev/null
+++ b/code/serial_sink_simple/sink_simple.py
@@ -0,0 +1,77 @@
+import time, serial 
+import numpy as np 
+import pandas as pd 
+import matplotlib.pyplot as plt 
+
+class UsbSerial:
+    def __init__(self, port, baudrate=115200):
+        self.port = port
+        self.ser = serial.Serial(port, baudrate=baudrate, timeout=1)
+
+    def write(self, data: bytes):
+        self.ser.write(data)
+
+    def read(self):
+        return self.ser.read()
+
+ser = UsbSerial("COM23") 
+
+stamp_count = 1000
+pck_len = 32
+
+stamps = np.zeros(stamp_count)
+
+for i in range(stamp_count):
+  count = 0 
+  while True:
+    if count >= 32:
+      stamps[i] = time.perf_counter() * 1e6
+      break 
+    byte = ser.read()
+    if byte:
+      count += 1 
+
+print("stamps, ", stamps)
+
+def plot_stamps(stamps):
+  # make df from stamps 
+  df = pd.DataFrame({'timestamps': stamps})
+
+  # calculate deltas between stamps 
+  df['deltas'] = df['timestamps'].diff() 
+
+  # clean NaN's 
+  df = df.dropna()
+
+  # wipe obviously-wrong deltas (i.e. the 1st, which goes 0-start-us) 
+  df = df[df['deltas'] < 100000]
+
+  # Plotting
+  fig, ax1 = plt.subplots(figsize=(11, 3))
+
+  ax1.set_xlim([250, 1100])
+
+  # Primary x-axis (time deltas)
+  df['deltas'].plot(kind='hist', bins=100, ax=ax1)
+  ax1.set_xlabel('Time-Stamp Deltas (us) and equivalent (MBits/s)')
+  ax1.set_ylabel(f'Frequency (of {stamp_count})')
+
+  # get axis ticks to calculate equivalent bandwidths 
+  x_ticks = ax1.get_xticks()
+  ax1.set_xticks(x_ticks)
+  bandwidths = [((pck_len * 8) * (1e6 / x)) / 1e6 for x in x_ticks]
+  ticks = [] 
+
+  for i in range(len(x_ticks)):
+    print(i, x_ticks[i], bandwidths[i]) 
+    ticks.append(f"{x_ticks[i]:.0f} ({bandwidths[i]:.3f})")
+
+  ax1.set_xticklabels(ticks)
+
+  plt.title(f'Single-Source COBS Data Sink Deltas, pck_len={pck_len}')
+
+  plt.tight_layout()
+
+  plt.show()
+
+plot_stamps(stamps)
\ No newline at end of file
diff --git a/code/serial_source_simple/serial_source_simple.ino b/code/serial_source_simple/serial_source_simple.ino
new file mode 100644
index 0000000000000000000000000000000000000000..94e16345b2b2a28195bf26f0fa157f36314c5cbb
--- /dev/null
+++ b/code/serial_source_simple/serial_source_simple.ino
@@ -0,0 +1,24 @@
+// py-transport-tester 
+// using the RP2040 at 133 MHz 
+
+void setup() {
+  Serial.begin(9600);
+  pinMode(PIN_LED_B, OUTPUT);
+  digitalWrite(PIN_LED_B, HIGH);
+}
+
+uint32_t lastBlink = 0;
+
+void loop() {
+  // write forever, 
+  if(Serial.availableForWrite()){
+    while(Serial.availableForWrite()){
+      Serial.write(125);
+    }
+  }
+  // blink to see hangups 
+  if(lastBlink + 100 < millis()){
+    lastBlink = millis();
+    digitalWrite(PIN_LED_B, !digitalRead(PIN_LED_B));
+  }
+}
diff --git a/images/2023-12-27_simple-01-baseline.png b/images/2023-12-27_simple-01-baseline.png
new file mode 100644
index 0000000000000000000000000000000000000000..304539cfacb0085fde9860dce5fb4a7e6fdcda7a
Binary files /dev/null and b/images/2023-12-27_simple-01-baseline.png differ
diff --git a/images/2023-12-27_simple-02-cobsless.png b/images/2023-12-27_simple-02-cobsless.png
new file mode 100644
index 0000000000000000000000000000000000000000..71acf648c26ec711c9b9ba30861975e8113fef34
Binary files /dev/null and b/images/2023-12-27_simple-02-cobsless.png differ
diff --git a/images/2023-12-27_simple-03-cobsless-240mhz.png b/images/2023-12-27_simple-03-cobsless-240mhz.png
new file mode 100644
index 0000000000000000000000000000000000000000..d0e9a07e2c356b9a4feaa214e55c3ac8fe7c2b39
Binary files /dev/null and b/images/2023-12-27_simple-03-cobsless-240mhz.png differ
diff --git a/images/2023-12-27_simple-04-cobsless-d21.png b/images/2023-12-27_simple-04-cobsless-d21.png
new file mode 100644
index 0000000000000000000000000000000000000000..2d7b96c6eb1c3ea31ff815c3a53171d386d2d0e5
Binary files /dev/null and b/images/2023-12-27_simple-04-cobsless-d21.png differ