Создание PDF-файла на 500 страниц займет время, независимо от используемой вами технологии, поэтому решение состоит в том, чтобы отправить задание в очередь асинхронных задач (celery, huey, django-queue, ...), в конечном итоге с некоторым опросом, чтобы показать индикатор. Даже если вам удастся оптимизировать дерьмо из процесса генерации, ВСЕ ЕЩЕ займет слишком много времени, чтобы вписаться в цикл запроса / ответа HTTP (из POV пользователя по крайней мере даже одна минута уже слишком длинная)
Примечание: нет ничего удивительного в том, что максимальная загрузка вашего ЦП - генерация огромного PDF-файла не только требует времени, но и требует больших вычислительных ресурсов и легко потребляет вашу память. Это само по себе является еще одной причиной для использования распределенной очереди задач, чтобы вы могли запустить процесс на отдельном узле и избежать уничтожения вашего переднего сервера).