<?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: 全网低价IP</title>
    <description>The latest articles on DEV Community by 全网低价IP (@socks5ip).</description>
    <link>https://dev.to/socks5ip</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%2F4127732%2Fa534ece7-c74c-4d1b-922e-04c4aa8b408e.jpg</url>
      <title>DEV Community: 全网低价IP</title>
      <link>https://dev.to/socks5ip</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/socks5ip"/>
    <language>en</language>
    <item>
      <title>Concurrency, Connections, Threads: Which Number Your Proxy Plan Actually Meters</title>
      <dc:creator>全网低价IP</dc:creator>
      <pubDate>Mon, 02 Nov 2026 02:08:58 +0000</pubDate>
      <link>https://dev.to/socks5ip/concurrency-connections-threads-which-number-your-proxy-plan-actually-meters-48ff</link>
      <guid>https://dev.to/socks5ip/concurrency-connections-threads-which-number-your-proxy-plan-actually-meters-48ff</guid>
      <description>&lt;p&gt;You raised the thread count because requests were timing out. Throughput improved for an afternoon, then the provider's endpoint started returning errors and half the workers stalled. The plan advertised 200 concurrency, so the ceiling was supposed to be somewhere far away.&lt;/p&gt;

&lt;p&gt;Four different numbers get described as "how much you can run at once", and they sit on three different layers. Mixing them up is how people buy a bigger tier to fix a problem that was never on the provider's side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four terms, three layers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Numbers that live here&lt;/th&gt;
&lt;th&gt;Who sets it&lt;/th&gt;
&lt;th&gt;What exceeding it looks like&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Your machine&lt;/td&gt;
&lt;td&gt;threads, open sockets, upstream bandwidth&lt;/td&gt;
&lt;td&gt;your client settings, your NIC&lt;/td&gt;
&lt;td&gt;queueing, timeouts, CPU or bandwidth saturation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Your plan&lt;/td&gt;
&lt;td&gt;concurrency, rotation quota, extraction frequency, IP allowlist&lt;/td&gt;
&lt;td&gt;the provider, per tier&lt;/td&gt;
&lt;td&gt;endpoint rejection or a limit-exceeded message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The destination&lt;/td&gt;
&lt;td&gt;per-IP rate limits, fingerprint scoring&lt;/td&gt;
&lt;td&gt;the site you are calling&lt;/td&gt;
&lt;td&gt;CAPTCHAs and 429s however many IPs you rotate&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That third row is where the money goes missing. When the destination throttles you, more concurrency and more threads make it worse. Backing both off is frequently the actual fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Threads are yours; concurrency is theirs
&lt;/h2&gt;

&lt;p&gt;Concurrency is an authorisation number printed on the plan: connections the provider agrees to hold open for you at one instant. It is a contract, not a measurement.&lt;/p&gt;

&lt;p&gt;Threads are your own parallelism unit inside a scraper or a multi-boxing tool. Connection count is what the machine is holding right now — visible in Proxifier, NekoBox, or &lt;code&gt;ss -tn&lt;/code&gt;. The three move together, but not one to one.&lt;/p&gt;

&lt;p&gt;A thread that issues one request and waits holds one connection. A thread with keep-alive across ten hosts can hold ten.&lt;/p&gt;

&lt;p&gt;So "raise the threads" pushes on all three layers at once. Hit your machine's wall first and you get timeouts with a sagging success rate. Hit the plan's wall first and you get endpoint errors. The symptoms differ, so read them before changing anything.&lt;/p&gt;

&lt;p&gt;Do the arithmetic before upgrading: 40 threads touching two hosts each is up to 80 sockets. Against a tier that allows 50 concurrency, a configuration with "only" 40 threads is already over.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extraction frequency is a rhythm, not a capacity
&lt;/h2&gt;

&lt;p&gt;Extraction frequency governs how often you may call the endpoint that hands out new IPs. It says nothing about how long an IP stays usable — that is session length or rotation quota, a separate line item.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Rhythm&lt;/th&gt;
&lt;th&gt;Fits&lt;/th&gt;
&lt;th&gt;Watch out for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Timed batch&lt;/td&gt;
&lt;td&gt;one list per fixed interval&lt;/td&gt;
&lt;td&gt;crawling, batch registration&lt;/td&gt;
&lt;td&gt;missing the window costs a whole cycle; the script must wait&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;On-demand&lt;/td&gt;
&lt;td&gt;one call, immediate response&lt;/td&gt;
&lt;td&gt;flash sales, short bursts&lt;/td&gt;
&lt;td&gt;the rate cap usually tracks the tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Manual pull&lt;/td&gt;
&lt;td&gt;a human clicks in a dashboard&lt;/td&gt;
&lt;td&gt;topping up a handful of IPs&lt;/td&gt;
&lt;td&gt;cannot be scripted, so it does not scale&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;One question decides which pattern you need: does a script or a human trigger the rotation? If a script does, the interval and its retries belong in the code, with a backoff that respects the window.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measure your own ceiling
&lt;/h2&gt;

&lt;p&gt;Provider pages describe the tier, not your NIC, your CPU, or your distance from the exit. The only trustworthy number is the one you measure, and it takes about ten minutes.&lt;/p&gt;

&lt;p&gt;Ramp the level and record the first failure. A minimal SOCKS5 greeting is enough to test connection slots — you do not need to fetch a real page to find out when sockets stop opening.&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;socket&lt;/span&gt;&lt;span class="p"&gt;,&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;concurrent.futures&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ThreadPoolExecutor&lt;/span&gt;

&lt;span class="n"&gt;PROXY&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;203.0.113.10&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1080&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;          &lt;span class="c1"&gt;# your exit
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;probe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;):&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;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_connection&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;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x05\x01\x00&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                     &lt;span class="c1"&gt;# ver 5, 1 method, no-auth
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x05\x00&lt;/span&gt;&lt;span class="sh"&gt;"&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="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x05\x01\x00\x01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inet_aton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1.1.1.1&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="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;big&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&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;# REP byte
&lt;/span&gt;        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;return &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="n"&gt;ok&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;OSError&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;for&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&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="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;with&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;level&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;probe&lt;/span&gt;&lt;span class="p"&gt;,&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;level&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
    &lt;span class="n"&gt;ok&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="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="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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;p50&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;p50=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ok&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;ok&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="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="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="sh"&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;level&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;ok=&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;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&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;p50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read the output as a curve, not a single figure. The level just before the success rate drops is your sustainable setting; the level just before median latency doubles is your burst setting. Re-run after changing machines, exits, or targets, because the line moves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Five mistakes that cost a tier upgrade
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reading "unlimited" as unlimited concurrency.&lt;/strong&gt; It usually modifies rotation count. Concurrency is a separate authorisation, often printed in the same table two columns away.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Counting threads and calling it concurrency.&lt;/strong&gt; Threads are yours and are bounded by hardware, not by the plan.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assuming a missing allowlist entry means a dead line.&lt;/strong&gt; An unauthorised source returns an endpoint-level rejection while the exit is perfectly reachable. If the socket opens, the line is not the problem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rotating IPs to escape a destination rate limit.&lt;/strong&gt; Per-IP limits reset; account and fingerprint signals do not. More IPs against one account is the standard way to burn a whole pool.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sizing on peak, buying on average.&lt;/strong&gt; Pick the tier from the level you can hold for a full business cycle, not from a burst you hit twice a day.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is concurrency the same as connection count?&lt;/strong&gt; No. Concurrency is the cap the provider grants per tier; connection count is what your machine holds right now. Compare them deliberately or you will never know which one you exceeded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The plan says unlimited — can I run unlimited threads then?&lt;/strong&gt; No. Unlimited typically refers to rotations. Your host still has a socket and bandwidth ceiling, and the tier lists concurrency separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why do I get CAPTCHAs with 200 healthy exits?&lt;/strong&gt; Because the limit lives at the destination, not in your pool. Per-IP limits may reset while account and fingerprint signals persist across rotations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I rotated faster and throughput fell. Why?&lt;/strong&gt; Every rotation costs a handshake, a TLS session, and often a cold cookie jar. Past some point the switching cost exceeds the gain, and the pool looks healthy while success rate drops.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to verify the numbers
&lt;/h2&gt;

&lt;p&gt;Term definitions and per-tier comparisons sit side by side at the &lt;a href="https://socks5ip.com.cn/daili-ip-zhishiku/" rel="noopener noreferrer"&gt;proxy IP knowledge base&lt;/a&gt;, and exits can be measured before you commit at the &lt;a href="https://socks5ip.com.cn/ip-check-center/" rel="noopener noreferrer"&gt;IP check center&lt;/a&gt;. If a tier's wording is ambiguous, ask the vendor to confirm the concurrency cap and the rotation quota in writing before paying — those two numbers, not the headline price, decide whether the plan fits.&lt;/p&gt;

</description>
      <category>networking</category>
      <category>performance</category>
      <category>python</category>
      <category>devops</category>
    </item>
    <item>
      <title>Your SOCKS5 Proxy Works Fine. Your DNS Is What Leaks the Location.</title>
      <dc:creator>全网低价IP</dc:creator>
      <pubDate>Thu, 29 Oct 2026 02:20:12 +0000</pubDate>
      <link>https://dev.to/socks5ip/your-socks5-proxy-works-fine-your-dns-is-what-leaks-the-location-4mdl</link>
      <guid>https://dev.to/socks5ip/your-socks5-proxy-works-fine-your-dns-is-what-leaks-the-location-4mdl</guid>
      <description>&lt;p&gt;You pointed a client at a SOCKS5 exit, checked the address, and it geolocates to the country you paid for. Then the site still serves you the home-language version, and a login from an unfamiliar city shows up in the account history two days later.&lt;/p&gt;

&lt;p&gt;The tunnel is not broken. SOCKS5 is a connect verb over a byte pipe — it carries exactly the traffic you hand it, from the process you configured. Name resolution is a separate conversation, and it habitually happens outside that pipe.&lt;/p&gt;

&lt;h2&gt;
  
  
  One byte decides where the lookup happens
&lt;/h2&gt;

&lt;p&gt;RFC 1928 defines a single request type that matters here. The client asks the proxy to open a TCP connection to a destination, and the destination is encoded in the &lt;code&gt;ATYP&lt;/code&gt; field:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ATYP=0x01&lt;/code&gt; — a raw IPv4 address. The client already resolved the name itself, so the DNS query left through the machine's own resolver before the tunnel was ever involved.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ATYP=0x03&lt;/code&gt; — a domain name. The client hands over the hostname and the proxy resolves it on the exit side.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ATYP=0x04&lt;/code&gt; — an IPv6 address, with the same consequence as &lt;code&gt;0x01&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So "SOCKS5 is configured" covers two different behaviours, decided by one byte set by a library flag most people never read.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who resolves the name, by client
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Client and setting&lt;/th&gt;
&lt;th&gt;ATYP sent&lt;/th&gt;
&lt;th&gt;Resolver actually used&lt;/th&gt;
&lt;th&gt;Leaks&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;curl --socks5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0x01&lt;/td&gt;
&lt;td&gt;local stub resolver&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;curl --socks5-hostname&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0x03&lt;/td&gt;
&lt;td&gt;proxy egress&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PySocks, &lt;code&gt;rdns=False&lt;/code&gt; (default)&lt;/td&gt;
&lt;td&gt;0x01&lt;/td&gt;
&lt;td&gt;local stub resolver&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PySocks, &lt;code&gt;rdns=True&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;0x03&lt;/td&gt;
&lt;td&gt;proxy egress&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chromium &lt;code&gt;--proxy-server=socks5://&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;0x03&lt;/td&gt;
&lt;td&gt;proxy egress&lt;/td&gt;
&lt;td&gt;only via DoH or bypass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OS-wide TUN on a router&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;whatever the host emits&lt;/td&gt;
&lt;td&gt;depends on port 53&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The two &lt;code&gt;curl&lt;/code&gt; flags look interchangeable and are not. A scraper moved from &lt;code&gt;--socks5-hostname&lt;/code&gt; to &lt;code&gt;--socks5&lt;/code&gt; keeps working perfectly while quietly publishing every hostname it visits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three escape paths that survive a working tunnel
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The client resolves locally.&lt;/strong&gt; This is the common case; most HTTP libraries default to it. Nothing about the exit looks wrong afterwards — the IP and the ASN are correct — but a resolver upstream logged every domain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UDP port 53 never enters the tunnel.&lt;/strong&gt; A SOCKS5 &lt;code&gt;CONNECT&lt;/code&gt; is TCP-only. Plain DNS over UDP is simply not carried, so an app-level proxy setting leaves the system resolver untouched. &lt;code&gt;UDP ASSOCIATE&lt;/code&gt; exists for this, but support on the proxy side is uneven and most clients never request it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Split tunneling on a network-level tunnel.&lt;/strong&gt; L2TP with default-gateway routing disabled, or a TUN interface with a bypass list, sends the resolver query out of the physical interface while the browser still shows the remote address. The tunnel is up; one route is wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Symptom to cause to fix
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What you observe&lt;/th&gt;
&lt;th&gt;What it means&lt;/th&gt;
&lt;th&gt;What actually fixes it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Exit IP correct, site language still local&lt;/td&gt;
&lt;td&gt;names resolved locally (&lt;code&gt;ATYP=0x01&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;switch the client to remote resolution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Proxy on, unrelated apps still resolve&lt;/td&gt;
&lt;td&gt;app-level scoping only&lt;/td&gt;
&lt;td&gt;drop or redirect outbound 53 at the gateway&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tunnel up, leak test shows home resolver&lt;/td&gt;
&lt;td&gt;split tunneling&lt;/td&gt;
&lt;td&gt;restore default route, push DNS to the tunnel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fixed by restarting the browser only&lt;/td&gt;
&lt;td&gt;resolver or browser cache&lt;/td&gt;
&lt;td&gt;flush, then retest with a fresh hostname&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The fourth row is worth sitting with. A test run right after a fix can measure the state before the fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proving it with 20 lines
&lt;/h2&gt;

&lt;p&gt;This performs the handshake by hand and sends &lt;code&gt;ATYP=0x03&lt;/code&gt;, which delegates resolution to the exit. Run it against a hostname that only the exit can resolve, then block outbound port 53 and run it again.&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;socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;struct&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;socks5_connect_domain&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;pport&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dport&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_connection&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;pport&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;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x05\x01\x00&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                  &lt;span class="c1"&gt;# VER, NMETHODS, NO-AUTH
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x05\x00&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;OSError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;method negotiation failed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;idna&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x05\x01\x00\x03&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;bytes&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;name&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;H&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dport&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                              &lt;span class="c1"&gt;# ATYP=0x03: exit resolves
&lt;/span&gt;    &lt;span class="n"&gt;rep&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&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;if&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;rep&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;rep&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;OSError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SOCKS5 reply code %s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rep&lt;/span&gt;&lt;span class="p"&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;if&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;rep&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;short&lt;/span&gt;&lt;span class="sh"&gt;"&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;s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the second run still connects while &lt;code&gt;socket.getaddrinfo()&lt;/code&gt; for the same name fails, your names are being resolved inside the tunnel — that is the behaviour you want, and it is now measured rather than assumed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistakes that keep the leak alive
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Treating a browser proxy extension as an operating-system setting. It is not; every other process keeps its own path out.&lt;/li&gt;
&lt;li&gt;Copying &lt;code&gt;--socks5&lt;/code&gt; instead of &lt;code&gt;--socks5-hostname&lt;/code&gt; into a scraper template, then wondering why the exit logs look clean and the target still localises you.&lt;/li&gt;
&lt;li&gt;Enabling DNS over HTTPS to "solve" leaks while DoH is pinned to a provider outside the tunnel. The query moved; it did not move into the pipe.&lt;/li&gt;
&lt;li&gt;Believing the leak-test page, when that page was itself loaded through the proxy. Test from the machine's own stack with port 53 blocked.&lt;/li&gt;
&lt;li&gt;Ignoring negative caching and TTLs, then re-testing inside the same minute and reading a stale answer as a regression.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does SOCKS5 carry DNS at all?&lt;/strong&gt;&lt;br&gt;
Yes, through &lt;code&gt;ATYP=0x03&lt;/code&gt; for TCP destinations, and through &lt;code&gt;UDP ASSOCIATE&lt;/code&gt; if the proxy implements it. Neither is automatic — the client has to choose it, which is why library defaults matter more than the proxy vendor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is DNS over HTTPS a fix?&lt;/strong&gt;&lt;br&gt;
It relocates the resolver, and whether that relocation is inside the tunnel depends entirely on where DoH is configured. Configured inside the proxy scope it helps; configured on the device with a bypass list it is another exit path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Port 53 is blocked but names still resolve. Why?&lt;/strong&gt;&lt;br&gt;
Something is answering without a network query: a stub resolver cache, a browser's own resolver, or a DoH endpoint over 443. Flush, use a hostname never queried before, and repeat.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does this affect API clients and scrapers, not just browsers?&lt;/strong&gt;&lt;br&gt;
It affects them more. Browsers usually delegate hostnames correctly; Python, Go and Node clients often resolve locally by default, and their traffic never looks different from the outside.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this sits in a proxy stack
&lt;/h2&gt;

&lt;p&gt;Resolution policy is a property of the client, not of the exit, so a clean IP reputation and a correct tunnel still leave one path open until the client is configured to delegate. The DNS leak detection walkthrough on &lt;a href="https://socks5ip.com.cn/ip-tools/ip-security/dnsxieloujiancejiaocheng/" rel="noopener noreferrer"&gt;socks5ip.com.cn&lt;/a&gt; covers the per-platform fixes, and the &lt;a href="https://socks5ip.com.cn/ip-check-center/" rel="noopener noreferrer"&gt;IP check centre&lt;/a&gt; confirms what the exit actually looks like to the outside before you go chasing resolver behaviour.&lt;/p&gt;

&lt;p&gt;Measure the path, then fix one layer at a time. A tunnel that carries the names is worth more than a larger pool of addresses.&lt;/p&gt;

</description>
      <category>networking</category>
      <category>security</category>
      <category>python</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Region Locks Are Not IP Locks: What a Proxy Actually Changes for Overseas Game Clients</title>
      <dc:creator>全网低价IP</dc:creator>
      <pubDate>Mon, 26 Oct 2026 02:04:26 +0000</pubDate>
      <link>https://dev.to/socks5ip/region-locks-are-not-ip-locks-what-a-proxy-actually-changes-for-overseas-game-clients-4dkj</link>
      <guid>https://dev.to/socks5ip/region-locks-are-not-ip-locks-what-a-proxy-actually-changes-for-overseas-game-clients-4dkj</guid>
      <description>&lt;p&gt;You buy a residential exit in the right country, log in, and the client still greets you in the wrong language. The store prices in the wrong currency, matchmaking drops you into the wrong pool, and a verification prompt appears two sessions later.&lt;/p&gt;

&lt;p&gt;The instinct is to blame the exit. Usually the exit is doing exactly what you paid for. A game client does not consult a single "region" — it reads four different signals, and a proxy only writes to one of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four signals, one of which you control
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;IP geolocation at the edge.&lt;/strong&gt; The publisher queries a commercial geo database with your exit address. This is the only signal your proxy rewrites directly — and it rewrites it in &lt;em&gt;their&lt;/em&gt; vendor's database, which may not agree with the lookup tool you used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Store and account country.&lt;/strong&gt; Fixed when the account was created or by the issuing country of the payment instrument on file. This is an account attribute, not a network one, so no amount of re-routing moves it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Measured latency.&lt;/strong&gt; Matchmaking picks a datacenter by round-trip time, not by the country string in your IP record. A block registered in Frankfurt that tunnels traffic back to Singapore measures like Singapore.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Behavioural history.&lt;/strong&gt; Login countries, device IDs, time-of-day patterns. This one only degrades when you change exits — it never improves by changing them.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;Source of truth&lt;/th&gt;
&lt;th&gt;Does swapping the exit IP change it?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;IP geolocation&lt;/td&gt;
&lt;td&gt;Publisher's geo vendor&lt;/td&gt;
&lt;td&gt;Yes — but only in their view of the address&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Store/account country&lt;/td&gt;
&lt;td&gt;Account creation, payment instrument&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Matchmaking pool&lt;/td&gt;
&lt;td&gt;RTT measured to datacenter&lt;/td&gt;
&lt;td&gt;Partly — by physics, not by registration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trust score&lt;/td&gt;
&lt;td&gt;Login history, device fingerprint&lt;/td&gt;
&lt;td&gt;No, and it usually gets worse&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why the store region stays put
&lt;/h2&gt;

&lt;p&gt;Most storefronts bind purchase region to the country of the payment method, because that is the field with a bank behind it. Your IP is a hint; the card's issuing country is a fact.&lt;/p&gt;

&lt;p&gt;This is why "buy a local IP, get local prices" fails so consistently. The store accepts the new IP and then declines the purchase because the instrument does not match the region you switched into.&lt;/p&gt;

&lt;p&gt;Console ecosystems are stricter still: the account's country is chosen at creation and changing it typically requires a local payment method plus a support path. A proxy is not part of that flow at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Audit instead of guessing
&lt;/h2&gt;

&lt;p&gt;Measure two things from the same machine: what the exit looks like to a geo database, and how far the traffic actually travels. If the country says "close" and the RTT says otherwise, the block is resold or tunnelled.&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;socket&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="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&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;steam&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;store.steampowered.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;riot-na&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;na.leagueoflegends.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&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;rtt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;best&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;_&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;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;settimeout&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="n"&gt;t&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="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&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;t&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="n"&gt;best&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="k"&gt;else&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;best&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d&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;OSError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;pass&lt;/span&gt;
        &lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&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;if&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="k"&gt;else&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;best&lt;/span&gt;&lt;span class="p"&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;exit_info&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlopen&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://api.ipapi.is/&lt;/span&gt;&lt;span class="sh"&gt;"&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;8&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="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&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;read&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;d&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;location&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;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;d&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;asn&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;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="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;exit:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;exit_info&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&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="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="nf"&gt;items&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="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;s&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;rtt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&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="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;p&gt;Read the pair together, not separately. A US-registered exit measuring 190 ms to a US endpoint is not in the US — the announcement is American, the packet path is not. A non-US-registered exit measuring 20 ms to a US endpoint is where it claims not to be, and the game will still see the wrong country, because the edge lookup runs before any latency measurement.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Likely cause&lt;/th&gt;
&lt;th&gt;What actually fixes it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Store keeps old currency&lt;/td&gt;
&lt;td&gt;Purchase region bound to payment instrument&lt;/td&gt;
&lt;td&gt;Local payment method; a new account in-region&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Country correct, RTT 150 ms+&lt;/td&gt;
&lt;td&gt;Resold block tunnelled back to origin&lt;/td&gt;
&lt;td&gt;An exit with genuine local egress&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verification prompt after switch&lt;/td&gt;
&lt;td&gt;Login country jumped between sessions&lt;/td&gt;
&lt;td&gt;Stable exit per account; match prior country first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Matchmade into the wrong pool&lt;/td&gt;
&lt;td&gt;Matchmaker uses its own RTT probe&lt;/td&gt;
&lt;td&gt;Exit nearer the datacenter, not "nearer the country"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Worked for weeks, then dead&lt;/td&gt;
&lt;td&gt;Block re-classified as hosting or VPN&lt;/td&gt;
&lt;td&gt;Rotate exits and re-check purity before reusing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Five mistakes worth avoiding
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Judging an exit by a country string alone.&lt;/strong&gt; Run the RTT probe; the string is a database opinion.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forcing a store region with a foreign card.&lt;/strong&gt; You get declines, and in some cases a frozen account.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Changing exit mid-session.&lt;/strong&gt; Logging in from one country and purchasing from another ten minutes later is the pattern fraud systems are built to catch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assuming SOCKS5 handles game traffic.&lt;/strong&gt; TCP works everywhere; most titles also need UDP, and UDP relay (RFC 1928 &lt;code&gt;UDP ASSOCIATE&lt;/code&gt;) is optional and unevenly implemented by both proxies and clients.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treating a fixed exit as a permanent asset.&lt;/strong&gt; Residential blocks get reclassified. Re-audit monthly, not once.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does a proxy change my game store region?&lt;/strong&gt;&lt;br&gt;
No. The store region is an account attribute tied to your payment instrument's issuing country. The proxy changes which country the store &lt;em&gt;thinks you are browsing from&lt;/em&gt;, which affects pricing display and availability in some cases, but it does not rewrite the purchase region itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is my ping unchanged after switching to a "local" IP?&lt;/strong&gt;&lt;br&gt;
Because ping measures the packet path, not the registration record. If the block is announced locally but tunnels back to another continent, RTT reflects the tunnel. Check the pair — country and RTT — before concluding the proxy is slow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I play over SOCKS5?&lt;/strong&gt;&lt;br&gt;
For TCP-based traffic, yes. Many games and nearly all voice chat need UDP, which requires the proxy to support &lt;code&gt;UDP ASSOCIATE&lt;/code&gt; and the client to implement it. A router-level setup or a client with a UDP relay path is usually more reliable than a browser-style SOCKS5 proxy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Will switching countries flag my account?&lt;/strong&gt;&lt;br&gt;
It can. Rapid country changes on an established account are a recognisable pattern, and the response is usually a verification challenge rather than a ban. Keep one stable exit per account and change countries deliberately, not casually.&lt;/p&gt;

&lt;p&gt;Region selection is really a consistency problem: the exit, the account, and the measured path have to tell the same story. The &lt;a href="https://socks5ip.com.cn/zuixinzixun/wangchuangxiangmu/youxiipshishenme/" rel="noopener noreferrer"&gt;guide to region-based IP selection for overseas game clients&lt;/a&gt; covers the selection side in more depth, and the &lt;a href="https://socks5ip.com.cn/daili-ip-zhishiku/" rel="noopener noreferrer"&gt;proxy knowledge base&lt;/a&gt; covers exit types and protocol choices.&lt;/p&gt;

</description>
      <category>networking</category>
      <category>gaming</category>
      <category>python</category>
      <category>devops</category>
    </item>
    <item>
      <title>Why Three Geo-IP Databases Give Three Answers for the Same Address</title>
      <dc:creator>全网低价IP</dc:creator>
      <pubDate>Thu, 22 Oct 2026 02:20:50 +0000</pubDate>
      <link>https://dev.to/socks5ip/why-three-geo-ip-databases-give-three-answers-for-the-same-address-200</link>
      <guid>https://dev.to/socks5ip/why-three-geo-ip-databases-give-three-answers-for-the-same-address-200</guid>
      <description>&lt;p&gt;Ask three free lookup services where an address is and you will often get three answers: one says the city, one says the province capital, one says the country and nothing more. A tool flags the address as a crawler; the ISP's own whois says consumer line.&lt;/p&gt;

&lt;p&gt;This is not a bug in any single service. "Geo-IP" names &lt;strong&gt;three different datasets&lt;/strong&gt; that happen to share an output format, and most disagreements come from comparing the wrong one. Knowing which layer answered turns a confusing result into a diagnosis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three layers, three sources of truth
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Registration data&lt;/strong&gt; comes from RIR records — who holds the block, which country it was allocated in. Authoritative for the &lt;em&gt;holder&lt;/em&gt;, weak for the &lt;em&gt;user&lt;/em&gt;: a block allocated to a German subsidiary can be routed to Singapore tomorrow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Routing data&lt;/strong&gt; comes from BGP: which ASN announces the prefix, and where peers see it. It tells you where traffic physically lands, and it responds within hours to a network change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Observed data&lt;/strong&gt; comes from panels that record where real users of that address appear. Most accurate for consumer geography, slowest to update — a static residential IP that changes hands can keep its old city for months.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Owner of the truth&lt;/th&gt;
&lt;th&gt;Typical failure&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Registration (whois/RDAP)&lt;/td&gt;
&lt;td&gt;RIR&lt;/td&gt;
&lt;td&gt;Block allocated in one country, operated in another&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Routing (BGP/ASN)&lt;/td&gt;
&lt;td&gt;Network operator&lt;/td&gt;
&lt;td&gt;Anycast: one prefix, many locations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Observed (panel-based)&lt;/td&gt;
&lt;td&gt;Data vendor&lt;/td&gt;
&lt;td&gt;Thin samples, stale history, over-generalised centroids&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A vendor's answer is usually a blend, weighted by what its own customers observed. That weighting is proprietary, which is why two vendors disagree and both claim 99% accuracy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the answers diverge
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Anycast.&lt;/strong&gt; A CDN prefix is announced from dozens of sites. Which one your lookup resolves to depends on where the &lt;em&gt;query&lt;/em&gt; comes from, not where the address is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Registration lag.&lt;/strong&gt; Blocks are re-allocated faster than databases update: a /24 sold to a hosting provider in March may still read as a residential ISP in June.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Country-level fallback.&lt;/strong&gt; With no city-level confidence, a vendor returns the country centroid — a specific coordinate that looks precise and means nothing. In testing, some services return the same national coordinate for every address in a country while still reporting the correct region name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Heuristic side effects.&lt;/strong&gt; Provider-maintained "datacenter" lists are the worst offender: they are built from ASN lists, and ASN lists leak. In our own spot checks, one widely copied list included 16 Chinese carrier ASNs, which misclassifies consumer lines wholesale. A lookup that says "datacenter" often means "someone's ASN list says so", not "this is a server".&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the disagreement measurable
&lt;/h2&gt;

&lt;p&gt;Query three independent sources and compare country, region, and city &lt;strong&gt;separately&lt;/strong&gt;; aggregate agreement hides the case where all three agree on country and none on city.&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;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;

&lt;span class="n"&gt;SRC&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;ipapi.is&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://api.ipapi.is/?q={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;ip.sb&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://api.ip.sb/geoip/{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;ipinfo&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://ipinfo.io/{ip}/json&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;look&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tpl&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;SRC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&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;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tpl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ip&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;geo-probe/1.0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&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;8&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="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&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;read&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&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="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;d&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_code&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                         &lt;span class="n"&gt;d&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;region&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;d&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;d&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;is_datacenter&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;d&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;24&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;out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&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;ERR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&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="p"&gt;,&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ip&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;1.1.1.1&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;8.8.8.8&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="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;look&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&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 against addresses you already know, not random ones: you need a control. If one source is the outlier &lt;strong&gt;on the same field across every address&lt;/strong&gt;, its dataset is stale for your region — not merely imprecise.&lt;/p&gt;

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

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Likely layer at fault&lt;/th&gt;
&lt;th&gt;What to trust&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Country differs&lt;/td&gt;
&lt;td&gt;Anycast or BGP change&lt;/td&gt;
&lt;td&gt;Routing data, checked today&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Region correct, city is a national centroid&lt;/td&gt;
&lt;td&gt;Observed data with country fallback&lt;/td&gt;
&lt;td&gt;Region name; discard coordinates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Country/region right, "datacenter" flag wrong&lt;/td&gt;
&lt;td&gt;Provider ASN heuristic&lt;/td&gt;
&lt;td&gt;ASN holder type from RDAP, not the flag&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Everything right except ISP name&lt;/td&gt;
&lt;td&gt;Registration lag after re-allocation&lt;/td&gt;
&lt;td&gt;Routing data (ASN) again&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Different answer per request&lt;/td&gt;
&lt;td&gt;Load-balanced vendor backends&lt;/td&gt;
&lt;td&gt;Pin one endpoint for reproducibility&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two rules follow. &lt;strong&gt;Never mix fields from different sources in one decision&lt;/strong&gt; — country from vendor A and city from vendor B is how a consistent result becomes inconsistent. And &lt;strong&gt;record which vendor answered&lt;/strong&gt;: a comparison with unknown provenance is unreproducible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Five mistakes worth avoiding
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Treating country-centroid coordinates as data.&lt;/strong&gt; If region is right and city is the capital of a huge country, the coordinates are a placeholder.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trusting a "datacenter" boolean over the ASN.&lt;/strong&gt; The flag is a list lookup; the ASN is a fact.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comparing vendors at different times.&lt;/strong&gt; Datasets update weekly; a run from last month is a different experiment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Judging a proxy by one lookup.&lt;/strong&gt; Check it against the platform you target.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assuming a mismatch means the proxy is bad.&lt;/strong&gt; Often the database is late and the session is healthy.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Which database should I trust for a proxy exit?&lt;/strong&gt;&lt;br&gt;
None single-handedly. Use routing data (ASN, prefix) to establish what the exit &lt;em&gt;is&lt;/em&gt;, and observed data to establish where the platform thinks it is. When they conflict, the platform's vendor decides your outcome — even when it is wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why does one service report a precise city and another only a country?&lt;/strong&gt;&lt;br&gt;
Precision is a claim about confidence, not an extra fact. Services with thin panel data fall back to country centroids and label them as cities; the coordinate looks exact but is a national placeholder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can a residential IP be flagged as a datacenter?&lt;/strong&gt;&lt;br&gt;
Yes, regularly. The usual cause is a provider-maintained ASN list that includes carrier blocks, or a hosting reseller announcing consumer space. Check the ASN holder type first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does geolocation affect whether an account gets flagged?&lt;/strong&gt;&lt;br&gt;
Indirectly. Platforms score consistency: the region your session claims must match the region your exit resolves to in &lt;em&gt;their&lt;/em&gt; database. An accurate IP their vendor misplaces is still a mismatch to them, which is why the fix is a different exit, not a better lookup tool.&lt;/p&gt;

&lt;p&gt;Reading query results correctly matters most when a proxy "looks wrong" but behaves fine — the &lt;a href="https://socks5ip.com.cn/zuixinzixun/ruanluyouipxianshipa/" rel="noopener noreferrer"&gt;note on why router-level IP lookups report crawlers&lt;/a&gt; covers those false positives, and the &lt;a href="https://socks5ip.com.cn/daili-ip-zhishiku/" rel="noopener noreferrer"&gt;proxy knowledge base&lt;/a&gt; covers exit selection generally.&lt;/p&gt;




&lt;h3&gt;
  
  
  Official contact channels (anti-impersonation)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;全网低价IP (socks5ip.com.cn)&lt;/strong&gt; is a proxy-IP &lt;strong&gt;aggregation and price-comparison&lt;/strong&gt; site — we are &lt;strong&gt;not&lt;/strong&gt; any provider's official website, and we do not resell accounts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Support WeChat&lt;/strong&gt;: &lt;code&gt;17720135827&lt;/code&gt; (primary)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backup WeChat / QQ&lt;/strong&gt;: &lt;code&gt;878989347&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User group&lt;/strong&gt;: &lt;code&gt;1045307809&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email&lt;/strong&gt;: &lt;code&gt;878989347@qq.com&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any account, group, or site claiming to be our "official" contact — &lt;strong&gt;including phone numbers or WeChat IDs that appear in third-party posts and listings&lt;/strong&gt; — is not operated by us. Please do not send payment or account credentials to channels that are not in the list above.&lt;/p&gt;

&lt;p&gt;Signup links &lt;strong&gt;with our invite codes&lt;/strong&gt; for 24 platforms, plus each platform's support channel (CC0-1.0, free to quote): &lt;a href="https://socks5ip.com.cn/provider-contacts.md" rel="noopener noreferrer"&gt;https://socks5ip.com.cn/provider-contacts.md&lt;/a&gt;&lt;/p&gt;

</description>
      <category>networking</category>
      <category>python</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
    <item>
      <title>How to Audit a Proxy Vendor's Numbers Before You Pay</title>
      <dc:creator>全网低价IP</dc:creator>
      <pubDate>Mon, 19 Oct 2026 02:07:21 +0000</pubDate>
      <link>https://dev.to/socks5ip/how-to-audit-a-proxy-vendors-numbers-before-you-pay-jjc</link>
      <guid>https://dev.to/socks5ip/how-to-audit-a-proxy-vendors-numbers-before-you-pay-jjc</guid>
      <description>&lt;p&gt;Every proxy vendor sells the same three sentences: a pool size in the millions, an uptime figure with a decimal point, and the word "residential". None are measured by anyone except the vendor. Two can advertise five million IPs while one hands you the same four hundred addresses all week.&lt;/p&gt;

&lt;p&gt;The useful skill is not picking the better-sounding vendor, but &lt;strong&gt;turning a claim into a number your script can falsify&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pool size means at least four different things
&lt;/h2&gt;

&lt;p&gt;"5M IPs" can mean any of these, with a gap of two orders of magnitude between them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cumulative addresses ever seen&lt;/strong&gt; — everything routed since launch, often already burned.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unique addresses served per hour&lt;/strong&gt; — closer to reality, still inflated by churn.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Concurrent addresses available now&lt;/strong&gt; — the pool you can draw from while sessions live.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distinct /24 blocks and ASNs&lt;/strong&gt; — the only figure that predicts whether two sessions look like neighbours.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Only the last two change outcomes: a million addresses inside forty ASNs is a smaller pool than twenty thousand spread across four thousand, if your problem is correlation rather than volume.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to measure, and how to falsify it
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Vendor claim&lt;/th&gt;
&lt;th&gt;Number that actually constrains you&lt;/th&gt;
&lt;th&gt;How to falsify it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"Millions of IPs"&lt;/td&gt;
&lt;td&gt;Unique exits per hour, distinct /24s&lt;/td&gt;
&lt;td&gt;Sample 200 sessions, count distinct IPs and prefixes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"99.9% uptime"&lt;/td&gt;
&lt;td&gt;Success rate of a full request, not a TCP connect&lt;/td&gt;
&lt;td&gt;Fetch a small payload through the proxy, score HTTP 200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Residential"&lt;/td&gt;
&lt;td&gt;ASN class of the exit, not the product name&lt;/td&gt;
&lt;td&gt;Resolve each exit IP to its ASN and check the holder type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Unlimited concurrency"&lt;/td&gt;
&lt;td&gt;Success rate as you raise parallel sessions&lt;/td&gt;
&lt;td&gt;Ramp 4 → 16 → 64 workers, watch failure mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Fast nodes"&lt;/td&gt;
&lt;td&gt;Time to first byte of a real request&lt;/td&gt;
&lt;td&gt;Time the request body, not a ping&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Measure the end-to-end operation&lt;/strong&gt;: a 40 ms handshake proves nothing about a request that dies at TTFB.&lt;/p&gt;

&lt;h2&gt;
  
  
  A harness small enough to trust
&lt;/h2&gt;

&lt;p&gt;Standard library only. It reads &lt;code&gt;host:port&lt;/code&gt; lines, performs a real SOCKS5 handshake, requests a plain-text echo endpoint, and records the exit IP, latency, and prefix key. Concurrency stays low on purpose: hammering a trial endpoint is the fastest way to get your test IP blocked.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```pythonimport socket, struct, time&lt;br&gt;
from concurrent.futures import ThreadPoolExecutor&lt;/p&gt;

&lt;p&gt;def socks5_get(ep, host="api.ipify.org"):&lt;br&gt;
    h, p = ep.split(":")&lt;br&gt;
    t0 = time.time()&lt;br&gt;
    s = socket.create_connection((h, int(p)), timeout=8)&lt;br&gt;
    s.sendall(b"\x05\x01\x00")                        # greeting: no auth&lt;br&gt;
    if s.recv(2) != b"\x05\x00":&lt;br&gt;
        raise OSError("method rejected")&lt;br&gt;
    q = host.encode()&lt;br&gt;
    s.sendall(b"\x05\x01\x00\x03" + bytes([len(q)]) + q + struct.pack("&amp;gt;H", 80))&lt;br&gt;
    rep = s.recv(4)&lt;br&gt;
    if rep[1]:&lt;br&gt;
        raise OSError("connect failed rep=%d" % rep[1])&lt;br&gt;
    s.recv({1: 4, 4: 16}.get(rep[3], s.recv(1)[0] + 1) + 2)   # drain BND.ADDR&lt;br&gt;
    s.sendall(("GET / HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n" % host).encode())&lt;br&gt;
    data = b""&lt;br&gt;
    while chunk := s.recv(4096):&lt;br&gt;
        data += chunk&lt;br&gt;
    s.close()&lt;br&gt;
    ip = data.rsplit(b"\r\n\r\n", 1)[-1].decode().strip()&lt;br&gt;
    return {"exit": ip, "ms": round((time.time() - t0) * 1000),&lt;br&gt;
            "prefix": ".".join(ip.split(".")[:3])}&lt;/p&gt;

&lt;p&gt;def one(ep):&lt;br&gt;
    try:&lt;br&gt;
        return socks5_get(ep)&lt;br&gt;
    except Exception as e:&lt;br&gt;
        return {"exit": None, "err": type(e).&lt;strong&gt;name&lt;/strong&gt;}   # failures are data&lt;/p&gt;

&lt;p&gt;eps = [l.strip() for l in open("proxies.txt") if l.strip()]&lt;br&gt;
with ThreadPoolExecutor(max_workers=4) as pool:&lt;br&gt;
    rows = [r for r in pool.map(one, eps) if r.get("exit")]&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Write every row to JSONL as you go: a sample you cannot re-analyse is one you pay for twice.

## Designing the sample so the result means something

**Sample across time, not once.** Run the harness in three windows (morning, evening, late night in the target market's timezone). Vendors oversubscribe; the 03:00 pool is not the 21:00 pool.

**Size the sample for the claim under test.** Two hundred attempts give a success rate with a ±6 point confidence interval — enough to separate 85% from 98%, useless for 98.5% versus 99.3%. The second decimal is unverifiable in an afternoon; price it as such.

**Count unique exits, not requests.** The ratio of distinct exit IPs to successful requests is the most diagnostic number in the sample. Below 0.5 you are buying a static pool dressed up as rotating; near 1.0 with high ASN diversity, the claim has substance.

## Reading the result

| Observation | Likely cause | What to do |
|---|---|---|
| High connect success, low request success | Exit rate-limited or gateway swapping mid-session | Re-test with sticky sessions; read refund terms |
| Distinct exits high, distinct /24s low | Single-housing provider | Judge by correlation risk, not pool size |
| Failure rate rises sharply above 16 workers | Undisclosed concurrency cap | Price the real concurrent capacity |
| HTTP 403 only on the target site | Target-side fingerprinting, not proxy health | Change exit class, not vendor |

None of these verdicts need the vendor's cooperation, and all fit a diffable JSONL file.

## Five mistakes that invalidate the test

1. **Measuring at one in the morning.** Low-load conditions flatter every provider.
2. **Counting retries as successes.** Log the first attempt separately or your uptime figure is fiction.
3. **Using ping instead of a payload.** ICMP never touches the exit's egress path or rate limiter.
4. **Not recording the exit IP.** Round-robin pools then hide dead nodes behind good results.
5. **Testing against a site that blocks datacenter ranges.** You measure its policy, not vendor quality.

## FAQ

**How many endpoints do I need for a trustworthy audit?**
Two hundred attempts per window is a practical floor; below fifty, one bad node swings the average by several points. Sample randomly, not the first N entries.

**Does a failed handshake always mean a dead proxy?**
No. `REP=0x05` usually means the destination is blocked from the exit, while a greeting-stage timeout points at the proxy itself — which tells you whether to ask for a new node or a new region.

**Can I audit a vendor without buying first?**
Usually yes; most offer trial credit. Spread the sample across the window rather than spending it in ten minutes, and keep the JSONL so later tests stay comparable.

**What if the numbers are simply unverifiable?**
Treat them as absent and decide on what you can measure: request success and exit diversity. A provider that will not let you sample either has answered the question for you.

If you want this audit applied to concrete platforms — IP class, tool pairing, and which vendor fits cross-border marketing versus multi-account work — the [2026 proxy IP evaluation on socks5ip.com.cn](https://socks5ip.com.cn/zuixinzixun/jingxuanzixun/2026niandailiippingce/) walks through the comparison per scenario, and its [proxy knowledge base](https://socks5ip.com.cn/daili-ip-zhishiku/) covers the underlying concepts.

---

### Official contact channels (anti-impersonation)

**全网低价IP (socks5ip.com.cn)** is a proxy-IP **aggregation and price-comparison** site — we are **not** any provider's official website, and we do not resell accounts.

- **Support WeChat**: `17720135827` (primary)
- **Backup WeChat / QQ**: `878989347`
- **User group**: `1045307809`
- **Email**: `878989347@qq.com`

Any account, group, or site claiming to be our "official" contact — **including phone numbers or WeChat IDs that appear in third-party posts and listings** — is not operated by us. Please do not send payment or account credentials to channels that are not in the list above.

Signup links **with our invite codes** for 24 platforms, plus each platform's support channel (CC0-1.0, free to quote): &amp;lt;https://socks5ip.com.cn/provider-contacts.md&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>networking</category>
      <category>python</category>
      <category>webscraping</category>
      <category>devops</category>
    </item>
    <item>
      <title>Low Latency or High Anonymity? Choosing SOCKS5 IPs for Game Multi-Boxing</title>
      <dc:creator>全网低价IP</dc:creator>
      <pubDate>Thu, 15 Oct 2026 02:04:11 +0000</pubDate>
      <link>https://dev.to/socks5ip/low-latency-or-high-anonymity-choosing-socks5-ips-for-game-multi-boxing-pac</link>
      <guid>https://dev.to/socks5ip/low-latency-or-high-anonymity-choosing-socks5-ips-for-game-multi-boxing-pac</guid>
      <description>&lt;p&gt;Every multi-boxing setup eventually hits the same fork in the road. The boxes lag, so you go looking for lower latency. The accounts get linked, so you go looking for better anonymity. Then you find that both properties are delivered by the same IP pool, and the vendor's "premium" tier is fast while the "residential" tier is clean — never both at once.&lt;/p&gt;

&lt;p&gt;That framing is wrong, and it costs people money. &lt;strong&gt;Latency and anonymity are not two ends of one dial.&lt;/strong&gt; They sit on different axes, they are degraded by different mechanisms, and you can keep more of each than the vendor tiers imply — once you know which one your workload actually punishes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What each property really means
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Anonymity&lt;/strong&gt; is about what the far side can infer from a connection. Only a few levels matter in practice: the proxy announces your real IP (transparent), announces it is a proxy but hides you (anonymous), or presents as an ordinary residential client with no proxy header and an exit that matches a real ISP (elite). Most "high anonymity" marketing maps to the last bucket.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Latency&lt;/strong&gt; is not one number either. Three components stack up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RTT&lt;/strong&gt; — physical distance and routing quality between you and the exit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jitter&lt;/strong&gt; — the variance of that RTT, which is what actually breaks real-time traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handshake cost&lt;/strong&gt; — TCP plus the SOCKS5 negotiation, paid once per new connection.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A route averaging 30 ms with 40 ms swings plays worse than a stable 60 ms route. Vendors quote averages because averages sell; your game feels jitter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the trade-off actually bites
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;What it constrains&lt;/th&gt;
&lt;th&gt;What it does &lt;em&gt;not&lt;/em&gt; constrain&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Low RTT&lt;/td&gt;
&lt;td&gt;Exit location, peering quality&lt;/td&gt;
&lt;td&gt;Anonymity level&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Low jitter&lt;/td&gt;
&lt;td&gt;Route stability, hop count, exit load&lt;/td&gt;
&lt;td&gt;Exit geography&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Elite anonymity&lt;/td&gt;
&lt;td&gt;ISP class of the exit, absence of proxy headers&lt;/td&gt;
&lt;td&gt;Throughput&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Many boxes&lt;/td&gt;
&lt;td&gt;Independent exits across subnets&lt;/td&gt;
&lt;td&gt;Latency, directly&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The last row is the important one. Multi-boxing fails on &lt;strong&gt;correlation&lt;/strong&gt;, not on raw speed — and correlation comes from shared subnets, shared ASNs, and shared session timing, not from latency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measure before you buy
&lt;/h2&gt;

&lt;p&gt;You cannot trade away the right property until both numbers are known. This stdlib-only probe times TCP connect plus the SOCKS5 negotiation separately, so a slow result can be attributed rather than guessed:&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;socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;statistics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="n"&gt;HOST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;USER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PWD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;203.0.113.10&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1080&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;u&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;p&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;socks5_probe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rounds&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="n"&gt;lat&lt;/span&gt; &lt;span class="o"&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;_&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;rounds&lt;/span&gt;&lt;span class="p"&gt;):&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;perf_counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_connection&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;HOST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PORT&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;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x05\x02\x00\x02&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                  &lt;span class="c1"&gt;# greeting: offer user/pass
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x05\x02&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&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;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;bytes&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;USER&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;USER&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                  &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;bytes&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;PWD&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;PWD&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;   &lt;span class="c1"&gt;# RFC 1929 auth
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&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;host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;api.ipify.org&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x05\x01\x00\x03&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;bytes&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;host&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;
                  &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x01\xbb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                        &lt;span class="c1"&gt;# CONNECT :443
&lt;/span&gt;        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                                      &lt;span class="c1"&gt;# reply: BND.ADDR
&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;append&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;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;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;statistics&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;
    &lt;span class="n"&gt;jitter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stdev&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="k"&gt;if&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;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mf"&gt;0.0&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;n=%d median=%.1fms jitter=%.1fms&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&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;lat&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;median&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="n"&gt;jitter&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="nf"&gt;socks5_probe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three signals matter: a median inside your game's tick budget, a jitter figure smaller than that budget, and a stable exit. If the exit IP moves under you, no latency number is worth anything — your sessions are being correlated by rotation you never asked for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing by workload
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Workload&lt;/th&gt;
&lt;th&gt;Prioritise&lt;/th&gt;
&lt;th&gt;Safe to give up&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Single real-time session&lt;/td&gt;
&lt;td&gt;Jitter&lt;/td&gt;
&lt;td&gt;Everything else&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Many boxes, one market&lt;/td&gt;
&lt;td&gt;One distinct exit per box&lt;/td&gt;
&lt;td&gt;Remote geography&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Emulator farm, unattended&lt;/td&gt;
&lt;td&gt;Exit diversity over speed&lt;/td&gt;
&lt;td&gt;Lowest RTT&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Chain the decision instead of averaging it: pick the anonymity tier first, because it fixes the exit pool; choose exits inside that tier by jitter; then verify with the probe above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Five mistakes that cost the most
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Buying "high anonymity" for a latency problem.&lt;/strong&gt; If boxes lag, a cleaner IP changes nothing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Judging a route by average RTT.&lt;/strong&gt; Measure jitter — that is what breaks input.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assuming different IPs mean independence.&lt;/strong&gt; Ten addresses in one /24 are one neighbourhood.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Letting the pool rotate mid-session.&lt;/strong&gt; An exit change during a login is a red flag.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing once and trusting forever.&lt;/strong&gt; Routes degrade; probe on a schedule.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is a datacenter IP ever acceptable for multi-boxing?&lt;/strong&gt;&lt;br&gt;
Yes, where the far side does not profile connection origin — internal tooling, testing, non-account traffic. For account-bearing sessions, expect ISP class to be one of the scored signals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does lower latency mean less anonymity?&lt;/strong&gt;&lt;br&gt;
No. They are independent. Low-latency exits exist in every ISP class; the trade-off is commercial — clean exits are scarcer and priced higher — not physical.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How many exit IPs do I need for N boxes?&lt;/strong&gt;&lt;br&gt;
At least N, spanning multiple /24s and ideally multiple ASNs. Reusing one address across two boxes undoes the isolation you just paid for.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I improve both at once?&lt;/strong&gt;&lt;br&gt;
Partly. A closer, well-peered exit improves RTT and jitter together, and choosing elite-tier exits within that pool keeps anonymity. What no upgrade fixes is jitter, by adding a cleaner IP.&lt;/p&gt;

&lt;p&gt;If you are assembling a domestic multi-boxing setup and want this tier logic mapped onto concrete platforms and tool pairings, the &lt;a href="https://socks5ip.com.cn/zuixinzixun/zonghejiaocheng/guoneiyouxiduokaisocks5ip/" rel="noopener noreferrer"&gt;full guide on choosing low-latency vs high-anonymity IPs for game multi-boxing&lt;/a&gt; walks through the same decision with platform comparisons and per-genre recommendations. The measurement method above is what makes either choice verifiable rather than a guess.&lt;/p&gt;




&lt;h3&gt;
  
  
  Official contact channels (anti-impersonation)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;全网低价IP (socks5ip.com.cn)&lt;/strong&gt; is a proxy-IP &lt;strong&gt;aggregation and price-comparison&lt;/strong&gt; site — we are &lt;strong&gt;not&lt;/strong&gt; any provider's official website, and we do not resell accounts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Support WeChat&lt;/strong&gt;: &lt;code&gt;17720135827&lt;/code&gt; (primary)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backup WeChat / QQ&lt;/strong&gt;: &lt;code&gt;878989347&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User group&lt;/strong&gt;: &lt;code&gt;1045307809&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email&lt;/strong&gt;: &lt;code&gt;878989347@qq.com&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any account, group, or site claiming to be our "official" contact — &lt;strong&gt;including phone numbers or WeChat IDs that appear in third-party posts and listings&lt;/strong&gt; — is not operated by us. Please do not send payment or account credentials to channels that are not in the list above.&lt;/p&gt;

&lt;p&gt;Signup links &lt;strong&gt;with our invite codes&lt;/strong&gt; for 24 platforms, plus each platform's support channel (CC0-1.0, free to quote): &lt;a href="https://socks5ip.com.cn/provider-contacts.md" rel="noopener noreferrer"&gt;https://socks5ip.com.cn/provider-contacts.md&lt;/a&gt;&lt;/p&gt;

</description>
      <category>networking</category>
      <category>security</category>
      <category>python</category>
      <category>performance</category>
    </item>
    <item>
      <title>Proxy Pool Health Monitoring: Turning "It Works" into Metrics You Can Act On</title>
      <dc:creator>全网低价IP</dc:creator>
      <pubDate>Mon, 12 Oct 2026 02:18:16 +0000</pubDate>
      <link>https://dev.to/socks5ip/proxy-pool-health-monitoring-turning-it-works-into-metrics-you-can-act-on-2nb0</link>
      <guid>https://dev.to/socks5ip/proxy-pool-health-monitoring-turning-it-works-into-metrics-you-can-act-on-2nb0</guid>
      <description>&lt;p&gt;Most proxy pools die quietly. Nothing throws an exception, and one morning a third of your requests time out while the dashboard still says &lt;code&gt;200 OK&lt;/code&gt; — because a scraper that retries three times and finally succeeds looks identical to one that never had a problem.&lt;/p&gt;

&lt;p&gt;That is the real failure mode: &lt;strong&gt;you are measuring your application, not your infrastructure.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why "it works" is not a health check
&lt;/h2&gt;

&lt;p&gt;A ping is not a proxy check, and neither is a TCP connect. What you need is whether a &lt;em&gt;complete, correctly authenticated protocol exchange&lt;/em&gt; can carry traffic now — and how fast:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;What breaks&lt;/th&gt;
&lt;th&gt;A naive check reports&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Network&lt;/td&gt;
&lt;td&gt;Host unreachable, port filtered&lt;/td&gt;
&lt;td&gt;Down (correct)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TCP&lt;/td&gt;
&lt;td&gt;Port open, no service behind it&lt;/td&gt;
&lt;td&gt;Up (wrong)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Protocol&lt;/td&gt;
&lt;td&gt;Handshake rejected, bad credentials&lt;/td&gt;
&lt;td&gt;Up (wrong)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Identity&lt;/td&gt;
&lt;td&gt;Exit IP moved, or is not where you expect&lt;/td&gt;
&lt;td&gt;Up (wrong)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Capacity&lt;/td&gt;
&lt;td&gt;Handshake fine, throughput collapsed&lt;/td&gt;
&lt;td&gt;Up (wrong)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Only the first row is caught by a ping — which is why a pool reporting "100% alive" can still cost you a day.&lt;/p&gt;

&lt;h2&gt;
  
  
  The five metrics that matter
&lt;/h2&gt;

&lt;p&gt;Track these per endpoint, not per pool — averages hide the endpoints you need to evict.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Definition&lt;/th&gt;
&lt;th&gt;Why it earns its place&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Handshake latency&lt;/td&gt;
&lt;td&gt;Time to complete protocol negotiation&lt;/td&gt;
&lt;td&gt;Earliest sign of congestion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rolling success rate&lt;/td&gt;
&lt;td&gt;Successes / attempts over last N runs&lt;/td&gt;
&lt;td&gt;Catches flapping, not just hard down&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exit IP stability&lt;/td&gt;
&lt;td&gt;Did the observed exit IP change&lt;/td&gt;
&lt;td&gt;Detects rotation you did not ask for&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exit IP correctness&lt;/td&gt;
&lt;td&gt;Is the exit in the expected region and ASN&lt;/td&gt;
&lt;td&gt;Catches silent rerouting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Throughput&lt;/td&gt;
&lt;td&gt;Bytes per second on a fixed transfer&lt;/td&gt;
&lt;td&gt;Catches "connected but useless"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Latency alone is not enough: a common trick is an endpoint that handshakes in 40 ms and then delivers 30 KB/s — the metric looks great while your pipeline stalls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measuring it with stdlib Python
&lt;/h2&gt;

&lt;p&gt;You do not need a framework — a socket, a timer, and a small request are the whole check. The SOCKS5 version, following RFC 1928:&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;socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;socks5_check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&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;pwd&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;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;8.0&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 (ok, handshake_ms, error).&lt;/span&gt;&lt;span class="sh"&gt;"""&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;perf_counter&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;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_connection&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&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="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;OSError&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="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;tcp:%s&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;e&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;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\x05\x02\x00\x02&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\x05\x01\x00&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;ver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&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;ver&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mh"&gt;0xFF&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;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;no acceptable auth method&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mh"&gt;0x02&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                        &lt;span class="c1"&gt;# RFC 1929 user/pass exchange
&lt;/span&gt;            &lt;span class="n"&gt;u&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="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;pwd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\x01&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;bytes&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;u&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;bytes&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;p&lt;/span&gt;&lt;span class="p"&gt;)])&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mh"&gt;0x00&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;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;auth rejected&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
        &lt;span class="c1"&gt;# CONNECT 1.1.1.1:443 -&amp;gt; reply VER REP RSV ATYP BND.ADDR BND.PORT
&lt;/span&gt;        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\x05\x01\x00\x01&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inet_aton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1.1.1.1&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;struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;!H&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;rep&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&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;if&lt;/span&gt; &lt;span class="n"&gt;rep&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mh"&gt;0x00&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;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;REP=0x%02x&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;rep&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&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;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="bp"&gt;None&lt;/span&gt;
    &lt;span class="nf"&gt;except &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;OSError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;IndexError&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="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;handshake:%s&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
    &lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The timing wraps the &lt;strong&gt;entire&lt;/strong&gt; exchange, not just &lt;code&gt;connect()&lt;/code&gt; — that is what makes it a metric about the proxy rather than the network. And the structured error string matters: when half the pool fails at once, &lt;code&gt;tcp:&lt;/code&gt; versus &lt;code&gt;REP=0x05&lt;/code&gt; separates a routing incident from a credentials incident.&lt;/p&gt;

&lt;p&gt;To verify the exit IP, reuse the socket after the handshake: send &lt;code&gt;GET / HTTP/1.1&lt;/code&gt; with &lt;code&gt;Host: api.ipify.org&lt;/code&gt; and read the body. A stable exit IP is a feature you pay for; a changing one is either a documented rotating product or a misconfiguration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thresholds worth alerting on
&lt;/h2&gt;

&lt;p&gt;Absolute latency means little without your route, so set thresholds against a rolling per-endpoint baseline:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;Condition&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Latency drift&lt;/td&gt;
&lt;td&gt;p95 &amp;gt; 2× 7-day baseline&lt;/td&gt;
&lt;td&gt;Warn — usually congestion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Success rate&lt;/td&gt;
&lt;td&gt;&amp;lt; 95% over last 20 runs&lt;/td&gt;
&lt;td&gt;Quarantine the endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Consecutive failures&lt;/td&gt;
&lt;td&gt;3 in a row&lt;/td&gt;
&lt;td&gt;Evict from the active set&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exit IP change&lt;/td&gt;
&lt;td&gt;Any change outside a maintenance window&lt;/td&gt;
&lt;td&gt;Warn, verify it is intended&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Throughput&lt;/td&gt;
&lt;td&gt;&amp;lt; 50% of baseline for 3 runs&lt;/td&gt;
&lt;td&gt;Demote; keep alive but deprioritize&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The key word is &lt;em&gt;quarantine&lt;/em&gt;, not delete. Keep a failing endpoint in a slow retry lane so it can re-earn its place — endpoints that fail during a maintenance window come back; endpoints that fail for three days do not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Checking the pool average instead of per endpoint.&lt;/strong&gt; A pool at 90% success looks healthy until you notice all 10% of failures are the same three endpoints serving your most important account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Only testing on failure.&lt;/strong&gt; A check that runs when the pipeline breaks is a debugger, not a monitor. Run it on a schedule independent of traffic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Treating one failure as death.&lt;/strong&gt; Transient packet loss is real, so require a few consecutive failures before evicting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Ignoring time of day.&lt;/strong&gt; Your provider's peak hours are not yours, so compare like with like.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Forgetting the identity layer.&lt;/strong&gt; Latency and success rate say nothing about whether the exit is still in the country you need. Check exit IP, region, and ASN together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. One aggressive probe.&lt;/strong&gt; A tight loop looks like an attack and gets your IP rate-limited. Space your probes and rotate your sample.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;How often should I probe each endpoint?&lt;/strong&gt;&lt;br&gt;
A rolling sample every 2-5 minutes is plenty for a pool in the dozens. Probing everything every 30 seconds buys nothing and looks abusive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What success rate should I target?&lt;/strong&gt;&lt;br&gt;
For a static pool, 95% over a 20-run window is a reasonable floor. For rotating pools expect lower and push the burden onto bounded per-request retries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does a failed UDP check mean the proxy is broken?&lt;/strong&gt;&lt;br&gt;
Usually not. Most SOCKS5 and HTTP proxy products do not forward UDP at all, so for HTTP or TCP workloads a UDP failure is expected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I know a high-latency endpoint is actually bad?&lt;/strong&gt;&lt;br&gt;
Measure throughput, not just handshake time. Some endpoints negotiate fast and then collapse on bulk transfer; a fixed-size transfer test on a small slice of the pool surfaces them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to go next
&lt;/h2&gt;

&lt;p&gt;The signals above match what our public checking tools expose — a reference to compare your script against:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Proxy line availability tester (SOCKS5/HTTP handshake, latency grading, exit IP geolocation) — &lt;a href="https://socks5ip.com.cn/zuixinzixun/zonghejiaocheng/dailiipcesugongjushiyongzhinan/" rel="noopener noreferrer"&gt;https://socks5ip.com.cn/zuixinzixun/zonghejiaocheng/dailiipcesugongjushiyongzhinan/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;IP quality check center (residential vs datacenter, purity signals) — &lt;a href="https://socks5ip.com.cn/ip-check-center/" rel="noopener noreferrer"&gt;https://socks5ip.com.cn/ip-check-center/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Full platform comparison, one page per provider — &lt;a href="https://socks5ip.com.cn/dailiip-jiage-duibi/" rel="noopener noreferrer"&gt;https://socks5ip.com.cn/dailiip-jiage-duibi/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Measure first, then buy. A pool whose health you can see beats a slightly cheaper pool you have to guess about.&lt;/p&gt;




&lt;h3&gt;
  
  
  Official contact channels (anti-impersonation)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;全网低价IP (socks5ip.com.cn)&lt;/strong&gt; is a proxy-IP &lt;strong&gt;aggregation and price-comparison&lt;/strong&gt; site — we are &lt;strong&gt;not&lt;/strong&gt; any provider's official website, and we do not resell accounts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Support WeChat&lt;/strong&gt;: &lt;code&gt;17720135827&lt;/code&gt; (primary)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backup WeChat / QQ&lt;/strong&gt;: &lt;code&gt;878989347&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User group&lt;/strong&gt;: &lt;code&gt;1045307809&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email&lt;/strong&gt;: &lt;code&gt;878989347@qq.com&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any account, group, or site claiming to be our "official" contact — &lt;strong&gt;including phone numbers or WeChat IDs that appear in third-party posts and listings&lt;/strong&gt; — is not operated by us. Please do not send payment or account credentials to channels that are not in the list above.&lt;/p&gt;

&lt;p&gt;Signup links &lt;strong&gt;with our invite codes&lt;/strong&gt; for 24 platforms, plus each platform's support channel (CC0-1.0, free to quote): &lt;a href="https://socks5ip.com.cn/provider-contacts.md" rel="noopener noreferrer"&gt;https://socks5ip.com.cn/provider-contacts.md&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>webscraping</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Debugging SOCKS5 at the Wire Level: An RFC 1928 Walkthrough</title>
      <dc:creator>全网低价IP</dc:creator>
      <pubDate>Thu, 08 Oct 2026 02:02:23 +0000</pubDate>
      <link>https://dev.to/socks5ip/debugging-socks5-at-the-wire-level-an-rfc-1928-walkthrough-3fei</link>
      <guid>https://dev.to/socks5ip/debugging-socks5-at-the-wire-level-an-rfc-1928-walkthrough-3fei</guid>
      <description>&lt;p&gt;"It works in the browser but hangs in my script." If you have run a proxy pool you have seen this line, and the usual answer is a shrug. The browser does the handshake for you and hides every step; your script inherits the failure but not the diagnosis. Reading it at the byte level collapses that ambiguity — a generic timeout becomes one specific phase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four phases, strictly ordered
&lt;/h2&gt;

&lt;p&gt;SOCKS5 is small. RFC 1928 defines exactly four exchanges, and each one depends on the previous reply. A stall is almost always "the client is waiting for a reply the server will never send, because the previous message was malformed or unacceptable."&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Greeting&lt;/strong&gt; (client → proxy): &lt;code&gt;VER&lt;/code&gt;, &lt;code&gt;NMETHODS&lt;/code&gt;, then that many &lt;code&gt;METHOD&lt;/code&gt; bytes. This is the client listing the auth methods it supports.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Method selection&lt;/strong&gt; (proxy → client): &lt;code&gt;VER&lt;/code&gt;, &lt;code&gt;METHOD&lt;/code&gt;. The proxy picks one, or &lt;code&gt;0xFF&lt;/code&gt; for "none acceptable."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Request&lt;/strong&gt; (client → proxy): &lt;code&gt;VER&lt;/code&gt;, &lt;code&gt;CMD&lt;/code&gt;, &lt;code&gt;RSV&lt;/code&gt;, &lt;code&gt;ATYP&lt;/code&gt;, &lt;code&gt;DST.ADDR&lt;/code&gt;, &lt;code&gt;DST.PORT&lt;/code&gt;. This is the actual ask — usually &lt;code&gt;CONNECT&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reply&lt;/strong&gt; (proxy → client): &lt;code&gt;VER&lt;/code&gt;, &lt;code&gt;REP&lt;/code&gt;, &lt;code&gt;RSV&lt;/code&gt;, &lt;code&gt;ATYP&lt;/code&gt;, &lt;code&gt;BND.ADDR&lt;/code&gt;, &lt;code&gt;BND.PORT&lt;/code&gt;. &lt;code&gt;REP = 0x00&lt;/code&gt; means success; anything else is a structured error, not a crash.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The version byte is &lt;code&gt;0x05&lt;/code&gt; in all four. If you ever see &lt;code&gt;0x04&lt;/code&gt; in a reply, you are talking SOCKS4 to a SOCKS5 endpoint, or vice versa.&lt;/p&gt;

&lt;h2&gt;
  
  
  The byte layout, phase by phase
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Phase&lt;/th&gt;
&lt;th&gt;Direction&lt;/th&gt;
&lt;th&gt;Fields (in order)&lt;/th&gt;
&lt;th&gt;Sizes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Greeting&lt;/td&gt;
&lt;td&gt;client → proxy&lt;/td&gt;
&lt;td&gt;VER, NMETHODS, METHODS[]&lt;/td&gt;
&lt;td&gt;1, 1, NMETHODS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Method selection&lt;/td&gt;
&lt;td&gt;proxy → client&lt;/td&gt;
&lt;td&gt;VER, METHOD&lt;/td&gt;
&lt;td&gt;1, 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Request&lt;/td&gt;
&lt;td&gt;client → proxy&lt;/td&gt;
&lt;td&gt;VER, CMD, RSV, ATYP, DST.ADDR, DST.PORT&lt;/td&gt;
&lt;td&gt;1, 1, 1, 1, var, 2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reply&lt;/td&gt;
&lt;td&gt;proxy → client&lt;/td&gt;
&lt;td&gt;VER, REP, RSV, ATYP, BND.ADDR, BND.PORT&lt;/td&gt;
&lt;td&gt;1, 1, 1, 1, var, 2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;ATYP&lt;/code&gt; decides how long &lt;code&gt;ADDR&lt;/code&gt; is: &lt;code&gt;0x01&lt;/code&gt; = 4-byte IPv4, &lt;code&gt;0x04&lt;/code&gt; = 16-byte IPv6, &lt;code&gt;0x03&lt;/code&gt; = one length byte followed by a domain name. Ports are big-endian. Getting the address type wrong is the single most common reason a hand-rolled client desynchronises: the proxy reads your domain name as raw address bytes and the stream never lines up again.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;CMD&lt;/code&gt; is usually &lt;code&gt;0x01&lt;/code&gt; (&lt;code&gt;CONNECT&lt;/code&gt;). &lt;code&gt;0x02&lt;/code&gt; (&lt;code&gt;BIND&lt;/code&gt;) and &lt;code&gt;0x03&lt;/code&gt; (&lt;code&gt;UDP ASSOCIATE&lt;/code&gt;) exist, but most proxy services only implement &lt;code&gt;CONNECT&lt;/code&gt; — a &lt;code&gt;0x03&lt;/code&gt; request against such a proxy returns &lt;code&gt;REP = 0x07&lt;/code&gt; (command not supported), which is a configuration fact, not a bug in your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Auth is what silently kills a connection
&lt;/h2&gt;

&lt;p&gt;Two methods carry most of the traffic: &lt;code&gt;0x00&lt;/code&gt; (no auth) and &lt;code&gt;0x02&lt;/code&gt; (username/password, defined in RFC 1929). If your client offers &lt;strong&gt;only&lt;/strong&gt; &lt;code&gt;0x02&lt;/code&gt; and the proxy is white-listed by source IP instead, it replies &lt;code&gt;METHOD = 0xFF&lt;/code&gt; and drops the connection — to your socket an empty read, not an error. That is why "authenticated" proxies work from one machine and not another: the source IP is the real credential.&lt;/p&gt;

&lt;p&gt;The practical fix is to offer both methods in the greeting and branch on the reply. Never assume the method you want.&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;socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;struct&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;socks5_connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proxy_host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proxy_port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dst&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="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_connection&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;proxy_host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proxy_port&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="c1"&gt;# 1. Greeting: offer no-auth AND user/pass
&lt;/span&gt;    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x05\x02\x00\x02&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&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;method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mh"&gt;0xFF&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;OSError&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 rejected all offered auth methods&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# 2. (If method == 0x02, do the RFC 1929 sub-negotiation here.)
&lt;/span&gt;    &lt;span class="c1"&gt;# 3. CONNECT with a domain name target
&lt;/span&gt;    &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dst&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="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x05\x01\x00\x03&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;bytes&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;host&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;!H&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                      &lt;span class="c1"&gt;# VER REP RSV ATYP
&lt;/span&gt;    &lt;span class="n"&gt;rep&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&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;if&lt;/span&gt; &lt;span class="n"&gt;rep&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mh"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;OSError&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;CONNECT failed, REP=0x&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;rep&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="n"&gt;x&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="c1"&gt;# 4. Consume BND.ADDR + BND.PORT so the socket is positioned at payload
&lt;/span&gt;    &lt;span class="n"&gt;ln&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mh"&gt;0x01&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x04&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&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;head&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="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&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="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ln&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;   &lt;span class="c1"&gt;# s is now a plain tunnel; write HTTP or TLS over it
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once &lt;code&gt;REP = 0x00&lt;/code&gt; and the bound address is drained, the socket behaves like a direct connection. There is no further framing — that is the whole point of SOCKS5, and the reason it tunnels protocols it knows nothing about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mapping &lt;code&gt;REP&lt;/code&gt; codes to real problems
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;REP&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;Usual cause&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0x01&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;General failure&lt;/td&gt;
&lt;td&gt;Proxy backend could not open the upstream socket&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0x02&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Connection not allowed&lt;/td&gt;
&lt;td&gt;Egress ACL / rule rejected the target&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0x03&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Network unreachable&lt;/td&gt;
&lt;td&gt;Exit host has no route to the target&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0x04&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Host unreachable&lt;/td&gt;
&lt;td&gt;Target DNS resolved but the host is down&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0x05&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Connection refused&lt;/td&gt;
&lt;td&gt;Target reachable, port closed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0x06&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;TTL expired&lt;/td&gt;
&lt;td&gt;Rare in practice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0x07&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Command not supported&lt;/td&gt;
&lt;td&gt;You asked for &lt;code&gt;BIND&lt;/code&gt;/&lt;code&gt;UDP&lt;/code&gt; on a &lt;code&gt;CONNECT&lt;/code&gt;-only proxy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0x08&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Address type not supported&lt;/td&gt;
&lt;td&gt;You sent IPv6 to an IPv4-only endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The distinction that saves the most time is &lt;code&gt;0x02&lt;/code&gt; versus &lt;code&gt;0x05&lt;/code&gt;. A &lt;code&gt;0x02&lt;/code&gt; means &lt;em&gt;your proxy is healthy but policy said no&lt;/em&gt; — a credential, geo, or allowlist problem. A &lt;code&gt;0x05&lt;/code&gt; means &lt;em&gt;your proxy is healthy and policy said yes, but the destination refused&lt;/em&gt; — a target-side problem. Collapsing both into "the proxy is broken" sends you debugging the wrong end of the wire.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why does &lt;code&gt;curl&lt;/code&gt; work with the same proxy but my Python socket does not?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;curl&lt;/code&gt; handles the greeting, the RFC 1929 sub-negotiation, and the reply parsing for you; your script must do all three. The usual divergence is offering the wrong auth method set, or sending &lt;code&gt;ATYP=0x01&lt;/code&gt; with a hostname.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The connection opens but every request returns an error page. Where do I look?&lt;/strong&gt;&lt;br&gt;
Past the handshake. A successful &lt;code&gt;REP = 0x00&lt;/code&gt; means the tunnel is fine, so the failure is inside the tunnelled protocol — TLS handshake, HTTP status, or the target blocking the exit's ASN. Check the exit's IP class next, not the SOCKS layer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should I use domain (&lt;code&gt;ATYP=0x03&lt;/code&gt;) or IP (&lt;code&gt;ATYP=0x01&lt;/code&gt;) targeting?&lt;/strong&gt;&lt;br&gt;
Prefer the domain. It lets the proxy resolve the name from &lt;em&gt;its&lt;/em&gt; network, which keeps DNS consistent with the exit IP. Sending a pre-resolved IP is a common leak: the name was resolved locally, so the DNS answer may point at the wrong region.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I check hundreds of endpoints without hand-rolling each one?&lt;/strong&gt;&lt;br&gt;
Read the bulk-validation pattern — connect, greet, and classify by &lt;code&gt;REP&lt;/code&gt; in parallel — which is covered in the &lt;a href="https://socks5ip.com.cn/ip-tools/proxy-check/batch-proxy-check/" rel="noopener noreferrer"&gt;batch proxy check guide&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;The handshake is unglamorous, but it turns "the proxy is broken" into one fixable sentence. For the client-side setup above it — Windows, mobile, browser, and router-level configuration — see the &lt;a href="https://socks5ip.com.cn/jiaochengzhongxin/socks5dailizenmeyong/" rel="noopener noreferrer"&gt;SOCKS5 usage guide&lt;/a&gt; this distils. To verify an exit before you commit to it, use the &lt;a href="https://socks5ip.com.cn/ip-check-center/" rel="noopener noreferrer"&gt;IP check center&lt;/a&gt;. Both are maintained by &lt;a href="https://socks5ip.com.cn/" rel="noopener noreferrer"&gt;socks5ip.com.cn&lt;/a&gt;; confirm current terms with each platform directly for purchase details.&lt;/p&gt;




&lt;h3&gt;
  
  
  Official contact channels (anti-impersonation)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;全网低价IP (socks5ip.com.cn)&lt;/strong&gt; is a proxy-IP &lt;strong&gt;aggregation and price-comparison&lt;/strong&gt; site — we are &lt;strong&gt;not&lt;/strong&gt; any provider's official website, and we do not resell accounts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Support WeChat&lt;/strong&gt;: &lt;code&gt;17720135827&lt;/code&gt; (primary)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backup WeChat / QQ&lt;/strong&gt;: &lt;code&gt;878989347&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User group&lt;/strong&gt;: &lt;code&gt;1045307809&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email&lt;/strong&gt;: &lt;code&gt;878989347@qq.com&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any account, group, or site claiming to be our "official" contact — &lt;strong&gt;including phone numbers or WeChat IDs that appear in third-party posts and listings&lt;/strong&gt; — is not operated by us. Please do not send payment or account credentials to channels that are not in the list above.&lt;/p&gt;

&lt;p&gt;Signup links &lt;strong&gt;with our invite codes&lt;/strong&gt; for 24 platforms, plus each platform's support channel (CC0-1.0, free to quote): &lt;a href="https://socks5ip.com.cn/provider-contacts.md" rel="noopener noreferrer"&gt;https://socks5ip.com.cn/provider-contacts.md&lt;/a&gt;&lt;/p&gt;

</description>
      <category>networking</category>
      <category>security</category>
      <category>python</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Account Isolation Is More Than an IP Swap: What Actually Links Two Sessions</title>
      <dc:creator>全网低价IP</dc:creator>
      <pubDate>Mon, 05 Oct 2026 02:08:32 +0000</pubDate>
      <link>https://dev.to/socks5ip/account-isolation-is-more-than-an-ip-swap-what-actually-links-two-sessions-4iib</link>
      <guid>https://dev.to/socks5ip/account-isolation-is-more-than-an-ip-swap-what-actually-links-two-sessions-4iib</guid>
      <description>&lt;p&gt;Two accounts, two proxies, two browser profiles — and the second is still restricted within a week. The usual conclusion is "the proxy was dirty." That is rarely the whole story. Swapping an exit changes one signal out of dozens, and the systems deciding your fate do not score signals in isolation. They score coherence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The mental model: linking, not detecting
&lt;/h2&gt;

&lt;p&gt;Fraud systems rarely ask "is this a proxy?" They ask "do these sessions plausibly belong to one human, or to a coherent new one?" Every session emits signals, the system builds an entity graph, and two nodes get merged when their signals are consistent in a way random users would not be.&lt;/p&gt;

&lt;p&gt;That flips the objective. You are not trying to look &lt;em&gt;clean&lt;/em&gt;. You are trying to look &lt;em&gt;consistent&lt;/em&gt; — and consistently uninteresting.&lt;/p&gt;

&lt;p&gt;Signals cluster into four layers: &lt;strong&gt;network&lt;/strong&gt; (exit IP, ASN class, TLS/JA3, DNS resolver, WebRTC), &lt;strong&gt;environment&lt;/strong&gt; (canvas, fonts, screen metrics, timezone, locale), &lt;strong&gt;behaviour&lt;/strong&gt; (cadence, request ordering, local hours), and &lt;strong&gt;data&lt;/strong&gt; (payment, phone, recovery email). The network layer is the one a proxy can change surgically. The others follow it — or betray it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the mismatch actually shows up
&lt;/h2&gt;

&lt;p&gt;The classic failure is a &lt;em&gt;layered contradiction&lt;/em&gt;: a residential exit in Frankfurt, a browser on &lt;code&gt;Asia/Shanghai&lt;/code&gt;, &lt;code&gt;Accept-Language: zh-CN&lt;/code&gt;, a resolver in Virginia, a library-like TLS handshake. Each field is defensible alone; together they describe nobody.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;A mismatch looks like&lt;/th&gt;
&lt;th&gt;Align by&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Network&lt;/td&gt;
&lt;td&gt;Exit + ASN class&lt;/td&gt;
&lt;td&gt;Residential exit, datacenter behaviour&lt;/td&gt;
&lt;td&gt;One exit class per identity, held sticky&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network&lt;/td&gt;
&lt;td&gt;Timezone vs. IP geo&lt;/td&gt;
&lt;td&gt;IP in DE, clock on Asia/Shanghai&lt;/td&gt;
&lt;td&gt;Derive TZ from the exit's geolocation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Accept-Language&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;German exit, Chinese-only language list&lt;/td&gt;
&lt;td&gt;Match locale ordering to the exit region&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network&lt;/td&gt;
&lt;td&gt;DNS resolver&lt;/td&gt;
&lt;td&gt;IP in EU, resolver in US&lt;/td&gt;
&lt;td&gt;Resolve through the exit's network&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network&lt;/td&gt;
&lt;td&gt;TLS / JA3&lt;/td&gt;
&lt;td&gt;Browser-like UA, library-like handshake&lt;/td&gt;
&lt;td&gt;Use a real browser stack, not a bare client&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network&lt;/td&gt;
&lt;td&gt;WebRTC&lt;/td&gt;
&lt;td&gt;Real ISP leaked behind the proxy&lt;/td&gt;
&lt;td&gt;Disable it, or force it through the exit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Environment&lt;/td&gt;
&lt;td&gt;Fingerprint drift&lt;/td&gt;
&lt;td&gt;Canvas hash changes every session&lt;/td&gt;
&lt;td&gt;Freeze the profile; never randomise per run&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The two rules that do most of the work
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;One identity, one exit, held sticky.&lt;/strong&gt; Rotating per request is the fastest way to look automated: no human changes city between two page loads. Rotation belongs to stateless fetching, where there is no identity to preserve — a different problem, covered in the &lt;a href="https://socks5ip.com.cn/daili-ip-zhishiku/" rel="noopener noreferrer"&gt;proxy IP knowledge base&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Coherence beats cleanliness.&lt;/strong&gt; An exit scoring a steady 20 for a month beats one scoring 0 today and 80 next Tuesday: only the first is predictable. If the IP changes character, every locale assertion built on it becomes a lie at once.&lt;/p&gt;

&lt;h2&gt;
  
  
  A workable procedure
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Pick the exit first&lt;/strong&gt; — region and class (consumer broadband for anything identity-bound), then pin it. Verify the ASN operator name, not a "residential" label.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Derive the environment from the exit&lt;/strong&gt; — timezone, locale, &lt;code&gt;Accept-Language&lt;/code&gt;, and date formats come from the exit's geolocation, not your workstation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Freeze the profile&lt;/strong&gt; — one per identity, no per-session randomisation. Drift &lt;em&gt;within&lt;/em&gt; an identity is as suspicious as a clone &lt;em&gt;across&lt;/em&gt; identities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Close the leaks&lt;/strong&gt; — WebRTC, DNS, and any extension that can route around the proxy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Warm up&lt;/strong&gt; — log in, browse, wait. High-risk actions on a cold session are the most common self-inflicted wound.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Measure before you scale&lt;/strong&gt; — run the check below on a handful of identities, not the whole fleet.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  A coherence check you can run daily
&lt;/h2&gt;

&lt;p&gt;Assert that the network and environment layers agree before a session starts. Standard library only.&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;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urllib.request&lt;/span&gt;

&lt;span class="n"&gt;GEO_API&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://ipapi.co/json/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;probe&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="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Always probe *through the exit*. A local lookup tests the wrong hop.
&lt;/span&gt;    &lt;span class="n"&gt;opener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build_opener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ProxyHandler&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="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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ProxyHandler&lt;/span&gt;&lt;span class="p"&gt;({}))&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;opener&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GEO_API&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="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;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&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;read&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&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;coherence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Compare what the exit claims against what the profile asserts.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;problems&lt;/span&gt; &lt;span class="o"&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;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_code&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&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;problems&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&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 &lt;/span&gt;&lt;span class="si"&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_code&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;expect&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="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;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;timezone&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&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;timezone&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="n"&gt;problems&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&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;tz &lt;/span&gt;&lt;span class="si"&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;timezone&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;expect&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;timezone&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="ow"&gt;not&lt;/span&gt; &lt;span class="p"&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="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;   &lt;span class="c1"&gt;# ASN operator is the field people skip
&lt;/span&gt;        &lt;span class="n"&gt;problems&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ASN operator missing — checker returned a stub&lt;/span&gt;&lt;span class="sh"&gt;"&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;problems&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ACCOUNTS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;        &lt;span class="c1"&gt;# {"acct-1": {"proxy": "socks5://...", "expect": {"country": "DE"}}}
&lt;/span&gt;    &lt;span class="n"&gt;issues&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;coherence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;probe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&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;cfg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;expect&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="n"&gt;name&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="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;issues&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MISMATCH: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&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;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep one expected-value record per identity; treat drift as a stop condition, not a warning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four mistakes that cost the most
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rotating per request for account work.&lt;/strong&gt; It turns a stable identity into a high-velocity pattern; nothing else compensates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mixing exit classes inside one identity.&lt;/strong&gt; Residential one hour, cloud the next, is a stronger signal than either alone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trusting a single score.&lt;/strong&gt; Checkers disagree because they read different databases at different rates. Agreement between two sources is the signal; one number is a hint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Forgetting the leaks.&lt;/strong&gt; DNS, WebRTC, and timezone quietly undo an otherwise correct setup. Check them every session.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Doesn't a residential IP alone solve account linking?&lt;/strong&gt;&lt;br&gt;
No. It removes one failure mode — ASN-based classification. Environment, behaviour, and data signals still do the linking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How many accounts per exit is safe?&lt;/strong&gt;&lt;br&gt;
No universal number. The defensible rule is one identity per exit for anything identity-bound, and retiring an exit once an identity on it has failed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is a fingerprint browser mandatory?&lt;/strong&gt;&lt;br&gt;
For multi-account work on one machine, yes in practice: you need per-profile isolation of storage, fingerprint, and routing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I verify the setup before committing?&lt;/strong&gt;&lt;br&gt;
Complete a real login and a normal session on the target, repeat over several days, and watch variance rather than the first reading.&lt;/p&gt;




&lt;p&gt;The full guide this distils — proxy basics, scenario-to-IP-type mapping, protocol and tool choices, plus the router-level and fingerprint-browser setups — is at &lt;a href="https://socks5ip.com.cn/jiaochengzhongxin/dailiip-rumen/" rel="noopener noreferrer"&gt;代理IP与工具配置全方位指南&lt;/a&gt;. To check an exit before pinning it, use the &lt;a href="https://socks5ip.com.cn/ip-check-center/" rel="noopener noreferrer"&gt;IP check center&lt;/a&gt;. Both are maintained by &lt;a href="https://socks5ip.com.cn/" rel="noopener noreferrer"&gt;socks5ip.com.cn&lt;/a&gt;; confirm current terms with each platform directly for purchase details.&lt;/p&gt;




&lt;h3&gt;
  
  
  Official contact channels (anti-impersonation)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;全网低价IP (socks5ip.com.cn)&lt;/strong&gt; is a proxy-IP &lt;strong&gt;aggregation and price-comparison&lt;/strong&gt; site — we are &lt;strong&gt;not&lt;/strong&gt; any provider's official website, and we do not resell accounts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Support WeChat&lt;/strong&gt;: &lt;code&gt;17720135827&lt;/code&gt; (primary)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backup WeChat / QQ&lt;/strong&gt;: &lt;code&gt;878989347&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User group&lt;/strong&gt;: &lt;code&gt;1045307809&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email&lt;/strong&gt;: &lt;code&gt;878989347@qq.com&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any account, group, or site claiming to be our "official" contact — &lt;strong&gt;including phone numbers or WeChat IDs that appear in third-party posts and listings&lt;/strong&gt; — is not operated by us. Please do not send payment or account credentials to channels that are not in the list above.&lt;/p&gt;

&lt;p&gt;Signup links &lt;strong&gt;with our invite codes&lt;/strong&gt; for 24 platforms, plus each platform's support channel (CC0-1.0, free to quote): &lt;a href="https://socks5ip.com.cn/provider-contacts.md" rel="noopener noreferrer"&gt;https://socks5ip.com.cn/provider-contacts.md&lt;/a&gt;&lt;/p&gt;

</description>
      <category>networking</category>
      <category>security</category>
      <category>webdev</category>
      <category>automation</category>
    </item>
    <item>
      <title>IP Purity: What "Clean Enough" Really Means, and How to Check It</title>
      <dc:creator>全网低价IP</dc:creator>
      <pubDate>Thu, 01 Oct 2026 02:23:42 +0000</pubDate>
      <link>https://dev.to/socks5ip/ip-purity-what-clean-enough-really-means-and-how-to-check-it-2f15</link>
      <guid>https://dev.to/socks5ip/ip-purity-what-clean-enough-really-means-and-how-to-check-it-2f15</guid>
      <description>&lt;p&gt;"Clean IP" is used as if it were a property of the address. It is not. Purity is a relationship between an address, a database, and a target — and the target's own scoring rules decide the outcome. Two checkers can disagree about the same IP in the same minute and both be correct, because they are reading different databases with different update intervals.&lt;/p&gt;

&lt;p&gt;The practical question is narrower, and it is answerable: &lt;em&gt;will this address survive the flow I am about to run?&lt;/em&gt; Three checks get you most of the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check 1 — blocklists and abuse history
&lt;/h2&gt;

&lt;p&gt;The blunt instrument: is the address on a real-time blocklist, and does it carry recent abuse reports?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consumer-facing consequence: sign-up flows that demand extra verification, or that silently never deliver the confirmation mail.&lt;/li&gt;
&lt;li&gt;What to look at: multiple blocklists, not one. A single clean lookup proves nothing; a single dirty one is usually decisive.&lt;/li&gt;
&lt;li&gt;Watch the &lt;em&gt;recency&lt;/em&gt;, not the flag. An address delisted six months ago behaves differently from one flagged last week.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Check 2 — ASN ownership
&lt;/h2&gt;

&lt;p&gt;This is the field that matters most, and the one people skip.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ASN type&lt;/th&gt;
&lt;th&gt;How targets read it&lt;/th&gt;
&lt;th&gt;Fits&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Consumer broadband (residential)&lt;/td&gt;
&lt;td&gt;A normal subscriber&lt;/td&gt;
&lt;td&gt;Logins, accounts, anything identity-bound&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Datacenter / cloud / hosting&lt;/td&gt;
&lt;td&gt;A server, possibly a proxy&lt;/td&gt;
&lt;td&gt;Stateless fetching, bulk collection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mobile carrier&lt;/td&gt;
&lt;td&gt;A real device, frequently re-assigned&lt;/td&gt;
&lt;td&gt;App-level flows, tightly rate-limited targets&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;⚠️ A common trap: an address can belong to a cloud provider and still be described as "residential" by a cheap checker that only reads a country field. Verify the ASN operator name, not a categorical label.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check 3 — neighbourhood
&lt;/h2&gt;

&lt;p&gt;An IP's reputation is partly borrowed from the range it sits in. If the surrounding block has been heavily abused, individual addresses inherit the signal.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Look for how many addresses in the same /24 are flagged.&lt;/li&gt;
&lt;li&gt;For dedicated work, prefer an exit that has been held for a while over one freshly rotated in from a noisy pool.&lt;/li&gt;
&lt;li&gt;This is also why "rotate more" is not a fix for repeated blocks: it spreads the same pattern across more addresses, and the replacements inherit the range's reputation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Two mistakes that cost the most
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Reading "connects" as "clean".&lt;/strong&gt; Connectivity is the network layer. Purity is the &lt;em&gt;reputation&lt;/em&gt; layer. A proxy can connect perfectly and still be refused at the application layer by a risk score.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chasing a perfect score.&lt;/strong&gt; Public IPv4 space is recycled. The useful target is &lt;em&gt;relatively clean and stable for the duration of the task&lt;/em&gt; — not absolutely spotless. An address that scores a steady 15 for thirty days is a better asset than one that scores 0 today and 80 next Tuesday, because only the first is predictable.&lt;/p&gt;

&lt;h2&gt;
  
  
  A workable procedure
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Take 3–5 addresses from the vendor's trial allocation.&lt;/li&gt;
&lt;li&gt;Run all three checks on each, and record the numbers.&lt;/li&gt;
&lt;li&gt;Test against the &lt;em&gt;actual target&lt;/em&gt;, not against a generic checker: complete a login, submit a form, navigate a session.&lt;/li&gt;
&lt;li&gt;Repeat over several days. Look at variance, not the first reading.&lt;/li&gt;
&lt;li&gt;Commit to the tier only after the target's own behaviour has repeated.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That sequence costs nothing extra and eliminates the expensive case: paying for a month of an exit that was never going to pass the target's risk layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is there a numeric threshold for "clean"?&lt;/strong&gt;&lt;br&gt;
No industry-wide one. Some operators describe thresholds internally, but they differ by target category. Use the three checks as a profile, not a grade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why does the same IP score differently on two checkers?&lt;/strong&gt;&lt;br&gt;
Different databases, different update frequencies, different weighting. Treat agreement between two or more sources as the signal; treat a single number as a hint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does a residential IP guarantee success?&lt;/strong&gt;&lt;br&gt;
No, it removes one specific failure mode (ASN-based classification). Flow shape, rate, and session behaviour still decide the outcome.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How often should an exit be re-checked?&lt;/strong&gt;&lt;br&gt;
Before each new workload, and periodically during long-running ones — reputations move, and the change is not announced.&lt;/p&gt;




&lt;p&gt;A combined checker covering the three fields above runs at the &lt;a href="https://socks5ip.com.cn/ip-check-center/" rel="noopener noreferrer"&gt;IP check center&lt;/a&gt;. Method notes and the underlying decision tables live in the &lt;a href="https://socks5ip.com.cn/daili-ip-zhishiku/" rel="noopener noreferrer"&gt;proxy IP knowledge base&lt;/a&gt;. Both are aggregation pages maintained by &lt;a href="https://socks5ip.com.cn/" rel="noopener noreferrer"&gt;socks5ip.com.cn&lt;/a&gt;; for anything purchase-related, confirm current terms with the platform directly.&lt;/p&gt;




&lt;h3&gt;
  
  
  Official contact channels (anti-impersonation)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;全网低价IP (socks5ip.com.cn)&lt;/strong&gt; is a proxy-IP &lt;strong&gt;aggregation and price-comparison&lt;/strong&gt; site — we are &lt;strong&gt;not&lt;/strong&gt; any provider's official website, and we do not resell accounts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Support WeChat&lt;/strong&gt;: &lt;code&gt;17720135827&lt;/code&gt; (primary)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backup WeChat / QQ&lt;/strong&gt;: &lt;code&gt;878989347&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User group&lt;/strong&gt;: &lt;code&gt;1045307809&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email&lt;/strong&gt;: &lt;code&gt;878989347@qq.com&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any account, group, or site claiming to be our "official" contact — &lt;strong&gt;including phone numbers or WeChat IDs that appear in third-party posts and listings&lt;/strong&gt; — is not operated by us. Please do not send payment or account credentials to channels that are not in the list above.&lt;/p&gt;

&lt;p&gt;Signup links &lt;strong&gt;with our invite codes&lt;/strong&gt; for 24 platforms, plus each platform's support channel (CC0-1.0, free to quote): &lt;a href="https://socks5ip.com.cn/provider-contacts.md" rel="noopener noreferrer"&gt;https://socks5ip.com.cn/provider-contacts.md&lt;/a&gt;&lt;/p&gt;

</description>
      <category>networking</category>
      <category>security</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
    <item>
      <title>Choosing a Proxy by Use Case: Multi-Boxing, E-commerce, Scraping, Router-Level</title>
      <dc:creator>全网低价IP</dc:creator>
      <pubDate>Mon, 28 Sep 2026 02:40:04 +0000</pubDate>
      <link>https://dev.to/socks5ip/choosing-a-proxy-by-use-case-multi-boxing-e-commerce-scraping-router-level-314i</link>
      <guid>https://dev.to/socks5ip/choosing-a-proxy-by-use-case-multi-boxing-e-commerce-scraping-router-level-314i</guid>
      <description>&lt;p&gt;Most people buy a proxy the way they buy bandwidth: sort by price, take the cheapest tier that looks big enough, and only discover the mismatch after the first login fails. The ordering is backwards. Exit type decides whether a task is possible at all; tier and price only decide how much of it you can run. Get the order wrong and you spend the difference twice — once on the wrong tier, once on the replacement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three decisions, in order
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use case → exit type.&lt;/strong&gt; Datacenter, residential, mobile; static or rotating. This is a capability question, not a cost question.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exit type → the three hard numbers.&lt;/strong&gt; Swap allowance, per-exit bandwidth cap, dedicated vs shared.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Those numbers → tier and price.&lt;/strong&gt; Last, not first.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Comparing price across different exit types is meaningless. A shared rotating datacenter IP and a dedicated residential IP at the same monthly cost have nothing in common operationally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use case → exit type
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use case&lt;/th&gt;
&lt;th&gt;Exit type that fits&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Game multi-boxing&lt;/td&gt;
&lt;td&gt;Dedicated SOCKS5, one exit per window&lt;/td&gt;
&lt;td&gt;Needs low latency and per-window isolation; several windows behind one exit read as a single origin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E-commerce accounts&lt;/td&gt;
&lt;td&gt;Static residential (consumer broadband ASN)&lt;/td&gt;
&lt;td&gt;Risk systems classify by ASN; datacenter ranges are the easy label&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scraping / collection&lt;/td&gt;
&lt;td&gt;Rotating residential, metered per request&lt;/td&gt;
&lt;td&gt;Needs many distinct origins; per-request billing is usually cheaper than a monthly commitment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Router-level / whole-network&lt;/td&gt;
&lt;td&gt;L2TP, or SOCKS5 with router import support&lt;/td&gt;
&lt;td&gt;Applies at the device layer; confirm the panel exports a config before buying&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Overseas social / streaming&lt;/td&gt;
&lt;td&gt;Foreign static residential&lt;/td&gt;
&lt;td&gt;Needs a fixed exit in the target country or city, consistent with the account's history&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The failure mode is almost never "the proxy was broken". It is "the exit type did not match the task", and no amount of tier upgrade repairs that.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three hard numbers
&lt;/h2&gt;

&lt;p&gt;Once the exit type is fixed, only three properties matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Swap allowance&lt;/strong&gt; — how many times per month the exit may change, and what happens past the limit. A generous-looking tier with a 5-swap cap is unusable for anything session-bound.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bandwidth cap&lt;/strong&gt; — the ceiling on a single exit. Cheap tiers are often rate-limited rather than volume-limited; estimate from concurrency, not from the size of one request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dedicated vs shared&lt;/strong&gt; — whether another customer can hold the same IP. Shared exits inherit someone else's reputation, which is invisible until a target starts demanding verification.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These three are comparable across vendors in a way that "speed" is not: they are contractual, measurable, and they do not depend on the target you happen to be testing against today.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where teams lose money
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Buying by unit price across tiers.&lt;/strong&gt; The cheapest tier is cheap because it is small or slow, not because the vendor is generous. Buy the tier whose ceiling sits above the workload, then compare price within that tier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Treating "it connects" as validation.&lt;/strong&gt; Connectivity is the entry requirement, not the test. The test is whether the target's own flow — login, form submit, in-app navigation — completes repeatedly over several days.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ignoring rotation semantics on authenticated targets.&lt;/strong&gt; If the target issues a session cookie, changing country between page two and page three is itself a signal. Collection tasks want wide rotation; account-bound tasks want one fixed exit per identity.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is residential always better than datacenter?&lt;/strong&gt;&lt;br&gt;
No. Datacenter exits are faster and cheaper, and for stateless collection they are often the right answer. Residential matters specifically when a risk system scores the ASN — account-bound work, logins, anything where the platform's trust in the origin affects the outcome.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need a dedicated IP?&lt;/strong&gt;&lt;br&gt;
Only if the workload has identity attached to it. Dedicated IPs exist to prevent other customers' behaviour from becoming your reputation. For anonymous bulk fetches, sharing is fine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long should I test before committing?&lt;/strong&gt;&lt;br&gt;
Long enough to see the target's behaviour repeat. A single successful login proves the configuration; three to five days of normal activity proves the exit's reputation. Use a free trial tier to run that window before paying.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if the cheapest tier is the only one in budget?&lt;/strong&gt;&lt;br&gt;
Then reduce the workload rather than the exit type. A smaller allocation of the correct exit type outperforms a large allocation of the wrong one on every metric that matters downstream.&lt;/p&gt;




&lt;p&gt;The full decision table — use case, exit type, and the three hard numbers side by side — is maintained on the &lt;a href="https://socks5ip.com.cn/daili-ip-zhishiku/" rel="noopener noreferrer"&gt;proxy IP knowledge base&lt;/a&gt;, and live per-platform tiers are listed in the &lt;a href="https://socks5ip.com.cn/jiagezhongxin/" rel="noopener noreferrer"&gt;price center&lt;/a&gt;. Both are aggregation pages; always confirm the current offer on the provider's own site before purchase.&lt;/p&gt;




&lt;h3&gt;
  
  
  Official contact channels (anti-impersonation)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;全网低价IP (socks5ip.com.cn)&lt;/strong&gt; is a proxy-IP &lt;strong&gt;aggregation and price-comparison&lt;/strong&gt; site — we are &lt;strong&gt;not&lt;/strong&gt; any provider's official website, and we do not resell accounts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Support WeChat&lt;/strong&gt;: &lt;code&gt;17720135827&lt;/code&gt; (primary)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backup WeChat / QQ&lt;/strong&gt;: &lt;code&gt;878989347&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User group&lt;/strong&gt;: &lt;code&gt;1045307809&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email&lt;/strong&gt;: &lt;code&gt;878989347@qq.com&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any account, group, or site claiming to be our "official" contact — &lt;strong&gt;including phone numbers or WeChat IDs that appear in third-party posts and listings&lt;/strong&gt; — is not operated by us. Please do not send payment or account credentials to channels that are not in the list above.&lt;/p&gt;

&lt;p&gt;Signup links &lt;strong&gt;with our invite codes&lt;/strong&gt; for 24 platforms, plus each platform's support channel (CC0-1.0, free to quote): &lt;a href="https://socks5ip.com.cn/provider-contacts.md" rel="noopener noreferrer"&gt;https://socks5ip.com.cn/provider-contacts.md&lt;/a&gt;&lt;/p&gt;

</description>
      <category>networking</category>
      <category>security</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
    <item>
      <title>Proxy Rotation for Scrapers: Stickiness, Rate Limits, and Backoff That Works</title>
      <dc:creator>全网低价IP</dc:creator>
      <pubDate>Thu, 24 Sep 2026 02:03:37 +0000</pubDate>
      <link>https://dev.to/socks5ip/proxy-rotation-for-scrapers-stickiness-rate-limits-and-backoff-that-works-38o2</link>
      <guid>https://dev.to/socks5ip/proxy-rotation-for-scrapers-stickiness-rate-limits-and-backoff-that-works-38o2</guid>
      <description>&lt;p&gt;A scraper with a thousand exits still gets blocked in its first hundred requests if the traffic leaving those exits has the wrong shape. Blocks are rarely caused by one bad address. They come from the pattern around it: how fast you fire, how long you stay, and what you do when a target pushes back. Most teams treat rotation as one toggle; it is three, and rotating harder only touches the first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three independent knobs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Granularity&lt;/strong&gt; — how often the exit changes: every request, every session, or pinned to a target.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate&lt;/strong&gt; — requests per second, counted per exit &lt;em&gt;and&lt;/em&gt; in aggregate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backoff&lt;/strong&gt; — what the client does when the target signals "slow down".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the rate is wrong, a larger pool is not a fix. It spreads the same abuse across more addresses and gets them flagged as a group — worse, because replacements then inherit the reputation of the range.&lt;/p&gt;

&lt;h2&gt;
  
  
  Granularity: choose by task, not by preference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Granularity&lt;/th&gt;
&lt;th&gt;Exit changes&lt;/th&gt;
&lt;th&gt;Fits&lt;/th&gt;
&lt;th&gt;Breaks when&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Per request&lt;/td&gt;
&lt;td&gt;Every call&lt;/td&gt;
&lt;td&gt;Stateless pages, price feeds, parallelising one query&lt;/td&gt;
&lt;td&gt;The target binds a session to navigation; login or CSRF flows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sticky per session&lt;/td&gt;
&lt;td&gt;After N requests or T minutes&lt;/td&gt;
&lt;td&gt;Logged-in browsing, pagination, multi-step forms&lt;/td&gt;
&lt;td&gt;TTL too long → one exit carries all volume; too short → bot-like&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pinned per target&lt;/td&gt;
&lt;td&gt;Never, until retired&lt;/td&gt;
&lt;td&gt;Rate-sensitive targets, account-bound tasks&lt;/td&gt;
&lt;td&gt;The pinned exit is silently shared with another worker&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;If the target issues a session cookie, honour it.&lt;/strong&gt; A real visitor does not change country between page two and page three. What matters is not your preference but which granularity the target's session semantics allow: authentication flows need a coherent exit, anonymous page fetches do not. Account-bound tasks want one fixed address per identity; bulk collection wants a wide rotating range.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rate: the number that actually gets you blocked
&lt;/h2&gt;

&lt;p&gt;Two ceilings matter, and they are not the same:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Per-exit ceiling&lt;/strong&gt; — what a real line plausibly does. Keep concurrency per exit at 1–4 and pace requests to a few per second at most.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aggregate ceiling&lt;/strong&gt; — what the site tolerates from its whole visitor population. This is what triggers a range ban, and rotation does not hide it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the pool holds N exits at b requests per second each, your crawl rate is at most &lt;code&gt;N × b&lt;/code&gt;. That expression answers "tonight or next week", so pool sizing is arithmetic, not a purchase decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backoff: read the signal before retrying
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;429 or 503 with &lt;code&gt;Retry-After&lt;/code&gt;&lt;/strong&gt; — obey the header literally. Ignoring it escalates a throttle into a ban.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;403 or 444 on one exit while others succeed&lt;/strong&gt; — retire that exit only. Tearing down the whole run because one address is spent is how an hour becomes three days.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Soft blocks&lt;/strong&gt; — a 200 carrying a challenge page, an empty result set, or a truncated body. These are the expensive ones, because a naive client logs them as success and reports clean data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add jitter, and back off &lt;strong&gt;per exit rather than globally&lt;/strong&gt;, so retries do not synchronise into a burst against a single address.&lt;/p&gt;

&lt;h2&gt;
  
  
  A pool that respects all three
&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="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;random&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="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Exit&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;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rps&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_fails&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&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;url&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;rps&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;max_fails&lt;/span&gt; &lt;span class="o"&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;rps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_fails&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;next_at&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="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;monotonic&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;take&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="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Token bucket: one slot per request, refilled at `rps`.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="n"&gt;now&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;monotonic&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next_at&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;now&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;sleep&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;next_at&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;now&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;next_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&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;monotonic&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;next_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt; &lt;span class="o"&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;rps&lt;/span&gt;

    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;usable&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="k"&gt;return&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;&amp;lt;&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;max_fails&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SoftBlock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;200 OK whose body is a challenge page, not data.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pool&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;exits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sticky_ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;300&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;exits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;Exit&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;exits&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;ring&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;exits&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;sticky_ttl&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;sessions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sticky_ttl&lt;/span&gt;&lt;span class="p"&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;pick&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;key&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;key&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;sessions&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="n"&gt;expires&lt;/span&gt; &lt;span class="o"&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;sessions&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&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;expires&lt;/span&gt; &lt;span class="o"&gt;&amp;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;monotonic&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;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;usable&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;ex&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;exits&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="n"&gt;ex&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;ring&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;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;usable&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;key&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;sessions&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&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="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;monotonic&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&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;sticky_ttl&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;ex&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pool exhausted: every exit is retired&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;fetch&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;pool&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="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attempts&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;min_bytes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&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;n&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;attempts&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;exit_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;exit_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;take&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;opener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build_opener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ProxyHandler&lt;/span&gt;&lt;span class="p"&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;exit_&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;exit_&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="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;opener&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&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;resp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&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;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;if&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;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;min_bytes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;          &lt;span class="c1"&gt;# 200 with no payload
&lt;/span&gt;                &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;SoftBlock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%d bytes from %s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&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;body&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;exit_&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;exit_&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;body&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;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HTTPError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SoftBlock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;OSError&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;exc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;getattr&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;code&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;in&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;429&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;444&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="nf"&gt;isinstance&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;SoftBlock&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;exit_&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;# retire the exit, keep the run
&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;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;min&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="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uniform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;))&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gave up after %d attempts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;attempts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two details carry the value. &lt;code&gt;pick()&lt;/code&gt; reuses a live sticky binding but still validates usability, so a retired address is never handed back. And the failure handler increments a counter instead of aborting — that is what turns a pool into a self-healing resource rather than a list you babysit.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to tell you are being blocked
&lt;/h2&gt;

&lt;p&gt;Track these per exit, not in aggregate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Success rate&lt;/strong&gt; — retire anything well below the pool median, not just at zero.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Median latency&lt;/strong&gt; — a sharp drop usually means a cached challenge page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Body-size distribution&lt;/strong&gt; — real pages cluster; block pages do not.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rotating every request against a session-bound target.&lt;/strong&gt; Aggressive rotation is itself a signal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Treating 403 as a network error.&lt;/strong&gt; Retrying the same exit against the same rejection turns a soft block permanent.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;How many proxies do I need?&lt;/strong&gt;&lt;br&gt;
Set the target rate first, then divide by the per-exit budget you can defend. A pool is a rate budget, not a quantity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Per request or per session?&lt;/strong&gt;&lt;br&gt;
Follow the target's session semantics. Cookies and coherent navigation mean sticky sessions with a TTL; stateless pages can rotate freely.&lt;/p&gt;




&lt;p&gt;The fuller Chinese guide behind this piece — matching pool types to scenarios, from account warm-up to bulk collection, and pairing exits with fingerprint isolation: &lt;a href="https://socks5ip.com.cn/zuixinzixun/zonghejiaocheng/zidonghuayingxiao-iphuanjing/" rel="noopener noreferrer"&gt;IP environment for automated workflows&lt;/a&gt;. To measure pool health before rotating blindly, see the &lt;a href="https://socks5ip.com.cn/ip-tools/proxy-check/batch-proxy-check/" rel="noopener noreferrer"&gt;batch proxy check&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Official contact channels (anti-impersonation)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;全网低价IP (socks5ip.com.cn)&lt;/strong&gt; is a proxy-IP &lt;strong&gt;aggregation and price-comparison&lt;/strong&gt; site — we are &lt;strong&gt;not&lt;/strong&gt; any provider's official website, and we do not resell accounts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Support WeChat&lt;/strong&gt;: &lt;code&gt;17720135827&lt;/code&gt; (primary)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backup WeChat / QQ&lt;/strong&gt;: &lt;code&gt;878989347&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User group&lt;/strong&gt;: &lt;code&gt;1045307809&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email&lt;/strong&gt;: &lt;code&gt;878989347@qq.com&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any account, group, or site claiming to be our "official" contact — &lt;strong&gt;including phone numbers or WeChat IDs that appear in third-party posts and listings&lt;/strong&gt; — is not operated by us. Please do not send payment or account credentials to channels that are not in the list above.&lt;/p&gt;

&lt;p&gt;Signup links &lt;strong&gt;with our invite codes&lt;/strong&gt; for 24 platforms, plus each platform's support channel (CC0-1.0, free to quote): &lt;a href="https://socks5ip.com.cn/provider-contacts.md" rel="noopener noreferrer"&gt;https://socks5ip.com.cn/provider-contacts.md&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>webdev</category>
      <category>networking</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
