Sobes.tech
Senior

There is a large file with a million URLs, how to download them quickly without overloading the system and getting banned by the external server?

sobes.tech AI

Answer from AI

To quickly and safely load a million URLs without overloading the system and risking a ban from the server, you need to:

  1. Limit the number of concurrent requests — use a worker pool or semaphore to control parallelism.
  2. Implement rate limiting — restrict the request rate to a single server to not exceed the allowed limit.
  3. Handle errors and perform retries with exponential backoff.
  4. Use asynchronous or concurrent mechanisms in Go (goroutines + channels).

Example in Go with parallelism control and delays:

package main

import (
    "bufio"
    "fmt"
    "net/http"
    "os"
    "sync"
    "time"
)

func worker(urls <-chan string, wg *sync.WaitGroup, rateLimiter <-chan time.Time) {
    defer wg.Done()
    client := &http.Client{Timeout: 10 * time.Second}
    for url := range urls {
        <-rateLimiter // wait for permission to request
        resp, err := client.Get(url)
        if err != nil {
            fmt.Printf("Error loading %s: %v\n", url, err)
            continue
        }
        resp.Body.Close()
        fmt.Printf("Loaded: %s\n", url)
    }
}

func main() {
    file, err := os.Open("urls.txt")
    if err != nil {
        panic(err)
    }
    defer file.Close()

    urls := make(chan string, 100)
    var wg sync.WaitGroup

    // Rate limit: 10 requests per second
    rateLimiter := time.Tick(100 * time.Millisecond)

    // Launch 20 workers
    for i := 0; i < 20; i++ {
        wg.Add(1)
        go worker(urls, &wg, rateLimiter)
    }

    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        urls <- scanner.Text()
    }
    close(urls)
    wg.Wait()
}

In this example:

  • 20 parallel workers process URLs.
  • rateLimiter limits request rate to 10 per second.
  • HTTP client has a timeout.

This approach allows efficient loading of many URLs without overloading the system or causing server-side blocking.