<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Proxy Universe</title>
    <description>The latest articles on DEV Community by Proxy Universe (@proxyuniverse).</description>
    <link>https://dev.to/proxyuniverse</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4032549%2F9cb42099-a6d6-4a7b-a5a8-74e935dd91c8.jpg</url>
      <title>DEV Community: Proxy Universe</title>
      <link>https://dev.to/proxyuniverse</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/proxyuniverse"/>
    <language>en</language>
    <item>
      <title>How to Verify Proxy Quality Before You Buy: Latency, Anonymity &amp; Geo Accuracy</title>
      <dc:creator>Proxy Universe</dc:creator>
      <pubDate>Tue, 04 Aug 2026 08:51:40 +0000</pubDate>
      <link>https://dev.to/proxyuniverse/how-to-verify-proxy-quality-before-you-buy-latency-anonymity-geo-accuracy-9m0</link>
      <guid>https://dev.to/proxyuniverse/how-to-verify-proxy-quality-before-you-buy-latency-anonymity-geo-accuracy-9m0</guid>
      <description>&lt;p&gt;Most proxy providers publish numbers you cannot verify. This is a practical walkthrough for checking latency, anonymity level, geo accuracy and pool depth yourself — using public endpoints and a small Python script — so you evaluate a pool on evidence instead of a pricing page.&lt;/p&gt;

&lt;h1&gt;
  
  
  How to Verify Proxy Quality Before You Buy: Latency, Anonymity &amp;amp; Geo Accuracy
&lt;/h1&gt;

&lt;p&gt;Every proxy provider publishes the same three claims: huge pool, high success rate, global coverage. None of them are verifiable from the outside, and all of them are true in the sense that a used car "runs."&lt;/p&gt;

&lt;p&gt;The good news is that the things that actually matter are measurable in about fifteen minutes with a small script and a minimum top-up. This post walks through what to measure, why each metric matters, and how to read the output.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually matters
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fayvu3yod4s46n1x7kyj5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fayvu3yod4s46n1x7kyj5.png" alt=" " width="800" height="356"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Four measurable properties tell you almost everything about a pool's usefulness:&lt;/p&gt;

&lt;p&gt;![Four measurable proxy metrics: latency, anonymity level, geo accuracy, pool depth — and what each one tells you&lt;br&gt;
&lt;em&gt;Four metrics, four different failure modes. Measure all four — any one of them alone is misleading.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Latency&lt;/strong&gt; — round-trip time through the proxy. Residential routing adds real overhead; anything under 1s to a nearby endpoint is healthy, 1–3s is workable for batch jobs, consistently above 3s will wreck any interactive workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anonymity level&lt;/strong&gt; — whether the proxy forwards headers that reveal it's a proxy at all. &lt;code&gt;X-Forwarded-For&lt;/code&gt;, &lt;code&gt;Via&lt;/code&gt;, and friends. A proxy that announces itself defeats the purpose.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Geo accuracy&lt;/strong&gt; — whether the IP is actually where the dashboard says it is. Registry data and physical routing disagree more often than you'd expect, and CDN-served content is regional, so a mismatch silently corrupts collected data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pool depth&lt;/strong&gt; — how many distinct IPs you actually get for a given location. A provider can support a country with forty usable addresses in it. That's technically true and operationally useless.&lt;/p&gt;
&lt;h2&gt;
  
  
  The script
&lt;/h2&gt;

&lt;p&gt;Nothing exotic — &lt;code&gt;requests&lt;/code&gt; and the standard library. It pulls each proxy from a list, measures round-trip time, checks which headers arrive at the other end, and resolves geo from a public IP-intelligence endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;collections&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Counter&lt;/span&gt;

&lt;span class="c1"&gt;# Public endpoints that echo what the other side sees.
&lt;/span&gt;&lt;span class="n"&gt;ECHO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://httpbin.org/get&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;GEO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://ipinfo.io/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Headers that reveal a proxy is in the path.
&lt;/span&gt;&lt;span class="n"&gt;LEAK_HEADERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Via&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-Real-Ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Forwarded&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-Proxy-Id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proxy_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Measure one proxy: latency, header leaks, exit IP and geo.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;proxies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;proxy_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;proxy_url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;proxy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;proxy_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ok&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perf_counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ECHO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proxies&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;proxies&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;latency_ms&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perf_counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;seen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;headers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{}))&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;leaks&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LEAK_HEADERS&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;seen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GEO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proxies&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;proxies&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;city&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;city&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;country&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;country&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;org&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;org&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ok&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;

&lt;span class="err"&gt;!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uploads&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;us&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;east&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.&lt;/span&gt;&lt;span class="n"&gt;amazonaws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;uploads&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;articles&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;m0npqy6rfl80uc8akfi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;png&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proxy_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expect_country&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;proxy_list&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;alive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ok&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;alive: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;alive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;

    &lt;span class="n"&gt;lat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;latency_ms&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;alive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;latency ms  min=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;lat&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;  median=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;lat&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;  max=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;lat&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;unique_ips&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;alive&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unique exit IPs: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;unique_ips&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (from &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; working proxies)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;leaking&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;alive&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;leaks&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;header leaks: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;leaking&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;leaking&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;   &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ip&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; leaks &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;leaks&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;expect_country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;wrong&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;alive&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;country&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;expect_country&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;geo mismatch: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wrong&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; expected &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;expect_country&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;wrong&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;   &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ip&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; -&amp;gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;country&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; / &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;city&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;top networks:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;org&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;alive&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;most_common&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# user:pass@host:port — one entry per proxy you want to evaluate
&lt;/span&gt;    &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://user:pass@proxy.example.net:8000&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://user:pass@proxy.example.net:8001&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nf"&gt;report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expect_country&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;US&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two notes on running it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test &lt;strong&gt;sequentially first&lt;/strong&gt;, not concurrently. Concurrency hides per-proxy latency in queue time and you'll misread the numbers.&lt;/li&gt;
&lt;li&gt;Run it &lt;strong&gt;twice, an hour apart&lt;/strong&gt;. A pool that looks great once and degrades on the second pass is telling you something important about peer churn.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Reading the results
&lt;/h2&gt;

&lt;p&gt;The raw numbers are less interesting than the patterns they form.&lt;/p&gt;

&lt;p&gt;![How to interpret proxy test results: healthy pool versus warning signs across latency, unique IPs, leaks and network diversity&lt;br&gt;
&lt;em&gt;The same four metrics, read as signals. Patterns matter more than individual values.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unique exit IPs well below the number of proxies tested.&lt;/strong&gt; You're being served a thin slice of the pool. Ten proxies returning three distinct IPs means you're effectively buying three IPs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Any header leak at all.&lt;/strong&gt; Non-negotiable. This is a configuration property of the provider's edge, not something you can patch client-side.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;org&lt;/code&gt; field showing hosting providers.&lt;/strong&gt; If the organisation behind your "residential" IPs is a cloud host or a datacenter ASN, the label is wrong. Real residential IPs resolve to consumer ISPs — the kind of names that show up on home broadband bills.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wide latency spread with a low median.&lt;/strong&gt; A median of 400ms with a max of 9s means a minority of peers are effectively dead. That tail is what causes mysterious timeouts in production, and it never appears in a provider's advertised average.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Country correct, city consistently wrong.&lt;/strong&gt; Registry drift. Fine if you only need country-level targeting; disqualifying if your task is city-specific.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do with a bad result
&lt;/h2&gt;

&lt;p&gt;Don't tune around it. If a pool leaks headers, serves datacenter ASNs under a residential label, or gives you six unique IPs out of twenty, that's structural — a bigger plan buys more of the same thing.&lt;/p&gt;

&lt;p&gt;The practical strategy is to make switching cheap:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Test on the smallest purchase possible&lt;/strong&gt; — providers that force large upfront commitments make you rationalise their flaws.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prefer traffic that doesn't expire&lt;/strong&gt;, so an unused balance from a failed test isn't a sunk cost pushing you to keep using a bad pool.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep two pools available&lt;/strong&gt; behind one config abstraction. 2026 killed several well-known proxy services with prepaid balances still on them — single-supplier setups went down with them.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;Run the script against whatever you're using now. Then run it against something else and compare — the numbers will make the decision for you, which is a much better position than choosing between two marketing pages.&lt;/p&gt;

&lt;p&gt;If you want a pool to test it against without a monthly commitment, that's what we built &lt;a href="https://go.proxyuniverse.org/dev-verify" rel="noopener noreferrer"&gt;ProxyUniverse&lt;/a&gt; for: residential, mobile, static ISP and dedicated IPv4 across 10+ networks on a single balance, pay-as-you-go, traffic that never expires. Buy the minimum, run the checks, decide with data.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you extend the script — concurrency handling, TLS timing, retry curves — drop it in the comments. I'd like to turn this into a proper little tool.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>webdev</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>The 2026 Proxy Purge: What Really Happened to 922, PIA S5 and LunaProxy</title>
      <dc:creator>Proxy Universe</dc:creator>
      <pubDate>Sat, 01 Aug 2026 10:04:39 +0000</pubDate>
      <link>https://dev.to/proxyuniverse/the-2026-proxy-purge-what-really-happened-to-922-pia-s5-and-lunaproxy-4l0e</link>
      <guid>https://dev.to/proxyuniverse/the-2026-proxy-purge-what-really-happened-to-922-pia-s5-and-lunaproxy-4l0e</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbfh9lvgw15ky3yk91m4g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbfh9lvgw15ky3yk91m4g.png" alt=" " width="800" height="1919"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The 2026 Proxy Purge: What Really Happened to 922, PIA S5 and LunaProxy
&lt;/h1&gt;

&lt;p&gt;If you run scraping pipelines or multi-account infrastructure, your Twitter feed in 2026 has looked like an obituary column: 922Proxy — dead. PIA S5 — client shut down. LunaProxy, PyProxy, IP2World, 360Proxy — domains not even resolving.&lt;/p&gt;

&lt;p&gt;This wasn't a coincidence, and it wasn't a market downturn. Here's what actually happened, verified from registry data and public threat-intelligence reports — and what it means for anyone whose infrastructure depends on residential proxies.&lt;/p&gt;

&lt;h2&gt;
  
  
  One takedown, many brands
&lt;/h2&gt;

&lt;p&gt;In January 2026, Google's Threat Intelligence Group disrupted the network behind IPIDEA. What most users never knew: IPIDEA wasn't one provider. Analysts published a list of affiliated brands, and it reads like the entire budget-S5 aisle: &lt;strong&gt;922Proxy, 360Proxy, LunaProxy, PIA S5, ABCProxy, IP2World&lt;/strong&gt; and more.&lt;/p&gt;

&lt;p&gt;These "different providers" with different logos, different dashboards and different Telegram support channels were, at the infrastructure level, largely one pool. When the core got disrupted, the storefronts died together. We ran DNS checks across the brand list in July 2026: &lt;code&gt;922proxy.com&lt;/code&gt;, &lt;code&gt;922s5.com&lt;/code&gt;, &lt;code&gt;lunaproxy.com&lt;/code&gt;, &lt;code&gt;pyproxy.com&lt;/code&gt;, &lt;code&gt;abcproxy.com&lt;/code&gt; — NXDOMAIN, all of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The zombie-brand problem
&lt;/h2&gt;

&lt;p&gt;Here's where it gets dangerous. The demand didn't die with the brands — Google autocomplete still suggests "s5 proxy 922" as the top completion for "s5 proxy". That orphaned demand attracts predators:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clone sites&lt;/strong&gt; registering hyphenated or swapped-TLD variants of dead brands, selling "the same service" through a lookalike dashboard. We found several already ranking. Before you trust a "revived" brand, check the domain's registration date via RDAP — a "10-year-old provider" on a domain registered in March 2026 is not the provider you knew.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Balance-recovery scams&lt;/strong&gt; targeting users whose prepaid IPs got locked inside dead clients.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The 9Proxy scare — a different story
&lt;/h2&gt;

&lt;p&gt;9Proxy went dark on June 28, 2026 and the community immediately filed it under "seized like the rest". The registry data never supported that: routine registrar lock, nameservers untouched, domain paid through 2027. It came back in mid-July — an unexplained outage, not a takedown. Different failure mode, same lesson: &lt;strong&gt;you can't tell an outage from a seizure from the inside, and your balance is hostage either way.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Engineering takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Treat proxy providers like any other third-party dependency.&lt;/strong&gt; Two suppliers minimum, health-checked, with traffic you can shift in minutes. If your scraper has retry logic but your proxy layer has a single vendor, you've just moved the SPOF.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prefer non-expiring, pay-as-you-go balances.&lt;/strong&gt; Subscriptions and time-boxed GB packs maximize your loss in a shutdown. Non-expiring GB means your exposure is only what you haven't burned yet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buy through channels with conversion paths.&lt;/strong&gt; PIA S5's desktop client died, but the network's GB API kept working — users who bought per-IP through the client got stuck; users on the API just kept going. When we route customers at &lt;a href="https://go.proxyuniverse.org/catalog" rel="noopener noreferrer"&gt;ProxyUniverse&lt;/a&gt;, we now explicitly prefer API-deliverable products for exactly this reason.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vet suppliers with registry data, not marketing.&lt;/strong&gt; RDAP is free. Domain age, registrar history, nameserver stability — five minutes of checking beats a locked balance.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The uncomfortable conclusion
&lt;/h2&gt;

&lt;p&gt;The budget residential proxy market runs on infrastructure whose ownership you can't audit, sold through brands that are sometimes just skins. That's not a reason to avoid it — the economics are unbeatable for a lot of legitimate work — but it is a reason to architect for provider death as a routine event, not an exception.&lt;/p&gt;

&lt;p&gt;The next purge will come. The only question is whether your pipeline notices.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I aggregate and monitor a dozen residential networks at &lt;a href="https://go.proxyuniverse.org/catalog" rel="noopener noreferrer"&gt;ProxyUniverse&lt;/a&gt; — one panel, per-GB pricing, no subscriptions. If your provider died this year, the catalog is a decent place to rebuild from.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>proxy</category>
      <category>webscraping</category>
      <category>security</category>
      <category>infrastructure</category>
    </item>
    <item>
      <title>80 Lines of Python That Keep My Scrapers Alive: Proxy Rotation with Retries, Health Checks &amp; Failover" published: false</title>
      <dc:creator>Proxy Universe</dc:creator>
      <pubDate>Sat, 25 Jul 2026 11:07:27 +0000</pubDate>
      <link>https://dev.to/proxyuniverse/80-lines-of-python-that-keep-my-scrapers-alive-proxy-rotation-with-retries-health-checks--31e</link>
      <guid>https://dev.to/proxyuniverse/80-lines-of-python-that-keep-my-scrapers-alive-proxy-rotation-with-retries-health-checks--31e</guid>
      <description>&lt;p&gt;Rotating proxies is easy. Surviving bans, timeouts and dead proxies is not. An 80-line Python rotator with health tracking and failover — copy-paste ready&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Rotating a list of proxies is easy. Rotating them &lt;em&gt;without your scraper dying&lt;/em&gt; when proxies get banned, time out, or return garbage is the part people get wrong. Below is a small, dependency-light proxy rotator that does retries, health tracking, and failover — copy-paste ready.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you scrape anything at scale, you already know the pain: you paste a list of proxies into a loop, it works for ten minutes, then half of them get rate-limited, three are dead, one returns a captcha page with HTTP 200, and your job silently produces junk. A naive &lt;code&gt;random.choice(proxies)&lt;/code&gt; doesn't cut it.&lt;/p&gt;

&lt;p&gt;This post builds a rotator that treats proxies like what they are — an unreliable resource pool — and keeps your scraper running anyway.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a real rotator needs
&lt;/h2&gt;

&lt;p&gt;Before code, the requirements that separate a toy from something you'd run in production:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Rotation&lt;/strong&gt; — spread requests across the pool so no single IP gets hammered.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retries&lt;/strong&gt; — a failed request should retry on a &lt;em&gt;different&lt;/em&gt; proxy, not the same dead one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health tracking&lt;/strong&gt; — proxies that fail repeatedly get benched; proxies that recover come back.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failure classification&lt;/strong&gt; — a timeout, a 407, a 429, and a captcha page are different problems and shouldn't be treated the same.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No heavy dependencies&lt;/strong&gt; — just &lt;code&gt;requests&lt;/code&gt;. (An async version at the end.)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 1: model a proxy with health
&lt;/h2&gt;

&lt;p&gt;Each proxy is more than a string — it carries a score we adjust as it succeeds or fails.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dataclasses&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dataclass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;


&lt;span class="nd"&gt;@dataclass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Proxy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;                      &lt;span class="c1"&gt;# "http://user:pass@host:port"
&lt;/span&gt;    &lt;span class="n"&gt;fails&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;                &lt;span class="c1"&gt;# consecutive failures
&lt;/span&gt;    &lt;span class="n"&gt;disabled_until&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;   &lt;span class="c1"&gt;# unix time; 0 means active
&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_available&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;disabled_until&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;penalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cooldown&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;60.0&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fails&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="c1"&gt;# exponential backoff: 60s, 120s, 240s...
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;disabled_until&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;cooldown&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fails&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;reward&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fails&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;disabled_until&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the exponential backoff: a proxy that keeps failing gets benched for longer each time, instead of being retried into the ground.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: the rotator
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;itertools&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;threading&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProxyRotator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proxy_urls&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_proxies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;Proxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;proxy_urls&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_cycle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;itertools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cycle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_proxies&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;threading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Proxy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Return the next available proxy, or wait for the soonest one.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_lock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_proxies&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
                &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_cycle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_available&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
            &lt;span class="c1"&gt;# all benched — return the one that frees up soonest
&lt;/span&gt;            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_proxies&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;disabled_until&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;alive_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_available&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_proxies&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;itertools.cycle&lt;/code&gt; gives round-robin rotation; the lock makes it thread-safe so you can use it from a thread pool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: the request wrapper with retries and classification
&lt;/h2&gt;

&lt;p&gt;This is the part that actually saves your job. We classify what went wrong and react accordingly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="c1"&gt;# treat these as "the proxy or target is refusing us"
&lt;/span&gt;&lt;span class="n"&gt;BAD_STATUS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;407&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;429&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;502&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;503&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rotator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ProxyRotator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;last_err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;proxy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rotator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;proxies&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;BAD_STATUS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;penalize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="n"&gt;last_err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HTTP &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="k"&gt;continue&lt;/span&gt;
            &lt;span class="c1"&gt;# crude captcha / block-page check on a 200
&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;captcha&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
                &lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;penalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cooldown&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;last_err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;captcha page&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="k"&gt;continue&lt;/span&gt;
            &lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reward&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;
        &lt;span class="nf"&gt;except &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timeout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;ConnectionError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;penalize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;last_err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;RuntimeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;all &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; attempts failed, last: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;last_err&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key details most tutorials miss:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;200 with a captcha&lt;/strong&gt; is a failure. Checking status code alone is not enough — sites return 200 on block pages constantly.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;407&lt;/strong&gt; means proxy auth failed — penalize the proxy, don't blame the target.&lt;/li&gt;
&lt;li&gt;We retry on a &lt;em&gt;fresh&lt;/em&gt; proxy each attempt, because retrying the same dead one is pointless.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 4: use it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;PROXIES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://user:pass@p1.provider.com:8000&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://user:pass@p2.provider.com:8000&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://user:pass@p3.provider.com:8000&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;rotator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ProxyRotator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PROXIES&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://httpbin.org/ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rotator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;| alive: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;rotator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;alive_count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;RuntimeError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;giving up on this URL:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it and watch &lt;code&gt;alive&lt;/code&gt; shrink and recover as proxies get benched and come back. That visibility alone will teach you more about your proxy pool's real quality than any provider's marketing page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Async version (for real throughput)
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;requests&lt;/code&gt; is synchronous. For thousands of URLs, here's the &lt;code&gt;aiohttp&lt;/code&gt; core — same rotator, async fetch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;aiohttp&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rotator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;proxy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rotator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;BAD_STATUS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;penalize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="k"&gt;continue&lt;/span&gt;
                &lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reward&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;except &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aiohttp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClientError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;TimeoutError&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;proxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;penalize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;rotator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ProxyRotator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PROXIES&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;aiohttp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ClientSession&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;fetch_async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rotator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Note: &lt;code&gt;aiohttp&lt;/code&gt; proxy auth needs the credentials in the &lt;code&gt;proxy&lt;/code&gt; URL, which our format already has.)&lt;/p&gt;

&lt;h2&gt;
  
  
  What this won't fix
&lt;/h2&gt;

&lt;p&gt;Honest limits, because your rotator is only as good as the proxies feeding it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A rotator can't fix a bad pool.&lt;/strong&gt; If your provider hands you already-flagged datacenter IPs, no amount of retry logic saves you. Rotating dead weight is still dead weight.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rotating too aggressively can &lt;em&gt;cause&lt;/em&gt; bans&lt;/strong&gt; for stateful tasks (logins, carts). For account work you want &lt;em&gt;sticky&lt;/em&gt; sessions, not rotation. Rotation is for stateless scraping.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free proxy lists&lt;/strong&gt; will make this code look broken because 90% of the pool is dead. The logic is fine; the input is garbage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the pool itself, you want residential or mobile IPs with real session control. I run mine through &lt;a href="https://proxyuniverse.org/en" rel="noopener noreferrer"&gt;ProxyUniverse&lt;/a&gt; — residential, mobile and ISP proxies that come as standard &lt;code&gt;host:port:user:pass&lt;/code&gt;, so they drop straight into the &lt;code&gt;PROXIES&lt;/code&gt; list above with no changes. After the 2026 provider shutdowns, I keep the pool spread across networks so one dying provider doesn't empty my rotator.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;The difference between a scraper that runs for ten minutes and one that runs for ten days is almost never the parsing code — it's how you handle the proxy layer failing. Health tracking + classified retries + failover is maybe 60 lines, and it's the 60 lines that matter.&lt;/p&gt;

&lt;p&gt;Grab the code, drop in your own proxies, and watch the &lt;code&gt;alive&lt;/code&gt; counter. If you build something on top of this (proxy scoring, per-domain pools, Prometheus metrics), I'd genuinely like to see it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question for the comments:&lt;/strong&gt; how do &lt;em&gt;you&lt;/em&gt; detect soft blocks — captcha pages and junk HTML that come back with a clean HTTP 200? That's the failure class this rotator handles worst, and I'm curious what checks people run in production. 👇&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webscraping</category>
      <category>python</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Best Proxies for Dating Sites like Match in 2026: Access, Privacy, and Avoiding Wrongful IP Bans</title>
      <dc:creator>Proxy Universe</dc:creator>
      <pubDate>Wed, 22 Jul 2026 18:39:08 +0000</pubDate>
      <link>https://dev.to/proxyuniverse/best-proxies-for-dating-sites-like-match-in-2026-access-privacy-and-avoiding-wrongful-ip-bans-344m</link>
      <guid>https://dev.to/proxyuniverse/best-proxies-for-dating-sites-like-match-in-2026-access-privacy-and-avoiding-wrongful-ip-bans-344m</guid>
      <description>&lt;p&gt;Dating platforms — Match, Tinder, Bumble, Hinge, OkCupid and the rest — are some of the most aggressively IP-policed sites on the internet. If you've ever been shadow-limited, geo-locked while traveling, or wrongly flagged after a single login from a new network, you've run into it. This guide explains how dating sites read your IP, and how to keep a clean, stable connection.&lt;/p&gt;

&lt;p&gt;I've supplied proxies to people working with dating platforms since 2023, and the recurring questions are always the same: which proxy type, which location, sticky or rotating. Here's the straight answer — plus a clear note on staying on the right side of the rules.&lt;/p&gt;

&lt;p&gt;Legitimate reasons people use proxies with dating sites&lt;br&gt;
Access while traveling or living abroad, where a platform limits or changes behavior by region.&lt;br&gt;
Privacy — not exposing your home IP and approximate location to a data-hungry platform.&lt;br&gt;
Stable location — keeping a consistent city/region so your matches and visibility don't scramble every time your ISP rotates your IP.&lt;br&gt;
Agencies and social-media managers legitimately operating a client's own profile from a fixed location.&lt;br&gt;
QA, testing and market research on how a platform behaves across regions.&lt;br&gt;
This article covers the networking layer for those cases. It is not a guide to deceiving people, and using proxies to run fake or fraudulent profiles violates every dating platform's terms and, in many places, the law. Don't. More on that at the end.&lt;/p&gt;

&lt;p&gt;Why dating sites are so sensitive to your IP&lt;br&gt;
Dating platforms fight fraud and spam constantly, so they lean hard on IP signals:&lt;/p&gt;

&lt;p&gt;IP reputation — datacenter and known-VPN ranges are heavily penalized or blocked. Dating apps block these faster than almost any other category of site.&lt;br&gt;
Geo consistency — your stated location, phone region, GPS and IP should agree. A profile set to Los Angeles logging in from a German datacenter is an instant red flag.&lt;br&gt;
IP churn — logging into one account from many different IPs in a short window looks like an account takeover and triggers verification or a lock.&lt;br&gt;
Shared-IP crowding — many accounts behind one IP is the classic spam signature.&lt;br&gt;
Datacenter proxies and public VPNs fail nearly all of these, which is exactly why people move to residential and mobile.&lt;/p&gt;

&lt;p&gt;Residential vs mobile vs datacenter for dating platforms&lt;br&gt;
Datacenter: fast and cheap, but the ranges are known and blacklisted. Dating apps detect these almost instantly. Not usable.&lt;/p&gt;

&lt;p&gt;Residential: real ISP IPs from homes. High trust, real geo, and you can lock to a specific city. This is the sensible default for a stable, natural-looking connection.&lt;/p&gt;

&lt;p&gt;Mobile (4G/5G): carrier IPs shared by huge numbers of real users, so they carry the highest trust — and mobile-first dating apps expect a mobile IP. This is often the strongest option for app-based platforms, at a higher cost per GB.&lt;/p&gt;

&lt;p&gt;Location and stability matter more than raw speed&lt;br&gt;
For dating platforms, a stable location beats everything. Pick the city you want to appear in, get a residential or mobile IP there, and match your device locale, timezone and (for apps) GPS region to it. Consistency is what reads as a normal user.&lt;/p&gt;

&lt;p&gt;Just as important: use a sticky (session) IP that stays the same across logins. Dating sites treat an account that hops IPs as suspicious. One account, one stable IP, held over time — that's the pattern that avoids verification loops and wrongful locks.&lt;/p&gt;

&lt;p&gt;A clean setup&lt;br&gt;
Residential or mobile IP in your target city, matched to device locale, timezone and region.&lt;br&gt;
A sticky session so the IP stays stable across sessions, not a rotating one.&lt;br&gt;
If a browser is involved, one clean browser profile tied to that one IP — don't mix.&lt;br&gt;
Standard host:port:user:pass (HTTP or SOCKS5), which drops into any browser, antidetect profile or mobile proxy tool.&lt;br&gt;
Warm up gradually; sudden bursts of activity from a fresh session look automated.&lt;br&gt;
Common mistakes&lt;br&gt;
Using datacenter proxies or free VPNs (blocked fastest of all).&lt;br&gt;
Letting the IP rotate between logins (looks like account takeover).&lt;br&gt;
Location on the profile not matching the IP or phone region.&lt;br&gt;
Sharing one IP across multiple accounts or people.&lt;br&gt;
A note on staying legitimate&lt;br&gt;
Proxies solve real access, privacy and stability problems. They do not make it acceptable to impersonate people, create fake or bulk profiles, or run romance scams — those harm real users, break platform rules everywhere, and are illegal in many jurisdictions. Payment processors, platforms and search engines all police this hard. Use proxies for legitimate access and privacy, not deception.&lt;/p&gt;

&lt;p&gt;What to use&lt;br&gt;
For dating platforms you want sticky residential or mobile IPs with precise city targeting, held stable over time. I run ProxyUniverse for this — residential, mobile and IPv4 across 10+ networks in one panel, with sticky sessions and city-level targeting, so you can keep one clean, stable IP per account.&lt;/p&gt;

&lt;p&gt;Whatever provider you choose, stability and a clean, well-located IP are what keep a dating connection trouble-free.&lt;/p&gt;

&lt;p&gt;TL;DR&lt;br&gt;
Dating sites ban on IP first and block datacenter ranges fastest. Use a sticky residential or mobile IP in your target city, match your locale, timezone and region to it, keep one stable IP per account, and never let it rotate between logins. And keep it legitimate — proxies are for access and privacy, not for fake profiles.&lt;/p&gt;

&lt;p&gt;What platform are you connecting to, and what's your setup? Happy to compare notes in the comments.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>proxy</category>
    </item>
    <item>
      <title>Don't Trust the Marketing Page: Score Your Proxy Provider's IP Quality in ~60 Lines of Python</title>
      <dc:creator>Proxy Universe</dc:creator>
      <pubDate>Tue, 21 Jul 2026 16:20:40 +0000</pubDate>
      <link>https://dev.to/proxyuniverse/dont-trust-the-marketing-page-score-your-proxy-providers-ip-quality-in-60-lines-of-python-1k7n</link>
      <guid>https://dev.to/proxyuniverse/dont-trust-the-marketing-page-score-your-proxy-providers-ip-quality-in-60-lines-of-python-1k7n</guid>
      <description>&lt;p&gt;&lt;em&gt;Subtitle: Every provider claims "clean residential IPs". After the 2026 outage wave I trust none of them — I test. Here's the scorer I run before putting money on any network: latency, fraud score, and ban-rate against real targets.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In my previous posts I covered building a failover layer and monitoring provider uptime. This closes the trilogy: how do you know a provider's IPs are actually good &lt;strong&gt;before&lt;/strong&gt; you commit a deposit?&lt;/p&gt;

&lt;p&gt;"Good" is measurable. For any proxy, three numbers tell you most of what matters:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Latency&lt;/strong&gt; — time to first byte through the proxy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fraud/abuse score&lt;/strong&gt; — is the IP already burned in reputation databases&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Target survival&lt;/strong&gt; — does the IP get challenged by the sites you actually care about&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The scorer
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;concurrent.futures&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;cf&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="c1"&gt;# proxies to test: grab 20-50 fresh IPs from the provider's gateway
&lt;/span&gt;&lt;span class="n"&gt;PROXIES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://user:pass@gate.provider.com:7777&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;# ... more sessions/IPs
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# swap for your real targets
&lt;/span&gt;&lt;span class="n"&gt;TARGETS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://www.amazon.com/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://www.google.com/search?q=test&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;IPINFO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://ipinfo.io/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;SCAMALYTICS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://scamalytics.com/ip/{ip}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;# manual check; API is paid
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_proxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proxy_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;proxy_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;proxy_url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;proxy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;proxy_url&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ok&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;# 1. latency + exit IP
&lt;/span&gt;    &lt;span class="n"&gt;t0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPINFO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proxies&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;latency_ms&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;t0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;exit_ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;geo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;country&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;city&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;org&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;org&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)[:&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;connect: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;

    &lt;span class="c1"&gt;# 2. datacenter smell test: residential orgs are ISPs, not clouds
&lt;/span&gt;    &lt;span class="n"&gt;dc_words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amazon&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;google&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;digitalocean&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ovh&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hetzner&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;m247&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;looks_dc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;org&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;dc_words&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 3. target survival: 200 = pass, 403/429/503 or captcha markers = burned
&lt;/span&gt;    &lt;span class="n"&gt;burned&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;TARGETS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;tr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proxies&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                              &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User-Agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mozilla/5.0 (Windows NT 10.0; Win64; x64)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="n"&gt;text_sample&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;4000&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;captcha&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text_sample&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;burned&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;burned&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;burned_targets&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;burned&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TARGETS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ok&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;cf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ThreadPoolExecutor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_workers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test_proxy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PROXIES&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;latency_ms&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;99999&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;good&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ok&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;looks_dc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;burned_targets&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;PASS: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;good&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
      &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(median latency &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;latency_ms&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ok&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])[&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;ms)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to read the results
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Latency.&lt;/strong&gt; Residential proxies add 300–900ms TTFB normally. Median above ~1.5s means an overloaded gateway — it won't get better under your production load.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The &lt;code&gt;looks_dc&lt;/code&gt; flag.&lt;/strong&gt; If a "residential" provider's exit IPs resolve to Amazon or M247 orgs, you're paying residential prices for datacenter IPs. Walk away. (This exact test has saved me from two providers this year.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Burned targets.&lt;/strong&gt; This is the one that matters most and the one no review can tell you, because it depends on &lt;em&gt;your&lt;/em&gt; targets. A pool that's clean for Amazon may be torched for sneaker sites. Test with 30+ IPs to get a real rate: anything above ~15% burned on first contact means the pool is oversold in your niche.&lt;/p&gt;

&lt;h2&gt;
  
  
  The workflow that actually protects you
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Deposit the minimum ($5–10) at any new provider.&lt;/li&gt;
&lt;li&gt;Pull 30–50 IPs, run the scorer against your real targets.&lt;/li&gt;
&lt;li&gt;Score again a week later — pool quality drifts as providers resell capacity.&lt;/li&gt;
&lt;li&gt;Keep results per provider; when quality drops two checks in a row, shift volume to your backup &lt;strong&gt;before&lt;/strong&gt; it becomes an emergency.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Step 4 is why I do all of this on an aggregator (&lt;a href="https://go.proxyuniverse.org/art-quality" rel="noopener noreferrer"&gt;one balance across 10+ networks&lt;/a&gt;) — moving volume between networks is a dropdown, not a new vendor onboarding. After watching PIA S5, IP2World, 922 S5 and 9Proxy users scramble this year, "migration is one click" stopped being a convenience and became the whole point.&lt;/p&gt;

&lt;p&gt;Next post: putting the three scripts together into a self-healing proxy layer with automatic weight shifting. If you want it sooner, say so in the comments.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>proxy</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Best Proxies for Online Surveys in 2026: Residential vs Mobile, Geo-Targeting, and a No-Ban Setup</title>
      <dc:creator>Proxy Universe</dc:creator>
      <pubDate>Fri, 17 Jul 2026 15:26:45 +0000</pubDate>
      <link>https://dev.to/proxyuniverse/best-proxies-for-online-surveys-in-2026-residential-vs-mobile-geo-targeting-and-a-no-ban-setup-2h5b</link>
      <guid>https://dev.to/proxyuniverse/best-proxies-for-online-surveys-in-2026-residential-vs-mobile-geo-targeting-and-a-no-ban-setup-2h5b</guid>
      <description>&lt;p&gt;If you take paid surveys or run survey accounts at any kind of scale, you already know the real bottleneck isn't finding surveys — it's not getting flagged, screened out, or banned. And nine times out of ten, the thing that gets you flagged is your IP.&lt;/p&gt;

&lt;p&gt;I've been supplying proxies to survey operators since 2023, and the same questions come up every week: which proxy type, which country, sticky or rotating, how many accounts per IP. This guide is the distilled answer.&lt;/p&gt;

&lt;p&gt;Why survey sites care so much about your IP&lt;/p&gt;

&lt;p&gt;Survey and market-research platforms make money by selling clean, unique respondents to their clients. So they invest heavily in filtering out anything that looks like duplicate or low-quality traffic. Your IP is the first signal they check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IP reputation — datacenter and known-VPN ranges get scored down or blocked outright.&lt;/li&gt;
&lt;li&gt;Geo consistency — if your profile says you're in Chicago but your IP resolves to a server farm in Frankfurt, you're screened out before question one.&lt;/li&gt;
&lt;li&gt;Uniqueness — multiple respondents from the same IP or subnet look like one person farming accounts.&lt;/li&gt;
&lt;li&gt;Timezone, language and IP alignment — mismatches between browser locale and IP geo are a classic flag.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Datacenter proxies fail almost all of these. That's why survey work is one of the clearest use cases for residential &lt;br&gt;
and mobile proxies.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fijcwwcvjzeqhn7jkldbp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fijcwwcvjzeqhn7jkldbp.png" alt=" " width="495" height="1003"&gt;&lt;/a&gt;&lt;br&gt;
Residential vs mobile vs datacenter for surveys&lt;/p&gt;

&lt;p&gt;Datacenter: cheap and fast, but the IP ranges are known and widely blacklisted by survey panels. Fine for scraping public pages, wrong tool for surveys. Skip.&lt;/p&gt;

&lt;p&gt;Residential: real ISP-assigned IPs from actual homes. This is the default choice for surveys — high trust score, real geo, and you can target specific countries and cities. The vast majority of survey operators I supply run residential.&lt;/p&gt;

&lt;p&gt;Mobile (4G/5G): carrier IPs shared by thousands of real users, so they carry very high trust and are the hardest to ban. Best when a survey platform is mobile-first, or when you need the absolute highest trust for high-value panels. More expensive per GB, so people usually reserve mobile for their most valuable accounts.&lt;/p&gt;

&lt;p&gt;Geo-targeting: pick the country before the proxy&lt;/p&gt;

&lt;p&gt;Survey payouts are not equal across countries. Tier-1 English-speaking geos — United States, United Kingdom, Canada, Australia — consistently pay the most per completed survey, because that's where the buying-power demographics are. Many high-value surveys are only offered to respondents in those countries.&lt;/p&gt;

&lt;p&gt;So the rule is simple: the account's declared country, the browser locale and timezone, and the proxy IP geo must all match. A US account needs a US residential IP, US timezone, en-US locale. Consistency is what keeps you in the high-paying survey queues instead of the "no surveys available" wall.&lt;/p&gt;

&lt;p&gt;Sticky sessions are non-negotiable&lt;/p&gt;

&lt;p&gt;This is the mistake that burns most beginners. Surveys are long — screeners, the main questionnaire, sometimes 10 to 30 minutes. If your IP rotates mid-survey, the platform sees the session jump IPs and voids the response, or bans the account.&lt;/p&gt;

&lt;p&gt;You want sticky (session) residential IPs: one stable IP held for the entire survey, ideally for the whole life of that account. Rotating proxies are for scraping, not for surveys. Configure a sticky session per account and leave it.&lt;/p&gt;

&lt;p&gt;A clean per-account setup that survives&lt;/p&gt;

&lt;p&gt;The setup that has worked for operators running anywhere from a handful to hundreds of accounts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One antidetect browser profile per survey account (AdsPower, Dolphin, GoLogin, Multilogin, and so on). Separate cookies, canvas, fonts and WebGL fingerprint per profile.&lt;/li&gt;
&lt;li&gt;One sticky residential IP per profile, in the account's country. Never share an IP across two accounts.&lt;/li&gt;
&lt;li&gt;Match locale, timezone and language to the IP geo.&lt;/li&gt;
&lt;li&gt;Keep the mapping stable: profile A always uses IP A. Don't shuffle IPs between profiles.&lt;/li&gt;
&lt;li&gt;Warm accounts up — don't blast 20 surveys in the first hour on a brand-new profile.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Proxy string format is the standard host:port:user:pass (HTTP or SOCKS5), which drops straight into any antidetect browser's proxy field.&lt;/p&gt;

&lt;p&gt;Common mistakes that get you banned&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using datacenter proxies (instant low trust).&lt;/li&gt;
&lt;li&gt;Rotating IPs mid-survey (voided responses).&lt;/li&gt;
&lt;li&gt;Piling multiple accounts on the same IP or subnet.&lt;/li&gt;
&lt;li&gt;IP in one country, browser locale and timezone in another.&lt;/li&gt;
&lt;li&gt;Reusing a residential IP that's already burned on the same panel.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A note on scale and rules&lt;/p&gt;

&lt;p&gt;Running many accounts is against most survey platforms' terms of service, so understand the risk before you scale. This guide is about the networking layer — how IPs are detected and how to keep sessions clean — not legal advice. Operate within the rules that apply to you.&lt;/p&gt;

&lt;p&gt;What to use&lt;/p&gt;

&lt;p&gt;For survey work you want sticky residential IPs with real country and city targeting, and mobile as a premium option for the highest-trust accounts. I run ProxyUniverse for this — residential, mobile and IPv4 across 10+ networks in one panel, with sticky sessions and country/city targeting, so you can keep one clean IP per account and switch networks if one degrades. Link: &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffldwrve0q5q88dzu62e2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffldwrve0q5q88dzu62e2.png" alt=" " width="495" height="1003"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1jrxwy8oaafilgvjascu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1jrxwy8oaafilgvjascu.png" alt=" " width="495" height="1003"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcskr3ah32584khb8mvcu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcskr3ah32584khb8mvcu.png" alt=" " width="495" height="1003"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whatever provider you pick, the checklist above is what actually keeps survey accounts alive.&lt;/p&gt;

&lt;p&gt;TL;DR&lt;/p&gt;

&lt;p&gt;Surveys get you banned on IP first. Use sticky residential IPs (mobile for premium accounts), match the country to high-payout geos like the US, UK, Canada and Australia, keep one IP per antidetect profile, and never rotate mid-survey. Get those five things right and your completion rate — and your earnings — stop bleeding out to screen-outs.&lt;/p&gt;

&lt;p&gt;What's your survey stack — which antidetect browser and proxy setup are you running? Curious how others structure it.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>vpn</category>
      <category>proxy</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Is 9Proxy Down in 2026? Verified Status, Timeline &amp; Best Alternatives</title>
      <dc:creator>Proxy Universe</dc:creator>
      <pubDate>Thu, 16 Jul 2026 17:25:25 +0000</pubDate>
      <link>https://dev.to/proxyuniverse/is-9proxy-down-in-2026-verified-status-timeline-best-alternatives-is-9proxy-down-in-2026-1fo</link>
      <guid>https://dev.to/proxyuniverse/is-9proxy-down-in-2026-verified-status-timeline-best-alternatives-is-9proxy-down-in-2026-1fo</guid>
      <description>&lt;p&gt;Last updated: July 16, 2026&lt;br&gt;
Quick answer: 9Proxy is not fully back. The public website loads again after going dark on June 28, 2026, but new purchases are still paused, the company has published no root cause, and full proxy stability is unconfirmed. If your workflow depends on it, keep a funded alternative running. Below is the verified timeline, what actually happened, whether it was "seized," and the alternatives that work right now.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1q4xmmv3m2kdu0lzf7uh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1q4xmmv3m2kdu0lzf7uh.png" alt=" " width="495" height="1003"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is 9Proxy down right now?&lt;/strong&gt;&lt;br&gt;
As of July 16, 2026:&lt;br&gt;
Website (9proxy.com): up. Homepage, login and docs respond.&lt;br&gt;
New purchases: still officially paused ("temporarily paused to support current customers first").&lt;br&gt;
Proxy service: partially restored, stability uneven across plans/regions per user reports.&lt;br&gt;
Root cause: never explained.&lt;br&gt;
So the honest description is "recovering, not recovered." A homepage that returns HTTP 200 is not proof your proxies authenticate, rotate and hold sessions — those are different systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happened&lt;/strong&gt;&lt;br&gt;
Reports clustered on June 28, 2026: the website wouldn't load, the desktop app timed out, active sessions dropped, and prepaid IP/GB balances became unusable. Support went quiet. This wasn't a marketing-site blip — login, dashboard, session generation and already-purchased capacity were all affected.&lt;br&gt;
On June 29, 9Proxy posted an identical notice to its Facebook page and its BlackHatWorld seller account: "We're currently experiencing a service disruption… our team has identified an unexpected issue… we're focused on a stable and secure recovery rather than a rushed fix… we don't have an exact restoration time yet." No cause, no ETA.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verified timeline&lt;/strong&gt;&lt;br&gt;
Jun 28 — Website + app down, sessions drop, balances locked.&lt;br&gt;
Jun 29 — Official "service disruption" notice (Facebook + BlackHatWorld), no cause/ETA.&lt;br&gt;
Jul 1 — Login + app still unavailable; homepage sometimes returns HTTP 200.&lt;br&gt;
~Jul 6 — First "it's working again" user comments (not an official all-clear).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why "HTTP 200" is not a proxy test&lt;/strong&gt;&lt;br&gt;
An uptime checker only confirms a web server answered. It does not verify a paying customer can:&lt;br&gt;
authenticate and see the correct balance,&lt;br&gt;
generate a residential endpoint,&lt;br&gt;
open an authenticated HTTP/SOCKS5 session,&lt;br&gt;
keep a sticky session alive,&lt;br&gt;
rotate to a fresh IP,&lt;br&gt;
get the requested country/city,&lt;br&gt;
actually reach the target site.&lt;br&gt;
That's why a status page can read "up" while users still report failures. Test authenticated sessions against your real targets before trusting production traffic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Was 9Proxy seized or shut down?&lt;/strong&gt;&lt;br&gt;
No credible evidence supports a seizure. The domain shows an ordinary registrar lock, unchanged Cloudflare nameservers, and registration paid through 2027 — no government banner, no agency, no court filing. The "seized" story traces back to a single competitor blog.&lt;br&gt;
For context, 2026 has been brutal for the proxy industry — the January IPIDEA-linked disruption (PIA S5, 922 S5, ABCProxy, Cherry Proxy) and the July NetNut/FBI action are real, better-attributed events. But sharing a calendar year with those isn't evidence. On verifiable facts, 9Proxy is a recovering service with paused sales, not a taken-down network.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9Proxy not working? Fast troubleshooting&lt;/strong&gt;&lt;br&gt;
Confirm it's them, not you — check a status monitor first.&lt;br&gt;
Re-authenticate — sign in fresh, verify balance, regenerate credentials.&lt;br&gt;
Update the desktop app — IP-based plans route through the client; timeouts often clear on the latest build.&lt;br&gt;
Test HTTP and SOCKS5 separately, and try a second location.&lt;br&gt;
Switch networks — rule out local firewall/DNS/ISP issues.&lt;br&gt;
Check the purchase pause — if you were topping up, that's expected right now.&lt;br&gt;
If sessions still fail, treat 9Proxy as unreliable for now and keep a funded fallback.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyqdluf2wwzhjddxr6a23.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyqdluf2wwzhjddxr6a23.png" alt=" " width="495" height="1003"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best 9Proxy alternatives in 2026&lt;/strong&gt;&lt;br&gt;
With sales paused and stability unproven, the smart move is to keep a working provider ready — even if you plan to return. These are residential-first, credible swaps:&lt;br&gt;
&lt;a href="https://go.proxyuniverse.org/711proxy" rel="noopener noreferrer"&gt;711Proxy&lt;/a&gt; — broad geo coverage for scraping and multi-accounting. Closest like-for-like swap. → &lt;a href="https://go.proxyuniverse.org/711proxy" rel="noopener noreferrer"&gt;https://go.proxyuniverse.org/711proxy&lt;/a&gt;&lt;br&gt;
&lt;a href="https://go.proxyuniverse.org/novproxy" rel="noopener noreferrer"&gt;NovProxy&lt;/a&gt; — clean residential pool, straightforward pricing. → &lt;a href="https://go.proxyuniverse.org/novproxy" rel="noopener noreferrer"&gt;https://go.proxyuniverse.org/novproxy&lt;/a&gt;&lt;br&gt;
&lt;a href="https://go.proxyuniverse.org/swiftproxy" rel="noopener noreferrer"&gt;Swiftproxy&lt;/a&gt; — value residential with sticky sessions. → &lt;a href="https://go.proxyuniverse.org/swiftproxy" rel="noopener noreferrer"&gt;https://go.proxyuniverse.org/swiftproxy&lt;/a&gt;&lt;br&gt;
&lt;a href="https://go.proxyuniverse.org/residential" rel="noopener noreferrer"&gt;IPRocket&lt;/a&gt; / LokiProxy — solid residential options worth benchmarking. → &lt;a href="https://go.proxyuniverse.org/residential" rel="noopener noreferrer"&gt;https://go.proxyuniverse.org/residential&lt;/a&gt;&lt;br&gt;
PIA Proxy GB — pay-per-GB, maps cleanly onto 9Proxy's GB budgeting. → &lt;a href="https://go.proxyuniverse.org/pia-gb" rel="noopener noreferrer"&gt;https://go.proxyuniverse.org/pia-gb&lt;/a&gt;&lt;br&gt;
&lt;a href="https://go.proxyuniverse.org/mobile" rel="noopener noreferrer"&gt;Mobile proxies&lt;/a&gt; — if you need true mobile IPs, not residential. → &lt;a href="https://go.proxyuniverse.org/mobile" rel="noopener noreferrer"&gt;https://go.proxyuniverse.org/mobile&lt;/a&gt;&lt;br&gt;
Migrate in stages: move 20–30% of traffic first, measure connection + target success rates, then scale.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fon6hblsx8f2y1npu6uj3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fon6hblsx8f2y1npu6uj3.png" alt=" " width="495" height="1003"&gt;&lt;/a&gt;&lt;br&gt;
Buy the alternatives cheaper — from one panel&lt;br&gt;
Here's the real lesson of this outage: a single provider is a single point of failure. When 9Proxy went dark, customers couldn't even reach money they'd already paid for.&lt;br&gt;
ProxyUniverse is a multi-provider panel — 711Proxy, NovProxy, Swiftproxy, IPRocket, PIA GB and mobile in one dashboard. Because it aggregates several networks, per-unit prices are often lower than buying direct, and you can switch networks the moment one starts failing — exactly the resilience an outage like this rewards. Diversify across providers and no single blackout ever locks you out again. → &lt;a href="https://go.proxyuniverse.org/catalog" rel="noopener noreferrer"&gt;https://go.proxyuniverse.org/catalog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;9Proxy refund &amp;amp; prepaid balance&lt;br&gt;
9Proxy's terms: GB traffic stays valid 180 days; unused IP balances don't expire — a paused store doesn't erase what you already bought.&lt;br&gt;
There are no monetary refunds (only automatic replacement of a dead IP within 60 seconds of allocation).&lt;br&gt;
If you can't reach a paid balance: open a support ticket, keep records (dates, screenshots, error codes), and if you paid by card with no resolution, a chargeback is the standard fallback.&lt;br&gt;
Because purchases are still paused, don't commit new spend to 9Proxy right now — keep a funded alternative running instead.&lt;/p&gt;

&lt;p&gt;FAQ&lt;br&gt;
Is 9Proxy down right now? Not completely — the site is back, but new purchases are paused and full stability is unconfirmed (as of July 16, 2026).&lt;br&gt;
Did 9Proxy get shut down / seized? No evidence of a seizure. It's an unconfirmed outage; the domain and registry look normal.&lt;br&gt;
When did the outage start? June 28, 2026.&lt;br&gt;
Can I get my money / balance back? GB stays valid 180 days and IP balances don't expire; no cash refunds. Keep records; chargeback as last resort.&lt;br&gt;
What are the best alternatives? 711Proxy, NovProxy, Swiftproxy, PIA GB — all available in one panel via ProxyUniverse.&lt;/p&gt;

&lt;p&gt;~Jul 8 — New "server down / all proxies failing" reports resurface.&lt;br&gt;
Jul 15 — Site stable (~99.86% uptime on monitors); new purchases still paused.&lt;br&gt;
There is no confirmed full-restoration date.&lt;/p&gt;

</description>
      <category>proxy</category>
      <category>webscraping</category>
      <category>privacy</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
