Background jobs help reduce your web app’s response time by separating time- and resource-consuming tasks from web requests. These background tasks (that might otherwise have slowed your users’ experience) are sent to a queue to be processed later. This results in happier end users, as they are able to access their dashboards or profile pages more quickly.
Ruby offers a large number of background worker libraries that developers can choose from; the most popular ones being Sidekiq, delayed_job and Resque. Monitoring the status of job runs, efficiency and resource utilization for these background jobs can be challenging in production environments. For background jobs spawned by web requests, we often have questions like
- Was the welcome email sent to this new user after signup?
- How long did it take between the admin user requesting the usage summary report and it being sent to them?
- Was this user’s data successfully uploaded to S3?
- What external resources did the background job interact with?
- What was the network latency between the job processor and the external resources?
- What were the host metrics during the job run?
TraceView can help you answer these questions!
With the release of Ruby gem 3.4.0, TraceView now provides Sidekiq, delayed_job and Resque support out of the box. For a large number of TraceView users, this means end-to-end visibility into your distributed transactions, without any modification of your code.
I’d like to show you how to answer these questions using TraceView. As an example, I’m using one of the more common background worker libraries, Sidekiq.
For applications that require some of the work to be processed asynchronously, Sidekiq offers a variety of options to configure background job processing for multiple use cases.
- An action can be triggered immediately after a web request
- An action can be triggered at a set interval after completion of a web request
- Periodic work execution (similar to cron jobs)
I have set up a simple Rails 4 application that uses Sidekiq to do things like authenticate users and asynchronously send email notifications. In TraceView, I’ve configured two separate apps for this application – ‘Rails’ as the container for all web requests to this app, and ‘Sidekiq_Worker’ as the container for all jobs triggered as a result of the web requests. You can see these apps on the Overview Charts page:
Drilling into the ‘Rails’ app, we can see performance of each component over time, and isolate slow requests. The issues could be anywhere – in actionview as the page is rendered, in Sequel as database calls are made or in memcache, caused by a slow memcache operation.
Along with the average performance of active layers, I can very quickly see the controller-action pairs that were in use, and their performance. It’s easy to read the dataset, as you can access average and standard deviation for the controller-action pairs:
Okay, first let’s find out what type of messages were sent from the RemoteCallWorkerJob Rails action to Sidekiq, and secondly, isolate the message types that were slow.
On the trace details page, we can see that this Sidekiq-client was used to send arguments ‘sendNotification’ and ‘Profile picture updated’ to the ‘ReportWorker’ job and this action was pretty quick as it took only 9.37 ms.
Now, let’s look at what’s happening on the Sidekiq-worker side. Here, I picked up a slower transaction from the Sidekiq-worker app’s heatmap. I can easily find out if the job succeeded or failed; how long it took for a job to be completed and if the ReportWorker job was resource intensive.
I can easily access details for any layer just by clicking on a specific layer.
This deeper insight into parent web requests and the resulting child Sidekiq jobs is provided out of the box with TraceView. Just install the latest ruby gem and that’s it! No additional configuration or code changes are required, and you get end-to-end visibility into your distributed Ruby applications.
We love hearing from you so please feel free to get in touch at firstname.lastname@example.org with your comments or feedback.