Just for the sake of the search engines and future Perl monks, I'll post the resolution to this. The problem is that Perl cannot free() memory. So as threads polled devices with large result sets, each one's memory footprint would get larger and larger. Once enough threads had their memory allocation ballooned to silly levels, the whole process would exceed the maximum process size. The solution is to keep closing and respawning threads to allow free() to happen or move the polling heavy lifting into a subprocess so that memory could be freed when the subprocess terminates.