Fundamentals 5 min read

Using Python Multithreading to Speed Up Image Downloads from Unsplash

This article demonstrates how employing Python's multithreading can dramatically reduce the time required to download multiple images from the Unsplash API, comparing a sequential approach that takes about 23 seconds with a threaded version that completes in roughly 5 seconds, and includes full code examples.

Python Programming Learning Circle
Python Programming Learning Circle
Python Programming Learning Circle
Using Python Multithreading to Speed Up Image Downloads from Unsplash

Using the correct data structures and algorithms can greatly improve program speed; multithreading or multiprocessing are common ways to achieve this in Python.

The article first presents a simple sequential script that downloads 15 images from the Unsplash API, measuring the execution time.

import requests
import time
img_urls = [
    'https://images.unsplash.com/photo-1516117172878-fd2c41f4a759',
    'https://images.unsplash.com/photo-1532009324734-20a7a5813719',
    'https://images.unsplash.com/photo-1524429656589-6633a470097c',
    'https://images.unsplash.com/photo-1530224264768-7ff8c1789d79',
    'https://images.unsplash.com/photo-1564135624576-c5c88640f235',
    'https://images.unsplash.com/photo-1541698444083-023c97d3f4b6',
    'https://images.unsplash.com/photo-1522364723953-452d3431c267',
    'https://images.unsplash.com/photo-1513938709626-033611b8cc03',
    'https://images.unsplash.com/photo-1507143550189-fed454f93097',
    'https://images.unsplash.com/photo-1493976040374-85c8e12f0c0e',
    'https://images.unsplash.com/photo-1504198453319-5ce911bafcde',
    'https://images.unsplash.com/photo-1530122037265-a5f1f91d3b99',
    'https://images.unsplash.com/photo-1516972810927-80185027ca84',
    'https://images.unsplash.com/photo-1550439062-609e1531270e',
    'https://images.unsplash.com/photo-1549692520-acc6669e2f0c'
]
start = time.perf_counter()  # start timer
for img_url in img_urls:
    img_name = img_url.split('/')[3]  # get image name from url
    img_bytes = requests.get(img_url).content
    with open(img_name, 'wb') as img_file:
        img_file.write(img_bytes)  # save image to disk
finish = time.perf_counter()  # end timer
print(f"Finished in {round(finish-start,2)} seconds")
# results
Finished in 23.101926751 seconds

The sequential run takes about 23 seconds.

Next, the article introduces Python's ThreadPoolExecutor to run the downloads concurrently, showing a threaded version of the script.

import time
from concurrent.futures import ThreadPoolExecutor
import requests

def download_images(url):
    img_name = url.split('/')[3]
    img_bytes = requests.get(url).content
    with open(img_name, 'wb') as img_file:
        img_file.write(img_bytes)
        print(f"{img_name} was downloaded")

start = time.perf_counter()  # start timer
with ThreadPoolExecutor() as executor:
    results = executor.map(download_images, img_urls)  # similar to map(func, *iterables)
finish = time.perf_counter()  # end timer
print(f"Finished in {round(finish-start,2)} seconds")
# results
Finished in 5.544147536 seconds

The threaded version completes in roughly 5 seconds, demonstrating a significant speedup and highlighting that threading is beneficial when multiple I/O‑bound API calls are made, while noting the overhead of thread creation.

For CPU‑intensive tasks such as heavy data or image processing, the article mentions that multiprocessing would generally outperform threading.

PerformancePythonConcurrencyMultithreadingImage Download
Python Programming Learning Circle
Written by

Python Programming Learning Circle

A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.