UDP seems VERY slow

Good Afternoon,

I am using the Photon 2's UDP library for sending an receiving packets to/from my PC. However, it seems to be extremely slow.

If you've seen any of my previous posts, you may have seen me note the UDP throughput of the Photon 2 back to itself is about 54Mbps. I have since come to the realization that is incorrect because sending data back to itself is treated as localhost or "" and the data never actually left the device.

I am now sending a 10KB UDP packet from my PC to my Photon 2 and built a hardware timer to count microseconds. This is a logic diagram of my timer as well as the code running on the Photon 2. The timer has been tested and works on a 1MHz (1 microsecond) frequency.


Sending a 10KB UDP packet from my PC to the Photon 2 takes about 134,000 microseconds for a throughput of 0.611Mbps = 611Kbps. Sending smaller packets seems to be even worse as it takes the same amount of time (134,000) microseconds to send even a 128 byte UDP packet.

I've heard people having issues with UDP before so if anyone has any pointers as to what might be going on I'd really appreciate it

Thank you,

Hi Matt,

The team is working on replication, and will have something for you next week.

1 Like

The P2/Photon 2 are intended to be IoT devices, not for use with high-speed data transfers even over Wi-Fi, so they are not at all optimized for it. However I wrote a test program to see what the performance is like.

UDP is by definition unreliable, so there isn't a maximum rate the Particle device can receive, per se. It's the maximum rate at the loss rate you can tolerate when sending to the Particle device. When you exceed the rate that the device can process the packets, they are discarded.

This is also dependent on the size of the packets. As the packets get larger, the number of packets that can be processed in a given window of time is reduced. For example, at 1024 byte packets, the P2 can receive 500 packets per second (500 Kbytes/sec), or a packet transmitted every 2 milliseconds. If you increase the packets to 8192 bytes, the packet sending interval must increase to 8 milliseconds, but this is still a doubling of the transfer rate (1000 Kbyte/sec). Larger packets than 8192 appear to be unreliable.

Because of the way the FreeRTOS threading works, each thread gets executed at a maximum rate of 1000 time per second. This includes the main loop thread. Because the incoming UDP buffer appears to be small, exceeding 1000 packets per second appears to incur large losses, even if the packets are small, and 500 packets per second seems optimal for minimizing losses.

It's different for upload (from the Particle device). That's mostly limited by the amount of blocking you can tolerate, though thread scheduling also comes into play.

Also TCP is different because it does have buffering and the ability for the receiver to slow down transmission.


Really appreciate both responses. Rick, I don't know if you mind sharing the test you wrote. I'm always interested in how these things are measured.

Thank you,

This tool is experimental and a little bit flaky.

It wrote it to test a single thing and got the necessary results so there probably won't be much development on it, but I published it because it does have some neat techniques if you can get past the device code occasionally locking up the device.

It only tests sending data to the Particle device, but I did intend for it to work in either direction but it's missing code for some bits of that.

There's a node.js server component that you run, and it's also an interactive tool that you can make menu selections on to run a test. You can configure the test parameters at the top of app.js.

There's device firmware that you flash to a Particle Wi-Fi device.

And you must connect the Particle device to the computer running the node script via USB.

You will probably want to monitor the device's serial USB debug using particle serial monitor.

The way it works is that the node server and device firmware communicate by USB control requests that run independently of the serial monitor. The allows the device to tell the server that it's online and what its IP address is. It's also how the server tells the device it's about to start a new test.