SETNX+TTL - yep, covered in my other reply: right call for multi-worker, overkill for the 40-line single-cron starter this post is.
regional blackouts — this is the real one. global "all green" while a specific country pool is toast is exactly what we saw during this year's outage wave. our fix was per-geo probes against the actual targets each geo is used for, weighted by where customers actually buy a US-heavy pool gets US-target probes, not a generic ip-api ping. if you only add one thing from this thread, add that.
connect vs read timeout split-agreed, and it's basically free to implement (requests does it natively with a (connect, read) tuple). gateway choking vs exit nodes dying are different incidents with different escalation paths, no reason to blur them.
cost-per-successful-request nice metric, we track success-rate-per-GB which is the same signal from the other end. it catches the "quiet degradation" phase weeks before users start complaining, you're right about that.
multi-region version with locking + per-geo probes is the next post in this series, this thread is basically writing the outline for me :)
if you're running this in production, swap out those json state files for Redis with SETNX and TTL, because otherwise you're gonna get absolutely hammered by alert spam and race conditions once you scale up. also actually test your geos against real targets you actually care about, not just some random IP checker, because 2026 taught us that the nightmare scenario is regional blackouts where your global monitoring says everything's fine but a specific country's pool is completely toast. So split your timeouts into connect and read separately so you can actually tell if it's a gateway choking or your exit nodes getting wrecked. And start tracking cost-per-successful-request because that's how you catch a pool quietly degrading before it face-plants spectacularly