DEV Community

Yuta Kusuno
Yuta Kusuno

Posted on

[Rails] count vs length vs size with Samples and a Diagram

When working with Active Record in Ruby on Rails, we often need to count the number of records. There are three main methods for this: .count, .length, and .size. Each of these methods behaves differently, and understanding these differences can help you write more efficient code.

Rails version

7.1.3.4

The .count Method

The .count method always performs a COUNT query to the database. This is true regardless of whether the records are loaded into memory or not. Here’s an example:

posts = Post.all
posts.count
# Post Count (1.8ms) SELECT COUNT(*) FROM "posts"
# => 1000

posts = Post.all; posts.count; posts.count
# Post Count (3.9ms) SELECT COUNT(*) FROM "posts"
# Post Count (0.7ms) SELECT COUNT(*) FROM "posts"
# => 1000
Enter fullscreen mode Exit fullscreen mode

Even if the records are already loaded into memory, .count will still perform a COUNT query:

posts = Post.all.load
# Post Load (2.6ms) SELECT "posts".* FROM "posts"
# => [#<Post id: 1...
posts.count
# Post Count (1.2ms) SELECT COUNT(*) FROM "posts"
# => 1000
Enter fullscreen mode Exit fullscreen mode

The .length Method

On the other hand, the .length method loads the records into memory if needed. So, if the records are already loaded, .length will return the number of records without performing a new query:

posts = Post.all
# Post Load (1.0ms) SELECT "posts".* FROM "posts" /* loading for pp */ LIMIT $1  [["LIMIT", 11]]
posts.length
# Post Load (3.3ms) SELECT "posts".* FROM "posts"
# => 1000

posts = Post.all; posts.length; posts.length
# Post Load (4.2ms) SELECT "posts".* FROM "posts"
# => 1000
Enter fullscreen mode Exit fullscreen mode

The .size Method

Lastly, the .size method performs a COUNT query if the records are not loaded. However, if the records are already loaded, .size will return the number of records without performing a new query:

posts = Post.all
# Post Load (0.5ms) SELECT "posts".* FROM "posts" /* loading for pp */ LIMIT $1  [["LIMIT", 11]]
posts.size
# Post Count (0.9ms) SELECT COUNT(*) FROM "posts"
# => 1000

posts = Post.all; posts.size; posts.size
# Post Count (1.2ms) SELECT COUNT(*) FROM "posts"
# Post Count (1.0ms) SELECT COUNT(*) FROM "posts"
# => 1000

posts = Post.all.load; posts.size; posts.size
# Post Load (6.3ms) SELECT "posts".* FROM "posts"
# => 1000
Enter fullscreen mode Exit fullscreen mode

Review count vs length vs size with a Diagram

Review with a Diagram

Each of these methods is similar, but I think you'll find that they work differently than you might imagine. If we can understand them, we can choose the appropriate method and optimize the performance of our application.

That is about it. Happy coding!

Top comments (0)