Skip to content

Sidekiq

Guide for background mail delivery via Sidekiq on Ruby on Rails (Ruby 3.2+). Messages are sent to Mailexam SMTP from a worker through Action Mailer — convenient for notifications and CI without blocking the HTTP request.

The web layer enqueues a job; Sidekiq sends the message asynchronously (similar to Celery in Python).

What you need

  • A Mailexam account and a project with SMTP credentials.
  • A message broker — Redis (required by Sidekiq).
  • Ruby 3.2+, Bundler, and a Rails application.

Copy from the welcome email (or dashboard) for your project:

  • YOUR_LOGIN — SMTP login (for example, xxxxx);
  • YOUR_PASSWORD — SMTP password (a unique pair with the login);
  • host — YOUR_LOGIN.mailexam.io (matches the login).

1. Dependencies

In Gemfile:

gem "rails", "~> 8.1"
gem "sidekiq", "~> 7.3"
gem "redis", "~> 5.0"
gem "dotenv-rails", groups: %i[development test]
bundle install

Run Redis locally (Docker):

docker run -d --name redis -p 6379:6379 redis:7-alpine

2. Environment variables

.env file in the project root:

REDIS_URL=redis://localhost:6379/0

MAILEXAM_LOGIN=YOUR_LOGIN
MAILEXAM_PASSWORD=YOUR_PASSWORD
MAILEXAM_PORT=587
MAIL_FROM=noreply@example.test

SMTP host: YOUR_LOGIN.mailexam.io.

3. Action Mailer configuration

Same as Ruby on Railsconfig/initializers/mailexam_mailer.rb or environment-specific SMTP settings.

4. Sidekiq configuration

config/initializers/sidekiq.rb:

Sidekiq.configure_server do |config|
  config.redis = { url: ENV.fetch("REDIS_URL", "redis://localhost:6379/0") }
end

Sidekiq.configure_client do |config|
  config.redis = { url: ENV.fetch("REDIS_URL", "redis://localhost:6379/0") }
end

config/sidekiq.yml:

:concurrency: 5
:queues:
  - default

Add worker autoload paths in config/application.rb:

config.autoload_paths << Rails.root.join("app/workers")
config.eager_load_paths << Rails.root.join("app/workers")

5. Mailer, worker, and route

Mailer (same as Rails example):

# app/mailers/test_mailer.rb
class TestMailer < ApplicationMailer
  def test_email
    @body = params[:body]

    mail(
      to: params[:to],
      subject: params[:subject]
    )
  end
end

Worker:

# app/workers/mail_test_worker.rb
class MailTestWorker
  include Sidekiq::Worker

  def perform(to, subject, body)
    TestMailer.with(
      to: to,
      subject: subject,
      body: body
    ).test_email.deliver_now
  end
end

Controller — enqueue instead of deliver_now:

# app/controllers/mail_controller.rb
class MailController < ApplicationController
  def test
    payload = JSON.parse(request.body.read.presence || "{}")

    MailTestWorker.perform_async(
      payload["to"].presence || "user@example.test",
      payload["subject"].presence || "Sidekiq + Mailexam",
      payload["body"].presence || payload["text"].presence || "Mailexam test from Sidekiq"
    )

    render json: { status: "ok", queued: true }
  end
end

Start Redis, Sidekiq, and Rails:

bundle exec sidekiq -C config/sidekiq.yml
bin/rails server
curl -X POST http://127.0.0.1:3000/mail/test \
  -H 'Content-Type: application/json' \
  -d '{"to":"user@example.test","subject":"Test","body":"Hello"}'

The message will appear in the Mailexam dashboard → your project → inbox after the worker processes the job.

6. Local development and CI

Environment Recommendation
local Redis + Sidekiq process + Rails server
CI Redis service, REDIS_URL, and Mailexam secrets in pipeline variables

Example for .gitlab-ci.yml:

variables:
  REDIS_URL: redis://redis:6379/0
  MAILEXAM_LOGIN: $MAILEXAM_LOGIN
  MAILEXAM_PASSWORD: $MAILEXAM_PASSWORD
  MAILEXAM_PORT: "587"
  MAIL_FROM: "noreply@example.test"

After an integration test, verify delivery via the Mailexam API.

7. Common issues

Job queued but mail not sent

  • Ensure Sidekiq is running.
  • Check REDIS_URL and Redis connectivity.
  • Inspect Sidekiq logs for SMTP errors.

TLS or authentication failed

  • SMTP host must be {login}.mailexam.io, same login as in the welcome email.

Message not in the dashboard

  • View the inbox of the same Mailexam project.
  • Wait for the worker to finish processing.

See also