Here's a high level overview on how we deal with it: let's say you have a device connected via UART to a Linux box with WiFi.
1. When an error occurs, the Memfault library collects all the needed information and saves a packed error_report_t in a circular buffer in non-volatile storage (say, flash).
2. When connectivity is available, your code calls our SDK and says "hey, can you give us N bytes of data to send". If Memfault has data in the circular buffer, it returns a chunk of N bytes. Otherwise it returns false.
3. You use your transport to send the N bytes packet to the Linux system.
4. Your code on the Linux box calls the Memfault Gateway SDK to tell it you've received N bytes of Memfault code.
5. The Memfault Gateway SDK recombines packets into error_report_t and HTTP POST-s them to our backend.
Does that make sense? Happy to talk about it in more details.