A high-performance, multithreaded file downloader written in Go that supports HTTP range requests, resume functionality, and real-time progress tracking.
- Multithreaded Downloads: Concurrent downloading using configurable number of goroutines
- HTTP Range Support: Automatically detects and utilizes HTTP range requests for faster downloads
- Resume Capability: Interrupted downloads can be resumed from where they left off
- Progress Tracking: Real-time progress bars for each download thread
- State Persistence: Download progress saved to JSON file for crash recovery
- Robust Error Handling: Graceful fallbacks and retry mechanisms
- File Verification: Automatic verification of downloaded file size
- Clean CLI Interface: Flag-based command-line interface with comprehensive help
- Installation
- Usage
- Architecture
- How It Works
- Configuration
- Examples
- Project Structure
- Technical Details
- Troubleshooting
- Contributing
- Go 1.24.3 or higher
git clone https://github.com/ZenMachina16/Multithreaded-Downloader
cd multithreaded-downloader
go build -o downloader main.gogo run main.go --url <URL> --output <filename>./downloader --url https://example.com/file.zip --output download.zip./downloader --url https://example.com/file.zip --output download.zip --threads 8./downloader --help| Flag | Description | Required | Default |
|---|---|---|---|
--url |
URL to download | Yes | - |
--output |
Output filename | Yes | - |
--threads |
Number of download threads | No | 4 |
--help |
Show help message | No | - |
The project follows a modular architecture with clear separation of concerns:
multithreaded-downloader/
βββ main.go # CLI interface and orchestration
βββ downloader/
β βββ downloader.go # Core download logic
β βββ state.go # Progress tracking and persistence
βββ download_state.json # Runtime progress file
βββ go.mod # Module definition
-
CLI Layer (
main.go)- Command-line argument parsing
- Input validation
- Error handling and user feedback
-
Downloader Package (
downloader/)- downloader.go: HTTP client, range detection, concurrent downloading
- state.go: Progress tracking, JSON serialization, state management
-
State Persistence
- JSON-based progress tracking
- Atomic updates for crash recovery
- Automatic cleanup on completion
// Checks HTTP range support
func (d *Downloader) SupportsRange() (bool, int64, error)- Sends HEAD request to check
Accept-Ranges: bytesheader - Falls back to partial GET request if HEAD fails
- Determines total file size from response headers
// Creates download parts
func CreateNewProgress(url, filename string, totalSize int64, numThreads int) *Progress- Divides file into equal segments based on thread count
- Each thread downloads a specific byte range
- Handles remainder bytes in the last segment
// Individual thread download logic
func (d *Downloader) downloadPart(ctx context.Context, part *Part, ...)- Each goroutine downloads its assigned range
- Uses HTTP Range headers:
Range: bytes=start-end - Implements retry logic for failed requests
- Updates progress atomically using
sync/atomic
// Real-time progress display
func (d *Downloader) PrintProgress()- Updates every 500ms with current download status
- Shows individual progress bars for each thread
- Displays overall completion percentage and data transferred
// Save/load progress functions
func SaveProgress(filename string, progress *Progress) error
func LoadProgress(filename string) (*Progress, error)- Saves progress to
download_state.jsonevery 500ms - Enables resume functionality after interruption
- Automatic cleanup on successful completion
- Default: 4 threads (good balance for most use cases)
- High-speed connections: 8-16 threads
- Limited bandwidth: 2-4 threads
- Server limitations: Falls back to 1 thread if ranges not supported
- Automatic retry on network errors
- 1-second delay between retries
- Continues from last successful byte position
- 32KB read buffer for optimal memory usage
- Balances between memory consumption and I/O efficiency
./downloader --url https://releases.ubuntu.com/20.04/ubuntu-20.04.6-desktop-amd64.iso --output ubuntu.iso --threads 8# First attempt (interrupted)
./downloader --url https://example.com/largefile.zip --output file.zip
# Resume (automatically detects existing progress)
./downloader --url https://example.com/largefile.zip --output file.zip./downloader --url https://example.com/file.pdf --output document.pdf --threads 1multithreaded-downloader/
β
βββ main.go # Entry point
β βββ Flag parsing
β βββ Input validation
β βββ Download orchestration
β
βββ downloader/
β β
β βββ downloader.go # Core functionality
β β βββ Downloader struct
β β βββ HTTP range detection
β β βββ Concurrent download logic
β β βββ Progress display
β β βββ Error handling
β β
β βββ state.go # State management
β βββ Progress structures
β βββ JSON serialization
β βββ State persistence
β βββ Utility functions
β
βββ download_state.json # Runtime progress file
βββ go.mod # Module definition
The downloader leverages HTTP/1.1 range requests (RFC 7233) to download file segments:
GET /file.zip HTTP/1.1
Host: example.com
Range: bytes=0-524287- Uses goroutines for concurrent downloads
sync.WaitGroupfor synchronizationsync/atomicfor thread-safe progress updatescontext.Contextfor cancellation handling
- Network timeouts: 30-second timeout per request
- Connection errors: Automatic retry with exponential backoff
- Partial failures: Individual thread recovery without affecting others
- State corruption: Graceful fallback to fresh download
- Streaming downloads with fixed buffer size
- No full file loading into memory
- Efficient I/O with
os.Seek()for precise positioning
Tested on a 100 Mbps connection with a 100MB file:
| Threads | Download Time | Speed Improvement |
|---|---|---|
| 1 | 45s | Baseline |
| 2 | 25s | 1.8x |
| 4 | 15s | 3x |
| 8 | 12s | 3.75x |
Results may vary based on server capabilities and network conditions.