---
title: "Skipping devise trackable module for API calls"
description:
  "This blog post discusses about issues faced due to devise trackable module
  for API calls and how to skip it"
canonical_url: "https://www.bigbinary.com/blog/skip-devise-trackable-module-for-api-calls"
markdown_url: "https://www.bigbinary.com/blog/skip-devise-trackable-module-for-api-calls.md"
---

# Skipping devise trackable module for API calls

This blog post discusses about issues faced due to devise trackable module for
API calls and how to skip it

- Author: Prathamesh Sonpatki
- Published: October 30, 2018
- Categories: Rails

We use devise gem for authentication in one of our applications. This
application provides an API which uses token authentication provided by the
devise gem.

We were authenticating the user using auth token for every API call.

```ruby
class Api::V1::BaseController < ApplicationController
  before_action :authenticate_user_using_x_auth_token
  before_action :authenticate_user!

  def authenticate_user_using_x_auth_token
    user_email = params[:email].presence || request.headers['X-Auth-Email']
    auth_token = request.headers['X-Auth-Token'].presence

    @user = user_email && User.find_by(email: user_email)

    if @user && Devise.secure_compare(@user.authentication_token, auth_token)
      sign_in @user, store: false
    else
      render_errors('Could not authenticate with the provided credentials', 401)
    end
  end
end
```

Everything was working smoothly initially, but we started noticing significant
reduction in the response times during peak hours after a few months.

Because of the nature of the business, the application gets API calls for every
user after every minute. Sometimes the application also get concurrent API calls
for the same user. We noticed that in such cases, the users table was getting
locked during the authentication process. This was resulting into cascading
holdups and timeouts as it was affecting other API calls which were also
accessing the users table.

After looking at the monitoring information, we found that the problem was
happening due to the `trackable` module of devise gem. The `trackable` module
keeps track of the user by storing the sign in time, sign in count and IP
address information. Following queries were running for every API call and were
resulting into exclusive locks on the users table.

```sql
UPDATE users SET last_sign_in_at = '2018-01-09 04:55:04',
current_sign_in_at = '2018-01-09 04:55:05',
sign_in_count = 323,
updated_at = '2018-01-09 04:55:05'
WHERE users.id = $1
```

To fix this issue, we decided to skip the user tracking for the API calls. We
don't need to track the user as every call is stateless and every request
authenticates the user.

Devise provides a hook to achieve this for certain requests through the
environment of the request. As we were already using a separate base controller
for API requests, it was easy to skip it for all API calls at once.

```ruby
class Api::V1::BaseController < ApplicationController
  before_action :skip_trackable
  before_action :authenticate_user_using_x_auth_token
  before_action :authenticate_user!

  def skip_trackable
    request.env['warden'].request.env['devise.skip_trackable'] = '1'
  end
end
```

This fixed the issue of exclusive locks on the users table caused by the
trackable module.

## Links

- [Human page](https://www.bigbinary.com/blog/skip-devise-trackable-module-for-api-calls)
