{"id":6756,"date":"2020-06-30T16:54:04","date_gmt":"2020-06-30T16:54:04","guid":{"rendered":"https:\/\/cheesecakelabs.com\/blog\/?p=6756\/"},"modified":"2022-07-01T17:08:43","modified_gmt":"2022-07-01T17:08:43","slug":"asynchronous-task-queue-django","status":"publish","type":"post","link":"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/","title":{"rendered":"Asynchronous task queue with Django, Celery and AWS SQS"},"content":{"rendered":"<p>When dealing with heavy workload functionalities that can have a big impact on web application performance, you may&nbsp;run an asynchronous task queue (scheduled or not). These asynchronous background&nbsp;tasks can not only drastically improve the scalability of the application by moving those highly consuming operations to the background, but also improve the functionality usability. Once spread on different components, each with its own responsibility, your code can even look cleaner, more isolated and can be easier to maintain.<\/p>\n<p><!--more-->This article introduces a few topics regarding a prebuilt architecture using <a href=\"https:\/\/cheesecakelabs.com\/blog\/blog\/django-framework-app-development\/\">Django<\/a>, Celery, Docker, and AWS SQS. The codebase is <a href=\"https:\/\/github.com\/rodolfolottin\/django-sqs-celery-template\">available on&nbsp;Github<\/a> and you can easily follow the README steps to have the application up and running with no effort.<\/p>\n<p><span style=\"font-weight: 400;\">The following section brings a brief overview of the components used to build the architecture.<\/span><\/p>\n<h2><b>Components description<\/b><\/h2>\n<h4>Message broker<\/h4>\n<p><a href=\"https:\/\/www.cloudamqp.com\/blog\/2020-04-03-why-use-rabbitmq-in-a-microservice-architecture.html\"><img decoding=\"async\" class=\" wp-image-6758 aligncenter\" src=\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2020\/06\/message-queue-and-rabbitmq-1.png\" alt=\"\" width=\"668\" height=\"293\" srcset=\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2020\/06\/message-queue-and-rabbitmq-1.png 1844w, https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2020\/06\/message-queue-and-rabbitmq-1-768x337.png 768w\" sizes=\"(max-width: 668px) 100vw, 668px\" \/><\/a><\/p>\n<p style=\"text-align: center;\">Message broker usage<\/p>\n<p><span style=\"font-weight: 400;\">First things first. What is a message broker? Our always friendly Wikipedia says that: <\/span><i><span style=\"font-weight: 400;\">It mediates communication among applications, minimizing the mutual awareness that applications should have of each other in order to be able to exchange messages, effectively implementing decoupling. <\/span><\/i><span style=\"font-weight: 400;\">(2020)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">In other words, it is an intermediate layer in which applications can communicate with &#8211; read and\/or write messages &#8211; and by having that, it allows the possibility of building two decoupled applications that do not rely on each other.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h4>Amazon SQS<\/h4>\n<p><a href=\"https:\/\/guilhermeteles.com.br\/amazon-simple-queue-service-amazon-sqs\/\"><img decoding=\"async\" class=\" wp-image-6759 aligncenter\" src=\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2020\/06\/aws-sqs-768x339.png\" alt=\"\" width=\"768\" height=\"339\"><\/a><\/p>\n<p style=\"text-align: center;\">Amazon SQS queue messaging flow<\/p>\n<p><span style=\"font-weight: 400;\">What is AWS SQS? &#8220;<\/span><i><span style=\"font-weight: 400;\">Amazon Simple Queue Service (SQS) is a fully managed message queuing service that enables you to decouple and scale microservices, distributed systems, and serverless applications. [&#8230;] Using SQS, you can send, store, and receive messages between software components at any volume, without losing messages or requiring other services to be available.&#8221; <\/span><\/i><span style=\"font-weight: 400;\">(Amazon, 2020)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">There are a few alternatives for SQS, like Kafka, Redis or RabbitMQ and all of them can be easily set up on Amazon using ElasticCache or AmazonMQ. Besides that, you do have the option of deploying your message broker on EC2 instances, which could be cheaper depending on the number of messages. But you should also consider the time and effort required to set it up on EC2 and the extra effort in case you decide to use it with Auto Scaling.&nbsp;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">What I see as the main benefit of using SQS is that it is fully managed by AWS and you pay on-demand according to your usage and if your application or feature requirements are according to SQS usage, it is very straightforward to configure and use it.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h4>Celery<\/h4>\n<p><a href=\"https:\/\/docs.celeryproject.org\/en\/stable\/getting-started\/introduction.html\"><img decoding=\"async\" class=\" wp-image-6760 aligncenter\" src=\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2020\/06\/celery_512.png\" alt=\"\" width=\"185\" height=\"185\" srcset=\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2020\/06\/celery_512.png 512w, https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2020\/06\/celery_512-300x300.png 300w\" sizes=\"(max-width: 185px) 100vw, 185px\" \/><\/a><\/p>\n<p style=\"text-align: center;\">Celery library logo<\/p>\n<p><span style=\"font-weight: 400;\">What is Celery? &#8220;<\/span><i><span style=\"font-weight: 400;\">Celery is an asynchronous task queue\/job queue based on distributed message passing. It is focused on real-time operation, but supports scheduling as well. [&#8230;] Tasks can execute asynchronously (in the background) or synchronously (wait until ready).&#8221; <\/span><\/i><span style=\"font-weight: 400;\">(Celery, 2020)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Essentially, Celery is used to coordinate and execute distributed <a href=\"https:\/\/cheesecakelabs.com\/blog\/blog\/biggest-benefits-of-python\/\">Python<\/a> tasks. It allows the possibility of moving a specific code execution outside of the HTTP request-response cycle. This way, your server can respond as quickly as possible for a specific request, as it spawns an asynchronous job as a worker to execute the specific piece of code, which improves your server response time. Also, with Celery you have the option of running jobs in the background on a regular schedule.<\/span><br \/>\n<a href=\"https:\/\/content.cheesecakelabs.com\/ebook-app-development\"><img decoding=\"async\" class=\"wp-image-7639 size-full aligncenter\" src=\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2021\/06\/ebook-app-value-guide-development-4.png\" alt=\"\" width=\"1930\" height=\"926\" srcset=\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2021\/06\/ebook-app-value-guide-development-4.png 1930w, https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2021\/06\/ebook-app-value-guide-development-4-768x368.png 768w\" sizes=\"(max-width: 1930px) 100vw, 1930px\" \/><\/a><\/p>\n<h2><b>Putting things together<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">To get everybody on the same page: AWS SQS is the message broker chosen here and Celery is the component responsible for orchestrating &#8211; consume: read and write &#8211; the message queue. Since Celery is a library, it needs to be set up on top of Django.<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">Note: The source code used in this blog post <\/span><\/i><a href=\"https:\/\/github.com\/rodolfolottin\/django-sqs-celery-template\"><i><span style=\"font-weight: 400;\">is available on GitHub<\/span><\/i><\/a><span style=\"font-weight: 400;\">. <\/span><i><span style=\"font-weight: 400;\">It assumes the following folders\/app structure:<\/span><\/i><\/p>\n<pre class=\"language-swift\"><code class=\"language-swift\"> \n.\n\u2514\u2500\u2500 src\n    \u251c\u2500\u2500 app\n    \u2502   \u251c\u2500\u2500 __init__.py\n    \u2502   \u251c\u2500\u2500 settings.py\n    \u2502   \u251c\u2500\u2500 urls.py\n    \u2502   \u2514\u2500\u2500 wsgi.py\n    \u251c\u2500\u2500 manage.py\n    [\u2026]\n<\/code><\/pre>\n<p><span style=\"font-weight: 400;\"><br \/>\nDocker isn&#8217;t necessary for the system to work, but it makes it a lot easier to reproduce the final system architecture locally and it also serves as a guide when configuring the system architecture on a cloud computing service environment.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">On the docker-compose file below, there are 5 configured services:<\/span><\/p>\n<pre class=\"language-swift\"><code class=\"language-swift\"> \nversion: \"3\"\nservices:\n  web:\n    build: .\n    volumes:\n      - .:\/usr\/src\/app\n    ports:\n      - 8000:8000\n    environment:\n      ENV: development\n    depends_on:\n      - db\n      - sqs\n\n  worker:\n    build: .\n    volumes:\n      - .:\/usr\/src\/app\n    command: bash -c \"cd src\/ &amp;&amp; celery -A app worker --loglevel=debug\"\n    depends_on:\n      - web\n      - sqs\n\n  beat:\n    build: .\n    volumes:\n      - .:\/usr\/src\/app\n    command: bash -c \"cd src\/ &amp;&amp; celery -A app beat --loglevel=debug\" \n    depends_on:\n      - web \n      - sqs \n\n  db:\n    image: postgres:12\n    ports:\n      - 5432:5432\n    volumes:\n      - .\/docker\/db\/pgdata:\/var\/lib\/postgresql\/data\n    environment:\n      POSTGRES_USER: postgres\n      POSTGRES_PASSWORD: postgres\n      POSTGRES_DB: app\n\n  sqs:\n    image: roribio16\/alpine-sqs\n    ports:\n      - 9324:9324\n      - 9325:9325\n    volumes:\n      - .\/config\/elasticmq.conf:\/opt\/config\/elasticmq.conf\n<\/code><\/pre>\n<p><span style=\"font-weight: 400;\">Here is the lowdown on the docker-compose file:<\/span><\/p>\n<ul>\n<li><i><span style=\"font-weight: 400;\">web<\/span><\/i><span style=\"font-weight: 400;\">: is the web service container.<\/span><\/li>\n<li><i><span style=\"font-weight: 400;\">worker<\/span><\/i><span style=\"font-weight: 400;\">:&nbsp;<\/span><span style=\"font-weight: 400;\">is a celery worker that spawns a supervisor process which does not process any tasks. Instead, it spawns child processes to execute the actual available tasks.<\/span><\/li>\n<li><i><span style=\"font-weight: 400;\">beat<\/span><\/i><span style=\"font-weight: 400;\">:&nbsp;<\/span><span style=\"font-weight: 400;\">is a celery scheduler that periodically spawn tasks that are executed by the available workers.<\/span><\/li>\n<li><i><span style=\"font-weight: 400;\">db<\/span><\/i><span style=\"font-weight: 400;\">: postgres <\/span><span style=\"font-weight: 400;\">database container<\/span><i><span style=\"font-weight: 400;\">.<\/span><\/i><\/li>\n<li><i><span style=\"font-weight: 400;\">sqs<\/span><\/i><span style=\"font-weight: 400;\">: <\/span><i><span style=\"font-weight: 400;\">i<\/span><\/i><span style=\"font-weight: 400;\">s a containerized Java implementation of the Amazon Queue Service that we will use to mimic the AWS SQS behaviour. The port 9324 is available to use the queue service and the 9325 is available to access the web interface.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Basically, the <\/span><i><span style=\"font-weight: 400;\">worker <\/span><\/i><span style=\"font-weight: 400;\">container service is responsible for searching and executing the available messages on the queues and the <\/span><i><span style=\"font-weight: 400;\">beat<\/span><\/i><span style=\"font-weight: 400;\"> container service is responsible for spawning periodical tasks to be executed by the workers. When working with periodical tasks, there are a few possible configurations. You can check a <\/span><a href=\"https:\/\/docs.celeryproject.org\/en\/stable\/userguide\/periodic-tasks.html#crontab-schedules\"><span style=\"font-weight: 400;\">few examples on this page<\/span><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The following code section is the <\/span><i><span style=\"font-weight: 400;\">config\/elasticmq.conf<\/span><\/i><span style=\"font-weight: 400;\"> file and it is used for the local execution only. It configures the node address for the sqs container. As Celery by default creates and uses a queue named &#8220;celery&#8221;, we&nbsp;don&#8217;t need to create a new queue unless&nbsp;we&nbsp;need it.<\/span><\/p>\n<pre class=\"language-swift\"><code class=\"language-swift\">\ninclude classpath(\"application.conf\")\n\nnode-address {\n   protocol = http\n   host = \"*\"\n   port = 9324\n   context-path = \"\"\n}\n\nrest-sqs {\n   enabled = true\n   bind-port = 9324\n   bind-hostname = \"0.0.0.0\"\n   \/\/ Possible values: relaxed, strict\n   sqs-limits = strict\n}\n<\/code><\/pre>\n<p><span style=\"font-weight: 400;\">This is what your <\/span><i><span style=\"font-weight: 400;\">app\/celery.py<\/span><\/i><span style=\"font-weight: 400;\"> file looks like. You can easily find the meaning of each config key on the <\/span><a href=\"https:\/\/docs.celeryproject.org\/en\/latest\/index.html\"><span style=\"font-weight: 400;\">Celery website<\/span><\/a><span style=\"font-weight: 400;\">. The main one is the <\/span><i><span style=\"font-weight: 400;\">BROKER_URL<\/span><\/i><span style=\"font-weight: 400;\">, which is the broker address that Celery will connect to. The <\/span><i><span style=\"font-weight: 400;\">BROKER_URL <\/span><\/i><span style=\"font-weight: 400;\">variable value is hardcoded just for illustration purposes. The user and password values are dummy values, as they are not configured on the docker container sqs service.&nbsp;<\/span><\/p>\n<pre class=\"language-swift\"><code class=\"language-swift\">\nimport os\n\nfrom celery import Celery\nfrom celery.schedules import crontab\nfrom django.conf import settings\n\nos.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"app.settings\")\n\napp = Celery(\"app\")\n\nCELERY_CONFIG = {\n    \"CELERY_TASK_SERIALIZER\": \"json\",\n    \"CELERY_ACCEPT_CONTENT\": [\"json\"],\n    \"CELERY_RESULT_SERIALIZER\": \"json\",\n    \"CELERY_RESULT_BACKEND\": None,\n    \"CELERY_TIMEZONE\": \"America\/Sao_Paulo\",\n    \"CELERY_ENABLE_UTC\": True,\n    \"CELERY_ENABLE_REMOTE_CONTROL\": False,\n}\n\nBROKER_URL = \"sqs:\/\/user:password@sqs:9324\/\",\n\nCELERY_CONFIG.update(\n    **{\n        \"BROKER_URL\": BROKER_URL,\n        \"BROKER_TRANSPORT\": \"sqs\",\n        \"BROKER_TRANSPORT_OPTIONS\": {\n            \"region\": \"us-west-2\",\n            \"visibility_timeout\": 3600,\n            \"polling_interval\": 60,\n        },\n    }\n)\n\napp.conf.update(**CELERY_CONFIG)\napp.autodiscover_tasks(packages={\"payment.tasks\"}))\n<\/code><\/pre>\n<p>The following code is what a dummy task function looks like. The application already knows that this is an asynchronous job just by using the decorator @task imported from Celery. Basically the decorator wraps the function and returns a task class instance with a few methods implemented.<\/p>\n<pre class=\"language-swift\"><code class=\"language-swift\">\nfrom celery import task\n\nfrom payment.models import Payment\n\n@task\ndef capture_payment(pk):\n    payment = Payment.objects.get(pk=pk)\n    print(f\"Capture payment: {payment}\")\n<\/code><\/pre>\n<p>The following section is an example of its usage.<\/p>\n<pre class=\"language-swift\"><code class=\"language-swift\">\nfrom payment.models import Payment\n\npayment = Payment.objects.first()\ncapture_payment.delay(pk=payment.pk)\n<\/code><\/pre>\n<p><span style=\"font-weight: 400;\">By calling it with the <\/span><i><span style=\"font-weight: 400;\">delay<\/span><\/i><span style=\"font-weight: 400;\"> method an <\/span><i><span style=\"font-weight: 400;\">AsyncResult <\/span><\/i><span style=\"font-weight: 400;\">instance will be generated and the worker will execute the message task once it is available in the queue.<\/span><\/p>\n<h2><b>Summary<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">In this blog post I&#8217;ve introduced to you the main concepts behind the proposed architecture and also I&#8217;ve enlightened what I considered important to know about it.&nbsp; With the <\/span><a href=\"https:\/\/github.com\/rodolfolottin\/django-sqs-celery-template\"><span style=\"font-weight: 400;\">codebase available on <\/span><i><span style=\"font-weight: 400;\">GitHub<\/span><\/i><\/a><span style=\"font-weight: 400;\">, you can effortlessly have a containerized Docker application that implements a job queueing system using Celery on top of Django for local development purposes. So, in order to deploy it, you need to create the respective services on AWS.<\/span><\/p>\n<h2><b>Known limitations<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Recently we have come across a limitation using AWS SQS: <\/span><a href=\"https:\/\/docs.aws.amazon.com\/AWSSimpleQueueService\/latest\/SQSDeveloperGuide\/sqs-visibility-timeout.html\"><span style=\"font-weight: 400;\">the visibility timeout<\/span><\/a><span style=\"font-weight: 400;\">, which is a period of time in which Amazon SQS prevents other consumers from receiving and processing the messages. In one of our projects, a task would have the possibility to be scheduled for running only 2 weeks from now, but as the maximum visibility timeout for a message is 12 hours, it isn&#8217;t possible to accomplish it by using SQS.<\/span><\/p>\n<h2><b>References<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Wikipedia.com, Message Broker. Available in: &lt;<\/span><a href=\"https:\/\/en.wikipedia.org\/wiki\/Message_broker\"><span style=\"font-weight: 400;\">https:\/\/en.wikipedia.org\/wiki\/Message_broker<\/span><\/a><span style=\"font-weight: 400;\">&gt;. Access in: June 24th, 2020.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Docs.aws.amazon.com, What is Amazon Simple Queue Service?. Available in: &lt;<\/span><a href=\"https:\/\/docs.aws.amazon.com\/AWSSimpleQueueService\/latest\/SQSDeveloperGuide\/welcome.html\"><span style=\"font-weight: 400;\">https:\/\/docs.aws.amazon.com\/AWSSimpleQueueService\/latest\/SQSDeveloperGuide\/welcome.html<\/span><\/a><span style=\"font-weight: 400;\">&gt;. Access in: June 24th, 2020.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Celeryproject, <\/span><span style=\"font-weight: 400;\">Celery &#8211; Distributed Task Queue. Available in: &lt;<\/span><a href=\"https:\/\/docs.celeryproject.org\/en\/stable\/\"><span style=\"font-weight: 400;\">https:\/\/docs.celeryproject.org\/en\/stable\/<\/span><\/a><span style=\"font-weight: 400;\">&gt;. Access in: June 24th, 2020.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>When dealing with heavy workload functionalities that can have a big impact on web application performance, you may&nbsp;run an asynchronous task queue (scheduled or not). These asynchronous background&nbsp;tasks can not only drastically improve the scalability of the application by moving those highly consuming operations to the background, but also improve the functionality usability. Once spread [&hellip;]<\/p>\n","protected":false},"author":65,"featured_media":6751,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[432],"tags":[350],"class_list":["post-6756","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-engineering","tag-tag-django"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Asynchronous Task Queue with Django, Celery and AWS SQS<\/title>\n<meta name=\"description\" content=\"When dealing with heavy workload functionalities that can have an impact on web application performance, you may run an asynchronous task queue.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Asynchronous Task Queue with Django, Celery and AWS SQS\" \/>\n<meta property=\"og:description\" content=\"When dealing with heavy workload functionalities that can have an impact on web application performance, you may run an asynchronous task queue.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/\" \/>\n<meta property=\"og:site_name\" content=\"Cheesecake Labs\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/cheesecakelabs\" \/>\n<meta property=\"article:published_time\" content=\"2020-06-30T16:54:04+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-07-01T17:08:43+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2020\/06\/Job_Queueing_System_Django_Docker_Celery_AWS_SQS.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1800\" \/>\n\t<meta property=\"og:image:height\" content=\"720\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Cheesecake Labs\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@cheesecakelabs\" \/>\n<meta name=\"twitter:site\" content=\"@cheesecakelabs\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/\"},\"author\":{\"name\":\"Rodolfo Lottin\"},\"headline\":\"Asynchronous task queue with Django, Celery and AWS SQS\",\"datePublished\":\"2020-06-30T16:54:04+00:00\",\"dateModified\":\"2022-07-01T17:08:43+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/\"},\"wordCount\":1261,\"image\":{\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2020\/06\/Job_Queueing_System_Django_Docker_Celery_AWS_SQS.png\",\"keywords\":[\"Django\"],\"articleSection\":[\"Engineering\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/\",\"url\":\"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/\",\"name\":\"Asynchronous Task Queue with Django, Celery and AWS SQS\",\"isPartOf\":{\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2020\/06\/Job_Queueing_System_Django_Docker_Celery_AWS_SQS.png\",\"datePublished\":\"2020-06-30T16:54:04+00:00\",\"dateModified\":\"2022-07-01T17:08:43+00:00\",\"author\":{\"@type\":\"person\",\"name\":\"Rodolfo Lottin\"},\"description\":\"When dealing with heavy workload functionalities that can have an impact on web application performance, you may run an asynchronous task queue.\",\"breadcrumb\":{\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/#primaryimage\",\"url\":\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2020\/06\/Job_Queueing_System_Django_Docker_Celery_AWS_SQS.png\",\"contentUrl\":\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2020\/06\/Job_Queueing_System_Django_Docker_Celery_AWS_SQS.png\",\"width\":1800,\"height\":720,\"caption\":\"asynchronous task queue\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cheesecakelabs.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Asynchronous task queue with Django, Celery and AWS SQS\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/#website\",\"url\":\"https:\/\/cheesecakelabs.com\/blog\/\",\"name\":\"Cheesecake Labs\",\"description\":\"Nearshore outsourcing company for Web and Mobile design and engineering services, and staff augmentation for startups and enterprises..\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cheesecakelabs.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"name\":\"Rodolfo Lottin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/#\/schema\/person\/image\/\",\"url\":false,\"contentUrl\":false,\"caption\":\"Rodolfo Lottin\"},\"description\":\"10 years of experience in Marketing and Sales in the Technology sector. My main purpose is help, support and structure efficient operations and also develop independent and multidisciplinary teams.\",\"url\":\"https:\/\/cheesecakelabs.com\/blog\/autor\/rodolfo-3\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Asynchronous Task Queue with Django, Celery and AWS SQS","description":"When dealing with heavy workload functionalities that can have an impact on web application performance, you may run an asynchronous task queue.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/","og_locale":"en_US","og_type":"article","og_title":"Asynchronous Task Queue with Django, Celery and AWS SQS","og_description":"When dealing with heavy workload functionalities that can have an impact on web application performance, you may run an asynchronous task queue.","og_url":"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/","og_site_name":"Cheesecake Labs","article_publisher":"https:\/\/www.facebook.com\/cheesecakelabs","article_published_time":"2020-06-30T16:54:04+00:00","article_modified_time":"2022-07-01T17:08:43+00:00","og_image":[{"width":1800,"height":720,"url":"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2020\/06\/Job_Queueing_System_Django_Docker_Celery_AWS_SQS.png","type":"image\/png"}],"author":"Cheesecake Labs","twitter_card":"summary_large_image","twitter_creator":"@cheesecakelabs","twitter_site":"@cheesecakelabs","twitter_misc":{"Written by":null,"Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/#article","isPartOf":{"@id":"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/"},"author":{"name":"Rodolfo Lottin"},"headline":"Asynchronous task queue with Django, Celery and AWS SQS","datePublished":"2020-06-30T16:54:04+00:00","dateModified":"2022-07-01T17:08:43+00:00","mainEntityOfPage":{"@id":"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/"},"wordCount":1261,"image":{"@id":"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/#primaryimage"},"thumbnailUrl":"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2020\/06\/Job_Queueing_System_Django_Docker_Celery_AWS_SQS.png","keywords":["Django"],"articleSection":["Engineering"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/","url":"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/","name":"Asynchronous Task Queue with Django, Celery and AWS SQS","isPartOf":{"@id":"https:\/\/cheesecakelabs.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/#primaryimage"},"image":{"@id":"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/#primaryimage"},"thumbnailUrl":"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2020\/06\/Job_Queueing_System_Django_Docker_Celery_AWS_SQS.png","datePublished":"2020-06-30T16:54:04+00:00","dateModified":"2022-07-01T17:08:43+00:00","author":{"@type":"person","name":"Rodolfo Lottin"},"description":"When dealing with heavy workload functionalities that can have an impact on web application performance, you may run an asynchronous task queue.","breadcrumb":{"@id":"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/#primaryimage","url":"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2020\/06\/Job_Queueing_System_Django_Docker_Celery_AWS_SQS.png","contentUrl":"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2020\/06\/Job_Queueing_System_Django_Docker_Celery_AWS_SQS.png","width":1800,"height":720,"caption":"asynchronous task queue"},{"@type":"BreadcrumbList","@id":"https:\/\/cheesecakelabs.com\/blog\/asynchronous-task-queue-django\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cheesecakelabs.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Asynchronous task queue with Django, Celery and AWS SQS"}]},{"@type":"WebSite","@id":"https:\/\/cheesecakelabs.com\/blog\/#website","url":"https:\/\/cheesecakelabs.com\/blog\/","name":"Cheesecake Labs","description":"Nearshore outsourcing company for Web and Mobile design and engineering services, and staff augmentation for startups and enterprises..","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cheesecakelabs.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","name":"Rodolfo Lottin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cheesecakelabs.com\/blog\/#\/schema\/person\/image\/","url":false,"contentUrl":false,"caption":"Rodolfo Lottin"},"description":"10 years of experience in Marketing and Sales in the Technology sector. My main purpose is help, support and structure efficient operations and also develop independent and multidisciplinary teams.","url":"https:\/\/cheesecakelabs.com\/blog\/autor\/rodolfo-3\/"}]}},"_links":{"self":[{"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/posts\/6756","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/users\/65"}],"replies":[{"embeddable":true,"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/comments?post=6756"}],"version-history":[{"count":1,"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/posts\/6756\/revisions"}],"predecessor-version":[{"id":10169,"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/posts\/6756\/revisions\/10169"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/media\/6751"}],"wp:attachment":[{"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/media?parent=6756"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/categories?post=6756"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/tags?post=6756"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}