---
# System prepended metadata

title: Async download options

---

# Asyncronous download

## Context
Currently we perform downloads using a syncronous POST request, this has a couple of limitations
* Poor user experience as user does not get feedback 
* Hard timeout of 180 seconds after which requests will fail on AWS Cloudfront

## Suggested user workflow
See https://communitiesuk.github.io/funding-service-design-post-award-alpha/beta-central-repo/async-download/download-data.html for prototype

* When the user presses 'Download' the user is presented with a success screen saying the file will be emailed to them.
* An asyncronous task is triggered which does the following:
  * Starts a download request on data-store with the filter parameters selected by the user 
  * Once the file is returned from the data-store it is persisted to S3
  * Generate a [pre-signed link](https://docs.aws.amazon.com/AmazonS3/latest/userguide/example_s3_Scenario_PresignedUrl_section.html) to the file
  * Send an email to the user who made the request using [Notify](www.notifications.service.gov.uk) including the pre-signed link as a parameter




## Async download options
There are a number of different options for implementing the asyncronous functionality

### Lambda
#### Pros
* Minimal cost as only pay for request time
* Small amount of code

#### Cons
* Need to consider monitoring/logging/failure scenarios
* Limited to 15minutes max runtime

### Celery (dedicated task queue service)
#### Pros
* Built in logging and monitoring
* Defined API for tasks
* Flask integration: https://flask.palletsprojects.com/en/2.3.x/patterns/celery/
* Fits in with possible future monilithic architecture

#### Cons
* More architecture to stand-up?

### SQS/SNS/Worker
#### Pros
* Defined pattern for copilot (see https://aws.github.io/copilot-cli/docs/developing/publish-subscribe/)
* Can handle long runtimes

#### Cons
* Need to think about monitoring/retry behaviour etc

## Other considerations
* Add a bucket lifecycle so files are not persisted beyond the lifetime of the link
* Consider using a spinner and asyncronously polling for the result (talk to design if they prefer this to the email route)
* Consider fronting the S3 with a proxy URL, or a service page to link to the downloads rather than linking to S3 directly
