Designing large video uploads (up to 2 GB) with presigned S3 URLs

Backend Live Coding November 13, 2026 python

The file does not pass through Django.

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# ======================================================================
# Q: Customers upload videos of up to 2 GB. How do you design it?
#
# The file does not pass through Django. The API hands out a presigned URL for a
# direct upload to S3, the browser uploads (multipart for large files), and then
# calls confirm. At that point a Celery task on the heavy queue checks the file
# type, transcodes and creates a thumbnail. Screens download the file from a
# CDN.
# A quota limit per subscription plan, a check that the file really is a
# video/image (not just by its extension), and an S3 lifecycle rule for uploads
# that were never confirmed.
# ======================================================================

def create_upload(request):
    media = Media.objects.create(workspace=request.user.workspace,
                                 status='pending', name=request.data['name'])
    key = f'ws/{media.workspace_id}/media/{media.pk}/{uuid4()}'
    url = s3.generate_presigned_url(
        'put_object', Params={'Bucket': BUCKET, 'Key': key,
                              'ContentType': request.data['content_type']},
        ExpiresIn=900)
    Media.objects.filter(pk=media.pk).update(s3_key=key)
    return Response({'media_id': media.pk, 'upload_url': url}, status=201)

def confirm_upload(request, pk):
    media = get_object_or_404(Media, pk=pk, workspace=request.user.workspace)
    transaction.on_commit(lambda: process_media.delay(media.pk))
    return Response(status=202)                     # Accepted: asynchronous processing