Rails 7.1 Expands ActiveRecord API with Async Query Support
source link: https://blog.saeloun.com/2023/11/21/rails-7-1-expands-active-record-async-quries/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Rails 7.1 Expands ActiveRecord API with Async Query Support
Nov 21, 2023Prasanth Chaduvula
I'm a React, Javascript & Rails full-stack Software Engineer. I have been working remotely for the past two years in a remote village. Before joining as a Software Engineer I founded kwiq - a hyperlocal delivery startup to deliver things in remote villages.
Traditionally, ActiveRecord queries have been synchronous, causing the application to pause and wait for the database to respond before continuing execution.
While this synchronous behavior works well in many cases, it can become a bottleneck when dealing with lengthy or resource-intensive queries, impacting the overall responsiveness of the application.
Asynchronous querying, however, is executed in a background thread. This enables our application main thread to remain responsive and handle incoming requests concurrently while the queries are executed in the background.
This asynchronous approach drastically enhances performance, especially in scenarios where waiting for the database response might hinder the application’s responsiveness.
Before
Rails 7 introduced ActiveRecord load_async method that allows multiple Active Record queries to be executed in parallel using the background thread and while our foreground thread continues on with the request.
This is useful for queries that can be performed long enough before their result will be needed, or for controllers which need to perform several independent queries.
@users = User.all.load_async
@posts = Post.order(published_at: :desc).load_async
It misses methods to load aggregate queries such as count, sum, etc.
After
Building upon the foundation laid in previous versions, Rails 7.1 introduced a suite of asynchronous methods in Active Record, significantly expanding its capabilities beyond traditional synchronous querying.
These new methods cater to various scenarios, including aggregates, single record retrieval, and custom SQL operations. They offer developers the flexibility to execute queries asynchronously, resulting in improved performance for specific types of database operations.
The following are the asynchronous methods in ActiveRecord:
async_count
async_sum
async_minimum
async_maximum
async_average
async_pluck
async_pick
async_ids
async_find_by_sql
async_count_by_sql
Asynchronous queries return promise objects. To retrieve the actual result of the asynchronous operation, we need to call the value
method on the returned promise. This method fetches the eventual value generated by the asynchronous query when it’s resolved.
Below is an example of using async_count
# Synchronous count
irb(main):001> User.count
User Count (58.7ms) SELECT COUNT(*) FROM "users"
=> 53
# Asynchronous count
irb(main):002> promise = User.async_count
User Count (3.6ms) SELECT COUNT(*) FROM "users"
=> #<ActiveRecord::Promise status=complete>
irb(main):003> promise.value
=> 53
async_count
operates similarly to count
but executes asynchronously, allowing the application to perform other tasks while the count
operation runs in the background. It provides the flexibility to maintain responsiveness in the application, especially beneficial when dealing with resource-intensive queries.
In the above example, User.count
fetches total (53) records in 58.7ms. Using User.async_count
, it fetches in 3.6ms as asynchronous operation schedules in the background. Calling value
on promise retrieves the records count (53), akin to synchronous count, affirming identical results asynchronously.
- Here is an example of
async_sum
# Synchronous sum
> Invoice.sum(:amount)
=> 0.32633333e6
# Asynchronous sum
> sum_amount = Invoice.async_sum(:amount)
> sum_amount.value
=> 0.32633333e6
async queries aims to optimize the handling of slower queries, particularly targeting aggregate functions (like count, sum) and methods that fetch single records or any result beyond a Relation, aiming for greater efficiency in their execution.
Conclusion
Implementing asynchronous queries in a Rails application offers diverse advantages. They optimize performance by executing multiple tasks concurrently, particularly benefiting complex or slow queries and applications handling concurrent requests.
Additionally, they improve application responsiveness by seamlessly managing requests while queries operate in the background. Asynchronous queries also aid in preserving memory by executing operations in separate threads, particularly advantageous for applications handling extensive datasets or high request volumes.
However, adopting best practices is crucial. Reserve asynchronous queries for slower or intricate tasks, avoid unnecessary overhead for simple queries, and conduct thorough testing to ensure compatibility and expected functionality, considering potential limitations with ActiveRecord features like transactions and callbacks.
Ultimately, embracing asynchronous queries presents a robust approach to enhancing performance, responsiveness, and memory management in our Rails application.
Share this post!
Recommend
-
13
Postgres Indexes for ActiveRecord Join Tables in Rails Apps Updated Jun 23, 2020 3 comments 9 minute read ...
-
9
UUID Primary Key in Rails 6 with PostgreSQL and Active Record Updated May 27, 2020 16 comments 8 minute read ...
-
4
Rails ActiveRecord PostgreSQL Foreign Keys and Data Integrity Updated Jun 28, 2019 5 minute read
-
8
Leaning on ActiveRecord Relations for Query Optimization Sep 14, 2021 • Ylan Segal •...
-
4
Rails adds support for Fiber-safe ActiveRecord ConnectionPools Feb 23, 2022 , by Swaathi Kakarla 2 minute read
-
3
The In-depth Guide to ActiveRecord load_async in Rails 7 Updated Mar 1, 2022 2 comments 18 minute read
-
2
ActiveRecord provides an easy way to select specific fields from the table using the ActiveRecord::QueryMethods#select method. Recently ActiveRecord::QueryMethods#select
-
5
Ruby ranges are very handy and efficient when you want to work with a sequence of numbers or characters bound by start and end values. But we could come across situations where we want ranges that either have no end value or start value. Ruby 2.6...
-
6
Friday, May 19, 2023 Rails World CFP, ActiveRecord.disconnect_all!, optimized where query and more! Posted by vipulnsward Hello Everyone! This is
-
10
Rails 7.1 Allows ActiveRecord reselect Query Method To Accept Hash Dec 15, 2023 •
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK