> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apiyi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# CDN Image/Video Downloads Are Slow — What to Do?

> APIYI hosts all generated images and videos on Cloudflare R2's global CDN. This guide helps you diagnose slow downloads from specific servers.

## Quick Answer

All images and videos generated by APIYI (Veo 3.1, Sora, Nano Banana, etc.) are hosted on **Cloudflare R2's global CDN**, which is fast worldwide by design. If downloads on your server are slow, **it is almost always a network-path issue between your server and Cloudflare's edge**, not a CDN problem itself — especially for servers in mainland China accessing overseas CDNs, where cross-border bandwidth, ISP routing, and local DNS resolution often degrade performance.

<Info>
  **Key point**

  Cloudflare R2 resource URLs typically look like `*.r2.cloudflarestorage.com` or a custom domain proxied through Cloudflare. Download speed depends on how efficiently your server can reach the nearest Cloudflare edge node.
</Info>

## Common Causes

<CardGroup cols={2}>
  <Card title="Cross-border congestion" icon="network">
    Servers in mainland China reaching overseas CDNs often hit congestion on international egress during peak hours, causing slowness or timeouts.
  </Card>

  <Card title="Suboptimal ISP routing" icon="route">
    Some cloud providers route international traffic through the US West or Europe, adding tens of milliseconds of unnecessary latency.
  </Card>

  <Card title="Poor DNS resolution" icon="globe">
    Local DNS may resolve Cloudflare hostnames to a distant edge (e.g., US West) instead of the nearest APAC node.
  </Card>

  <Card title="Firewall / security group limits" icon="shield">
    Some servers restrict outbound traffic to overseas IP ranges, port 443, or specific CDN domains, degrading connection quality.
  </Card>

  <Card title="HTTP/2 & connection reuse" icon="plug">
    Clients without HTTP/2 or connection reuse pay the TCP/TLS handshake cost for every file.
  </Card>

  <Card title="Single-threaded download" icon="gauge">
    Serial single-threaded downloads can't benefit from CDN multiplexing; throughput stays low.
  </Card>
</CardGroup>

## Troubleshooting Steps

<Steps>
  <Step title="Is it one server or everywhere?">
    Try downloading the same CDN URL from your laptop or another server.

    * Laptop fast, server slow → **server network path issue**
    * Slow everywhere → contact support with the specific URL
  </Step>

  <Step title="Test basic network to the CDN">
    Use `ping`, `mtr`, `traceroute` to inspect latency and packet loss:

    ```bash theme={null}
    ping <cdn-host>
    mtr -rwc 30 <cdn-host>
    traceroute <cdn-host>
    ```

    Packet loss, latency above 200ms, or routes bouncing overseas all indicate link-level problems.
  </Step>

  <Step title="Measure real download speed">
    Use `curl` to inspect timing and throughput:

    ```bash theme={null}
    curl -o /dev/null -w "dns:%{time_namelookup} connect:%{time_connect} \
    ttfb:%{time_starttransfer} total:%{time_total} speed:%{speed_download}\n" \
    "<CDN URL>"
    ```

    Focus on:

    * `time_namelookup`: DNS resolution time
    * `time_connect`: TCP connect time
    * `time_starttransfer`: Time to first byte (TTFB)
    * `speed_download`: Average throughput (bytes/sec)
  </Step>

  <Step title="Inspect DNS resolution">
    ```bash theme={null}
    dig <cdn-host>
    nslookup <cdn-host>
    ```

    Check whether the resolved IP is geographically near you. APAC users should get APAC edges; if not, switch to a public DNS.
  </Step>

  <Step title="Check server-side restrictions">
    Verify that security groups and firewalls allow port 443 and overseas IP ranges, and make sure there's no egress bandwidth cap in place.
  </Step>
</Steps>

## Solutions

### Option 1: Switch to a public DNS (easiest)

Default DNS on many servers resolves Cloudflare to distant nodes. Try these public DNS servers:

```bash theme={null}
{/* /etc/resolv.conf */}
nameserver 1.1.1.1        # Cloudflare
nameserver 8.8.8.8        # Google
nameserver 223.5.5.5      # AliDNS
nameserver 119.29.29.29   # DNSPod
```

<Tip>
  Prefer `1.1.1.1` — it's Cloudflare's own DNS and reliably resolves to the nearest Cloudflare edge, which is ideal for R2 / Cloudflare CDN traffic.
</Tip>

### Option 2: Optimize how you download

<CardGroup cols={2}>
  <Card title="Parallel downloads" icon="layers">
    For batches of files use a parallel downloader (`aria2c -x 8`, Python `asyncio + httpx`) to saturate bandwidth.
  </Card>

  <Card title="Resumable downloads" icon="refresh-cw">
    For large videos, use HTTP Range requests with retry so a failure doesn't restart from zero.
  </Card>

  <Card title="Connection reuse" icon="plug">
    Use clients with HTTP/2 or keep-alive (`httpx`, `requests.Session()`) to avoid repeated handshakes.
  </Card>

  <Card title="Stream to disk" icon="hard-drive">
    Stream the response directly to disk instead of loading the whole file into memory.
  </Card>
</CardGroup>

**Python example (recommended)**:

```python theme={null}
import httpx
import asyncio

async def download(url: str, path: str):
    async with httpx.AsyncClient(http2=True, timeout=120) as client:
        async with client.stream("GET", url) as resp:
            resp.raise_for_status()
            with open(path, "wb") as f:
                async for chunk in resp.aiter_bytes(chunk_size=1024 * 256):
                    f.write(chunk)

asyncio.run(download("<CDN URL>", "output.mp4"))
```

**aria2c example (CLI)**:

```bash theme={null}
aria2c -x 8 -s 8 -k 1M --file-allocation=none "<CDN URL>"
```

### Option 3: Move to a better-connected region

If your use case allows it, prefer regions with good connectivity to Cloudflare:

<CardGroup cols={2}>
  <Card title="Overseas (recommended)" icon="globe">
    AWS / GCP / Azure / Cloudflare Workers all reach Cloudflare R2 with very low latency (typically 10-50ms).
  </Card>

  <Card title="China: premium DCs" icon="server">
    If you must deploy in mainland China, pick DCs with triple-network BGP + premium international links (CN2 GIA, CMI, AS9929).
  </Card>

  <Card title="Hong Kong / Singapore" icon="network">
    A good compromise: low latency to mainland China (30-80ms) and excellent APAC Cloudflare connectivity.
  </Card>

  <Card title="Avoid cheap VPS" icon="alert-triangle">
    Budget hosts often have severely congested international egress and can drop to a few dozen KB/s at peak hours. Not recommended for CDN-heavy workloads.
  </Card>
</CardGroup>

### Option 4: Relay through another host (last resort)

If your server really can't reach Cloudflare quickly and you can't change regions:

1. **Use an overseas server as a relay**: download to an overseas box first, then transfer back via a private/premium link
2. **Relay via your own object storage**: mirror the asset into your own OSS / COS / S3 (e.g., a China-region bucket), and serve from there
3. **Pre-warm and cache**: download once from your backend and serve subsequent requests from a local cache

<Warning>
  **Mind the expiration**

  CDN URLs returned by APIYI for images/videos typically have a limited validity period (see the returned URL). Download and persist assets to your own storage **as soon as** the callback arrives, to avoid broken links later.
</Warning>

## Common Questions

<AccordionGroup>
  <Accordion title="Why is my laptop fast but my server slow?">
    Home broadband often has optimized international routes via your ISP, while cloud servers go through the datacenter's international egress — quality can vary dramatically. Check your DC's international bandwidth first and follow the troubleshooting steps above.
  </Accordion>

  <Accordion title="I changed DNS but it's still slow — why?">
    DNS only affects which CDN edge you resolve to. If the underlying international bandwidth is already congested, DNS changes alone won't help. Consider changing regions or relaying through an overseas host.
  </Accordion>

  <Accordion title="Is Cloudflare R2 blocked in mainland China?">
    Cloudflare is not blocked in mainland China, but international egress can get congested at peak hours and some ISPs take suboptimal routes, so access quality is inconsistent. This is a general cross-border networking issue, not an R2-specific problem.
  </Accordion>

  <Accordion title="Video downloads keep failing — what can I do?">
    Use a downloader that supports **resume**, like `aria2c` or `wget -c`, with reasonable timeouts and retries:

    ```bash theme={null}
    aria2c -x 8 -s 8 -c --max-tries=10 --retry-wait=3 "<CDN URL>"
    ```
  </Accordion>

  <Accordion title="Can APIYI return Base64 instead of a CDN URL?">
    Videos are large (tens to hundreds of MB), and Base64 adds about 33% overhead with no resume support — it's actually slower and wastes bandwidth. We **do not recommend** Base64 for large files. Some image endpoints support Base64 responses; see the relevant API docs.
  </Accordion>

  <Accordion title="How do I confirm the bottleneck is my network, not the CDN?">
    Run the same `curl` test from an overseas host (AWS Tokyo, Singapore, etc.). If it's fast there but slow on your server, the bottleneck is between your server and Cloudflare — not the CDN itself.
  </Accordion>
</AccordionGroup>

## Related Docs

<CardGroup cols={2}>
  <Card title="Network Proxy Configuration" icon="network" href="/en/faq/network-proxy">
    Proxy options when international connectivity is unstable
  </Card>

  <Card title="Where are APIYI Servers?" icon="server" href="/en/faq/server-location">
    Learn about APIYI server locations and latency
  </Card>

  <Card title="Veo Video Generation API" icon="video" href="/en/api-capabilities/veo/overview">
    Output format and URL validity for the video API
  </Card>

  <Card title="Contact Support" icon="headphones" href="https://work.weixin.qq.com/kfid/kfc9adfd5810ece25ec">
    If nothing helps, our team will assist you
  </Card>
</CardGroup>

<Info>
  **Info to share with support**

  When contacting us, please include:

  * The specific CDN URL (sensitive params can be masked)
  * Your server region / DC / cloud provider
  * Full `mtr` or `traceroute` output
  * Output of the `curl` timing command above
  * The time window when the issue occurred (helps correlate with cross-border link monitoring)
</Info>
