Proxy bandwidth billing: how providers count traffic

    Per-GB proxy billing counts request headers, TLS, redirects and failed responses, not just the page body. Here is every component, and how to audit it.

    · 14 min read · Pricing and economics

    Proxy bandwidth billing is easy to state and hard to predict. Providers count traffic in gigabytes crossing the connection, in both directions, whether or not the bytes were useful to you. Every page in this market advertises a price per gigabyte. Almost none of them define the gigabyte. That gap is where budgets break: you model the size of the pages you want, you buy against that model, and the invoice arrives 30 to 60 percent higher than the model said.

    This article defines the unit. Component by component, with the commands that let you count it yourself.

    The unit is a byte on the wire, not a page you received

    Start from the mental model that causes the problem. Most people budget as if they are buying documents. Ten thousand product pages at 80 KB each is 800 MB, so buy a gigabyte and go.

    The meter does not see documents. It sees a socket. Bytes go up the socket to the target and bytes come back down it, and both directions are traffic. A request you sent is billable even though nothing came back. A response you threw away is billable because it arrived. A redirect that took you somewhere you did not want to go is billable twice — once for the redirect, once for the destination.

    Three consequences follow immediately, and they are the three that surprise people:

    1. Small responses are the expensive ones, per unit of data. A 400-byte JSON reply carries the same protocol overhead as a 400 KB HTML page. On the JSON call, that overhead is most of the bill.
    2. Failures are not free. A blocked request still opened a connection, still negotiated TLS, still sent headers, and usually still received a body.
    3. Your own instrumentation will read low. Whatever you count in your HTTP client sits above several layers that the meter may also be counting.

    How providers count traffic, component by component

    Here is everything that can land inside a single billed request. Sizes vary by client, target and protocol version, so the column that matters is not the number — it is whether the component is under your control.

    Component Direction Under your control? Notes
    TCP connection setup both Partly Amortized if you reuse connections. Paid again on every new connection.
    TLS handshake both Partly Dominated by the server's certificate chain, which you do not choose. Session resumption removes most of it on later connections.
    CONNECT tunnel establishment both No For HTTPS through an HTTP proxy, the tunnel is set up before the request exists.
    Request line and headers up Yes Cookies, User-Agent, Accept-*. A fat cookie jar is pure cost on every request.
    Request body up Yes POST/GraphQL payloads. Usually small, occasionally not.
    Response headers down Partly Set-Cookie chains and security headers are larger than people expect.
    Response body down Yes The only part you actually wanted. Compressible.
    Each redirect hop both Partly A 301 is a full request/response cycle with headers on both sides.
    Retransmits and keepalives both No Depends on where the meter reads. Ask.

    The single most useful reframing: you are not billed for a page, you are billed for a conversation. The page is one turn in it.

    A worked example you can run in 30 seconds

    Do not take a vendor's byte breakdown on faith, including this one. Produce your own:

    curl -s -o /dev/null \
      -w 'req_line+hdrs=%{size_request}\nreq_body=%{size_upload}\nresp_hdrs=%{size_header}\nresp_body=%{size_download}\nredirects=%{num_redirects}\ntotal_time=%{time_total}\n' \
      -H 'Accept-Encoding: gzip, br' \
      -L 'https://example.com/some/product/page'
    

    Add the four size fields together and you have the HTTP-layer cost of one fetch. Run it with -L and without, and the difference is what your redirect chain costs. Run it with and without the Accept-Encoding header and the difference is what compression is saving you — see how to cut proxy bandwidth costs for what to do when a server ignores it.

    Two calibration points for the response-body half of that sum, from a source that publishes its method rather than asserting a range. The HTTP Archive's 2025 Web Almanac page weight chapter, from its July 2025 crawl, puts the median home page at 2,559 KB on mobile and 2,862 KB on desktop (Figure 14.1). Inside that same median home page, HTML is 22 KB (Figures 14.5 and 14.6). The remaining 2.5 MB is images, JavaScript, CSS and fonts. Whether you pay for it is decided entirely by whether your client fetches subresources.

    That is the whole headless-browser question in one sentence, and it is why the same crawl can cost more than a hundred times as much depending on the client you point at it — the per-page-type arithmetic is in measured bandwidth by page type.

    The table above deliberately carries no byte sizes for the request and TLS components, because no public dataset publishes them and this article will not invent them. Produce your own: run tcpdump on an uninstrumented host outside the proxy path, against one target, under three protocol configurations (HTTP/1.1 with TLS 1.2, HTTP/1.1 with TLS 1.3, HTTP/2 with TLS 1.3). The per-component split changes enough between those three that a single published number would mislead you anyway.

    What proxy bandwidth billing does when the request fails

    Four failure shapes, four very different byte profiles.

    Connection refused or DNS failure. Near zero. Nothing was tunneled. DNS itself is resolved by the exit, not billed as your traffic by most designs — confirm with your provider rather than assuming.

    407 or another auth rejection. Headers only, in both directions. Small, but it happens once per misconfigured worker per attempt, and misconfigured workers retry fast.

    403 or 429 with a challenge body. The expensive one. A modern bot- management interstitial is a real HTML document with inline JavaScript. You paid the handshake, the request, the response headers and the body — and got nothing parseable.

    Timeout mid-body. You pay for what arrived. A stream that dies at 60 percent of a 3 MB asset cost you roughly 1.8 MB and produced no record.

    Failed requests deserve their own treatment, because at scale they are not an edge case — they are a line item. Failed requests are billed too, and that article takes each of the four classes apart with a retry budget that survives contact with a per-GB plan.

    The success-rate multiplier

    This is the arithmetic that decides whether a project is viable, and it is arithmetic, not a statistic. No measurement required.

    If you need N gigabytes of usable data and your success rate is s, you are billed for approximately N / s gigabytes, before retries change anything about s.

    Take a 10 TB collection target:

    Success rate Billed volume Overhead vs. the target
    95% 10.53 TB +0.53 TB
    90% 11.11 TB +1.11 TB
    70% 14.29 TB +4.29 TB
    50% 20.00 TB +10.00 TB
    30% 33.33 TB +23.33 TB

    The curve is not linear and that is the point. Moving from 95 to 90 percent costs you half a terabyte. Moving from 50 to 30 percent costs you thirteen. A project that models cost at a healthy success rate and then meets a hardened target does not overrun by a margin — it overruns by a multiple.

    Put a price on it. At the residential rate published on the per-gigabyte rates page as of 2026-08-06, $1.99/GB, the same 10 TB of usable data costs $19,900 at a 100 percent success rate and $28,437 at 70 percent. The $8,537 difference bought you nothing. Rates change; check the page rather than this sentence.

    This is also why cost per successful request is the only number worth tracking. Cost per gigabyte is a rate card. Cost per successful request is your actual unit economics, and it moves when your blocking rate moves.

    Why a headless browser changes the arithmetic

    A plain HTTP client fetches one document. A headless browser fetches the document and then everything the document references: scripts, stylesheets, fonts, images, analytics beacons, ad tags, video posters. Against the median home page above, that is the difference between paying for 22 KB and paying for 2,559 KB on the same URL.

    Sometimes that is the right trade. Rendering defeats some detection, and some data genuinely only exists after JavaScript runs. But it is a trade, and it should be priced before it is made. See what a headless browser costs in gigabytes for the decision table.

    Per-GB, per-IP and per-request: what each model hides

    Every pricing model is a bet about which variable stays stable. The model does not remove risk; it moves it onto you or off you.

    Model What it hides You are exposed to Best when
    Per GB Success rate Blocking. Your bill scales with failure. Page weight is predictable and targets are tolerant.
    Per IP Utilization Idle capacity. You pay for addresses whether or not you use them. Sustained, steady, high-volume load.
    Per request Page weight Heavy pages. A 5 MB page costs the same as a 5 KB one. Small, uniform responses — APIs and JSON endpoints.
    Unmetered Contention and shaping Whatever the provider does to keep the plan profitable. You can test throughput before committing.

    Notice that no model is honest about all three variables at once. Choosing a pricing model is choosing which of your three unknowns you want to be surprised by.

    Per-IP pricing hides a second thing: it invites you to reason about a provider's headline pool number, which is unverifiable from outside. The pool figure a vendor prints on its homepage is not a measurement you can reproduce. Budget against your own throughput, not against someone else's count of addresses — the case against buying on pool size is made in full under per-IP pricing hides utilization risk.

    How to reconcile your own bill

    Three methods, in increasing order of fidelity. Run at least two. The disagreement between them is informative.

    Method 1 — count in the client. The curl -w invocation above, or the equivalent counters in your HTTP library. Cheapest to run. Reads lowest, because it sees the HTTP layer and nothing beneath it.

    Method 2 — count at a local intermediary. Point your scraper at a local mitmproxy and count there:

    # count.py — mitmproxy addon: mitmdump -s count.py
    up = down = n = 0
    
    def response(flow):
        global up, down, n
        n += 1
        up += len(str(flow.request.headers)) + len(flow.request.raw_content or b"")
        down += len(str(flow.response.headers)) + len(flow.response.raw_content or b"")
        print(f"n={n} up={up} down={down} total={up + down}")
    

    This catches traffic your application code never sees — the subresources a browser pulled, the redirect hops your client followed transparently. Still above the transport layer.

    Method 3 — count at the socket. Run the job in an isolated network namespace or container and read the interface counters before and after:

    cat /sys/class/net/eth0/statistics/rx_bytes /sys/class/net/eth0/statistics/tx_bytes
    # ...run the job...
    cat /sys/class/net/eth0/statistics/rx_bytes /sys/class/net/eth0/statistics/tx_bytes
    

    This sees everything: TLS records, TCP retransmits, keepalives, ACKs. It is the closest civilian approximation of a wire meter, and it will read higher than your provider if the provider meters at the HTTP layer rather than the socket.

    Why your number will differ. Expect a gap in both directions and know which one you are looking at:

    • Client-side counts read low. They miss TLS record framing, TCP/IP headers, retransmits and the CONNECT exchange.
    • Socket-side counts read high if the provider excludes transport overhead.
    • Compression accounting differs. If you count decoded bytes and the provider counts transferred bytes, a gzipped HTML page can differ by 4x between the two figures. Always count what came off the socket, not what your parser saw.

    A reconciliation within a few percent is normal and not worth chasing. A reconciliation off by 30 percent means one of you is counting a component the other is not, and the five questions below will find it.

    What AnonEdge documents about billed traffic

    One rate rule is published rather than inferred. Traffic routed through advanced Target Filters — state, city, ZIP and ASN — is billed at 2x the standard rate, while country selection and ASN exclusion are included in the base price. Both are documented under country, city and ASN targeting. If you are filtering to a ZIP code out of habit rather than necessity, you are paying double for the habit.

    Two gateway-side rejections also show up in traffic accounting discussions: 400 NO_RAY and 407 THREADS_EXHAUSTED. The first means no exit matched your filter. The second means you hit your plan's concurrent connection limits. Both are rejections, not responses from your target.

    Everything else about the meter — whether headers and the TLS handshake are counted, whether non-200 responses are billed, where the meter is read — is a question to put in writing to any provider, this one included. That is what the next section is for. Take a written answer, not a sales answer.

    Five questions to send a provider before you buy

    Send these as written. The quality of the answer tells you as much as the answer.

    1. What exactly is the billable unit? Request bytes plus response bytes? Headers included? Is the TLS handshake counted? Is TCP/IP overhead counted?
    2. How is a failed request billed? Specifically: a 403 with a challenge body, a 429, a connection reset mid-body, and a request that never received a response.
    3. How are redirects billed? One request or one per hop?
    4. How are retries billed, and do you retry on my behalf? Some gateways silently retry upstream. If yours does, ask whether those attempts land on your meter.
    5. Where is the meter read — at the gateway or at the exit node? This single answer determines whether the leg between the gateway and the exit is your traffic or the provider's.

    A provider that answers all five in writing is telling you the unit is well-defined internally. A provider that answers in ranges is telling you it is not.

    Frequently asked questions

    Are request headers included in proxy bandwidth billing?

    Under a per-GB model, traffic is counted in both directions, so request headers normally count. This matters most on high-volume, low-payload work: a large cookie jar and a verbose User-Agent are sent on every single request, and against a 400-byte JSON response the headers can exceed the payload. Confirm the exact rule with your provider in writing before you model a job that makes millions of small calls.

    Does a failed request use bandwidth?

    Yes, in every case where a connection was established. The TLS handshake, the request headers and any response body all crossed the wire before the failure was known. A 403 served with a bot-management challenge page is the most expensive failure class, because the challenge is a real HTML document with inline JavaScript. Only a refused connection or a DNS failure approaches zero cost.

    How do I estimate proxy bandwidth before I buy?

    Measure one representative page with curl -w, summing size_request, size_upload, size_header and size_download. Multiply by your page count. Then divide by your expected success rate, and multiply by your average attempts per URL. That four-step estimate is usually within a reasonable margin of the invoice. Skipping the success-rate division is the single most common budgeting error.

    Why is my proxy traffic usage higher than expected?

    Four causes account for most overruns, in order of frequency: retries against a target that has started blocking you, a headless browser downloading subresources you never parse, redirect chains counted per hop, and compression that was requested but not delivered. Measure the response class distribution first. You cannot cut what you have not attributed.

    Is per-GB cheaper than per-IP pricing?

    It depends on which variable is stable for you. Per-GB is cheaper for bursty, intermittent or low-volume work, because you pay nothing while idle. Per-IP is cheaper for sustained high-throughput work, because the marginal gigabyte is free once the address is paid for. The break-even point is set by your utilization, not by the headline rate on either plan.

    Do redirects count as separate billed requests?

    Usually yes. Each hop in a redirect chain is a full request and response with headers in both directions, and following a chain of three means paying for four exchanges to receive one document. Resolve redirect chains once during development, store the final URLs, and request those directly. On a recurring crawl this is one of the easiest reductions available.


    Check the per-gigabyte rates before you size the job. Datacenter, residential and mobile are metered the same way and priced differently, and the right choice is the cheapest pool that still succeeds against your target — see datacenter, residential and mobile pools for the comparison. Route through gw.anonedge.com:823 and measure your own byte count from the first request.